2011/11/20

知っておきたいFacebookのOGPをBloggerに対応させる活用法


前回の記事自分の指定した任意の場所でJavascriptを実行させる Tipsまとめの中で、Javascriptを活用したSNSシェアボタンの設置を紹介しました。簡単でスピーディな情報拡散ツールとしてのSNSの利用を考えるのであれば、Facebookのいいね!ボタンもアクセス数を伸ばす一つの要素になっています。

但し、そのままボタンを設置しただけでは殆ど意味は無く、OGPを設定してあげることで本来の機能を引き出すことが出来るようになります。今回は現状での最善策と考えられる、BloggerをFacebookのOGPに対応させる方法を紹介致します。


OGP (Open Graph Protocol) とは何か


基本的な内容は下記Linkページにて詳しく解説されており、分かりやすく参考になります。


フェイスブック、ミクシィ、グリーで使われている OGP (Open Graph Protocol) とは何か - IT戦記
簡単に言うと「このウェブページは何のことを書いているか」という情報を、プログラムから読める形で HTML に付加する記述方法のことです。決まった OGP という書き方で HTML に情報を付加しておくことで、プログラムからも意味を理解しやすいウェブページを作っていこうってことです。 ...



月間10万PVに貢献!Facebookからのアクセスを5倍に増やす方法 | gadget or gimmick
ブログで「いいね!」ボタンを押した時、どういう挙動をするのか、知っていますか?自分のプロフィールのウォールにアクティビティとして表示される “だけ” なんですよ。 ニュースフィードには表示されません! ...



つまりOGPを設定していないと「いいね!」ボタンが押されたとしても、Facebook上での扱いは押したユーザーのプロフィールページにのみしか表示されず、記事のtitleや概要(Description)などの情報がきちんと反映されないということになります。

OGPが設定されていない場合の表示



そこでOGPを設定してあげることによって、「いいね!」ボタンが押された時に最適化した表示でウォール上へ投稿され、簡単に友達へ記事を共有することができるようになります。

「シェアボタン」と同じような働きをするということですね。

ツイッターで例えると、Linkがツイートされた時に、そのユーザーのフォロワーへ情報が共有されるのと同じようなものと考えて頂ければ分かりやすいかと思います。

BloggerにFacebookのOGPを設定する



1.『Facebookページ(アプリID)の取得』を参考に下記ページからFacebookアプリを作成

http://developers.facebook.com/apps

「新しいアプリケーションを作成」でアプリを作り、App ID/API Keyを取得します。

2.Bloggerのデザイン>HTMLの編集を開き、HTMLタグに以下の属性を追加

xmlns:fb='http://www.facebook.com/2008/fbml' xmlns:og='http://ogp.me/ns#'
このようになります。
<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' lang='ja' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr' xmlns:fb='http://www.facebook.com/2008/fbml' xmlns:og='http://ogp.me/ns#'>
mixi/GreeもOGPの設定があるので合わせて追加しました。
xmlns:mixi='http://mixi-platform.com/ns#'
xmlns:gr='http://gree.jp/ns'

3.Bloggerのデザイン>HTMLの編集で以下の「meta」タグを「head」タグ内へ追加

こちらのzerippeさんが作成された、WEBアプリケーションを利用させて頂きます。

BloggerをOGPに対応させるときのog:imageをなんとかする : とある変人の超備忘録
記事のRSSから画像ファイルが使用されているかをチェックし、使用されていれば一番最初に見つかった画像にリダイレクトするWEBアプリケーションを作ってみました。 ...

<!-- OGP -->
<!-- 記事 -->
<b:if cond='data:blog.pageType == &quot;item&quot;'>
<meta property='og:type' content='article'/>
<meta property='og:title' expr:content='data:blog.pageName + &quot; | &quot; + data:blog.title'/>
<meta property='og:image' expr:content='&quot;http://bloggerspice.appspot.com/postimage/&quot; + data:blog.url'/>
</b:if>
<!-- ホーム -->
<b:if cond='data:blog.pageType == &quot;index&quot;'>
<meta property='og:type' content='blog'/>
<meta expr:content='data:blog.pageTitle' property='og:title'/>
<meta property='og:image' content='[ブログの固定画像URLを指定]'/>
</b:if>
<!-- アーカイブ -->
<b:if cond='data:blog.pageType == &quot;archive&quot;'>
<meta property='og:type' content='article'/>
<meta property='og:title' expr:content='data:blog.pageTitle'/>
<meta property='og:image' content='[ブログの固定画像URLを指定]'/>
</b:if>
<!-- 全てに適用 -->
<meta property='og:url' expr:content='data:blog.url'/>
<meta property='og:site_name' expr:content='data:blog.title'/>
<meta property='fb:app_id' content='[作成したアプリのApp ID/API Key]'/>
<meta property='og:locale' content='ja_JP'/>
<!-- /OGP -->
[ブログの固定画像URLを指定]は、自分の好きな画像を選択。

[作成したアプリのApp ID/API Key]は、『Facebook開発者』のページから確認できる。

ポイント

「og:description」は、敢えて設定しません。Facebookの仕様で、記事の始めの「p」タグで囲ってある部分が概要として認識されるので、記事を書く時は先頭のDescriptionにしたい部分を「p」タグで囲みます。

また下手に設定してしまうと、Google+で共有させた場合に「og:description」の部分を読み込んでしまうため、記事の概要として相応しくないものとなってしまう為です。

参考記事:Google+とOpen Graph Protocol おまけ | モバイルSEOの勧め

4.Facebookいいね!ボタンを押したときコメントが表示されるようにする

以下のCodeを</head>と<body>の間に入力
<div id='fb-root'></div>
<script src="http://connect.facebook.net/ja_JP/all.js#xfbml=1"></script>
<script>
// <![CDATA[
  window.fbAsyncInit = function() {
    FB.init({appId: '[作成したアプリのApp ID/API Key]', 
             status: true, 
             cookie: true,
       xfbml: true});
 
    FB.api('/me', function(response) {
      console.log(response.name);
    });
  };
  (function() {
    var e = document.createElement('script'); e.async = true;
    e.src = document.location.protocol +
      '//connect.facebook.net/ja_JP/all.js';
    document.getElementById('fb-root').appendChild(e);
  }());
// ]]>
</script>
[作成したアプリのApp ID/API Key]を忘れずに入力する

5.Facebookいいね!ボタンの設置

XFBMLのプラグインコードを使用して、任意の場所に設置
<span style='vertical-align: 4px;'>
<fb:like expr:href='data:post.url' layout='button_count' send='false' show_faces='false' width='100'/>
</span>
「layout」でボタンの種類、「send」で送るボタンの有無、「show_faces」でボタンを押したユーザーアイコン表示の有無、「width」で幅を設定する。

実際の表示はこちらで確認:Like Button - Facebook開発者

XFBMLで設置した場合、コメントを出すことができるようにするためか縦方向に位置がズレます。
そのため、vertical-alignで調整しています。

なお、iframeでもコメントを出すことができますが、Layout Styleがstandardである必要があり
少なくともwidthが400px、heightが35px以上ないと表示されないという制約があります。

Facebook OGPに対応した各種SNSボタンの設置例


Javascriptを活用したSNSシェアボタンの設置を改良して、OGP対応のものに変更します。
(function () {
    var Twitter_ID = '[あなたのTwitterID]';

    function generate_button_text(url, title) {
        var hatena_btn, twitter_btn, gplus_btn, tumblr_btn, ameba_btn, mixi_btn, fb_share_btn, twitter_follow_btn, facebook_btn;
        hatena_btn = '<a href="' + url + '" class="hatena-bookmark-button" data-hatena-bookmark-title="' + title + '" data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加">' + '<img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border:none;"/></a>';
        twitter_btn = '<div style="display:inline-block;width: 97px;"><a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="' + Twitter_ID + '">Tweet</a></div>';
        gplus_btn = '<span style="width: 62px;display: inline-block;"><div class="g-plusone" size="medium" data-size="medium" data-count="true" href=' + url + '></div></span>';
        if (/Firefox/i.test(navigator.userAgent)) {
            tumblr_btn = '<a onclick="return popitup(this.href);" href="http://www.tumblr.com/share?v=3&u=' + encodeURIComponent(url) + '&t=' + encodeURIComponent(title) + '" ' + 'title="Share on Tumblr" ' + 'style="display:inline-block;overflow:hidden;width:20px;height:20px;' + 'background:url(\'http://platform.tumblr.com/v1/share_4.png\') top left no-repeat transparent;" ' + 'data-text="' + title +  '" data-url="' + url + '"></a>';
        } else {
            tumblr_btn = '<a href="http://www.tumblr.com/share?v=3&u=' + encodeURIComponent(url) + '&t=' + encodeURIComponent(title) + '" ' + 'title="Share on Tumblr" ' + 'style="display:inline-block;overflow:hidden;width:20px;height:20px;' + 'background:url(\'http://platform.tumblr.com/v1/share_4.png\') top left no-repeat transparent;" ' + 'data-text="' + title +  '" data-url="' + url + '"></a>';
        }
        ameba_btn = '<a rel="nofollow" target="_blank" href="http://stat100.ameba.jp/blog/proxy.html?longurl=' + url + '&title=' + title + '&type=now" style="outline: none;" title="アメーバなうで紹介">' + '<img src="http://stat100.ameba.jp/common_style/img/common/btn/btn_share_now.png" alt="なうで紹介"></a>';
        mixi_btn = '<a rel="nofollow" target="_blank" onclick="return popitup(this.href,632,456);" href="http://stat100.ameba.jp/blog/proxy.html?longurl=' + url + '&type=mixi" title="mixiチェック">' + '<img src="http://img.mixi.jp/img/basic/mixicheck_entry/bt_check_1.png" alt="mixiチェック"></a>';
        fb_share_btn = '<div style="display:inline-block;vertical-align: 4px;"><a name="fb_share"></a></div>';
        twitter_follow_btn = '<span style="vertical-align: -3px;"><a href="http://twitter.com/' + Twitter_ID + '" class="twitter-follow-button" data-show-count="false" data-width="132px" data-lang="ja">Follow @' + Twitter_ID + '</a></span>';
        facebook_btn = '<br><fb:like href="' + encodeURIComponent(url) + '" send="true" width="450" show_faces="false"></fb:like>';

        return [hatena_btn, twitter_btn, gplus_btn, tumblr_btn, ameba_btn, mixi_btn, fb_share_btn, twitter_follow_btn, facebook_btn].join('&nbsp');
    }
    $(document).ready(function () {
        var infos = [],
            target_node;
        $.getScript('http://b.st-hatena.com/js/bookmark_button.js');
        $.getScript('http://platform.twitter.com/widgets.js');
        $.getScript('http://platform.tumblr.com/v1/share.js');
        $.getScript('http://connect.facebook.net/ja_JP/all.js');
            window.fbAsyncInit = function() {
              FB.init({appId: '[作成したアプリのApp ID/API Key]', 
                status: true, 
                cookie: true,
          xfbml: true});
              FB.api('/me', function(response) {
                   console.log(response.name);
              });
            };
            (function() {
            var e = document.createElement('script'); e.async = true;
            e.src = document.location.protocol +
              '//connect.facebook.net/ja_JP/all.js';
            document.getElementById('fb-root').appendChild(e);
            }());
        $.getScript('http://static.ak.fbcdn.net/connect.php/js/FB.Share');
          window.___gcfg = {lang: 'ja'};
           (function() {
            var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
            po.src = 'https://apis.google.com/js/plusone.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
          })();
       if (location.href.match(/\/\d{4}\/\d{2}\/[^.]+\.html/)) {
            $('div.post-footer-line span.post-timestamp a.timestamp-link').each(function (idx, node) {
                infos[idx] = [node.toString(), $("div.post h3.post-title").eq(idx).text()];
            });
            target_node = $('div.post-footer');
        }
        $.each(infos, function (idx, elm) {
            target_node.eq(idx).append(generate_button_text(elm[0], elm[1]));
        });
    });
}());

<!--Simple Popup Plugin v3.2 / RH Mods-->
var swin = null;

function popitup(mypage, w, h, pos, myname, infocus) {
    if (w != parseInt(w) || w <= 0) w = 500;
    if (h != parseInt(h) || h <= 0) h = 500;
    if (myname == null) {
        myname = "swin"
    };
    myleft = 0;
    mytop = 0;
    if (myleft == 0 && mytop == 0 && pos != "random") {
        pos = "center"
    };
    if (pos == "random") {
        myleft = (screen.width) ? Math.floor(Math.random() * (screen.width - w)) : 100;
        mytop = (screen.height) ? Math.floor(Math.random() * ((screen.height - h) - 75)) : 100;
    }
    if (pos == "center") {
        myleft = (screen.width) ? (screen.width - w) / 2 : 100;
        mytop = (screen.height) ? (screen.height - h) / 2 : 100;
    }
    settings = "width=" + w + ",height=" + h + ",top=" + mytop + ",left=" + myleft + ",scrollbars=no,location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=no";
    swin = window.open(mypage, myname, settings);
    if (infocus == null || infocus == "front") {
        swin.focus()
    };
    return false;
}
<!--/Simple Popup Plugin-->
実際にはFacebookいいね!とGoogle+の「script」の呼び出しは、設置済みなので下記部分が不要となります。
        $.getScript('http://connect.facebook.net/ja_JP/all.js');
            window.fbAsyncInit = function() {
              FB.init({appId: '[作成したアプリのApp ID/API Key]', 
                status: true, 
                cookie: true,
          xfbml: true});
              FB.api('/me', function(response) {
                   console.log(response.name);
              });
            };
            (function() {
            var e = document.createElement('script'); e.async = true;
            e.src = document.location.protocol +
              '//connect.facebook.net/ja_JP/all.js';
            document.getElementById('fb-root').appendChild(e);
            }());

          window.___gcfg = {lang: 'ja'};
           (function() {
            var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
            po.src = 'https://apis.google.com/js/plusone.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
          })();
また、titleタグをh3からh2に変更している場合は
「$("div.post h3.post-title")」の部分を「$("div.post h2.post-title")」と変更

「target_node = $('div.post-footer');」でデフォルトの共有ボタンの後に追加されます。
位置を変更したい場合は、任意のセレクタを選択します。

実際に当ブログで設置しているSample Code
(function () {
    var Twitter_ID = 'ichitaso';

    function generate_button_text(url, title) {
        var hatena_btn, twitter_btn, gplus_btn, tumblr_btn, ameba_btn, mixi_btn, fb_share_btn, twitter_follow_btn, facebook_btn;
        hatena_btn = '<a href="' + url + '" class="hatena-bookmark-button" data-hatena-bookmark-title="' + title + '" data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加">' + '<img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border:none;"/></a>';
        twitter_btn = '<div style="display:inline-block;width: 97px;"><a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="' + Twitter_ID + '">Tweet</a></div>';
        gplus_btn = '<span style="width: 62px;display: inline-block;"><div class="g-plusone" size="medium" data-size="medium" data-count="true" href=' + url + '></div></span>';
        if (/Firefox/i.test(navigator.userAgent)) {
            tumblr_btn = '<a onclick="return popitup(this.href);" href="http://www.tumblr.com/share?v=3&u=' + encodeURIComponent(url) + '&t=' + encodeURIComponent(title) + '" ' + 'title="Share on Tumblr" ' + 'style="display:inline-block;overflow:hidden;width:20px;height:20px;' + 'background:url(\'http://platform.tumblr.com/v1/share_4.png\') top left no-repeat transparent;" ' + 'data-text="' + title +  '" data-url="' + url + '"></a>';
        } else {
            tumblr_btn = '<a href="http://www.tumblr.com/share?v=3&u=' + encodeURIComponent(url) + '&t=' + encodeURIComponent(title) + '" ' + 'title="Share on Tumblr" ' + 'style="display:inline-block;overflow:hidden;width:20px;height:20px;' + 'background:url(\'http://platform.tumblr.com/v1/share_4.png\') top left no-repeat transparent;" ' + 'data-text="' + title +  '" data-url="' + url + '"></a>';
        }
        ameba_btn = '<a rel="nofollow" target="_blank" href="http://stat100.ameba.jp/blog/proxy.html?longurl=' + url + '&title=' + title + '&type=now" style="outline: none;" title="アメーバなうで紹介">' + '<img src="http://stat100.ameba.jp/common_style/img/common/btn/btn_share_now.png" alt="なうで紹介"></a>';
        mixi_btn = '<a rel="nofollow" target="_blank" onclick="return popitup(this.href,632,456);" href="http://stat100.ameba.jp/blog/proxy.html?longurl=' + url + '&type=mixi" title="mixiチェック">' + '<img src="http://img.mixi.jp/img/basic/mixicheck_entry/bt_check_1.png" alt="mixiチェック"></a>';
        fb_share_btn = '<div style="display:inline-block;vertical-align: 4px;"><a name="fb_share"></a></div>';
        twitter_follow_btn = '<span style="vertical-align: -3px;"><a href="http://twitter.com/' + Twitter_ID + '" class="twitter-follow-button" data-show-count="false" data-width="132px" data-lang="ja">Follow @' + Twitter_ID + '</a></span>';
        facebook_btn = '<br><fb:like href="' + encodeURIComponent(url) + '" send="true" width="450" show_faces="false"></fb:like>';

        return [hatena_btn, twitter_btn, gplus_btn, tumblr_btn, ameba_btn, mixi_btn, fb_share_btn, twitter_follow_btn, facebook_btn].join('&nbsp');
    }
    $(document).ready(function () {
        var infos = [],
            target_node;
        $.getScript('http://b.st-hatena.com/js/bookmark_button.js');
        $.getScript('http://platform.twitter.com/widgets.js');
        $.getScript('http://platform.tumblr.com/v1/share.js');
        $.getScript('http://static.ak.fbcdn.net/connect.php/js/FB.Share');
       if (location.href.match(/\/\d{4}\/\d{2}\/[^.]+\.html/)) {
            $('div.post-footer-line span.post-timestamp a.timestamp-link').each(function (idx, node) {
                infos[idx] = [node.toString(), $("div.post h2.post-title").eq(idx).text()];
            });
            target_node = $('div#honbun-footer');
        }
        $.each(infos, function (idx, elm) {
            target_node.eq(idx).append(generate_button_text(elm[0], elm[1]));
        });
    });
}());

<!--Simple Popup Plugin v3.2 / RH Mods-->
var swin = null;

function popitup(mypage, w, h, pos, myname, infocus) {
    if (w != parseInt(w) || w <= 0) w = 500;
    if (h != parseInt(h) || h <= 0) h = 500;
    if (myname == null) {
        myname = "swin"
    };
    myleft = 0;
    mytop = 0;
    if (myleft == 0 && mytop == 0 && pos != "random") {
        pos = "center"
    };
    if (pos == "random") {
        myleft = (screen.width) ? Math.floor(Math.random() * (screen.width - w)) : 100;
        mytop = (screen.height) ? Math.floor(Math.random() * ((screen.height - h) - 75)) : 100;
    }
    if (pos == "center") {
        myleft = (screen.width) ? (screen.width - w) / 2 : 100;
        mytop = (screen.height) ? (screen.height - h) / 2 : 100;
    }
    settings = "width=" + w + ",height=" + h + ",top=" + mytop + ",left=" + myleft + ",scrollbars=no,location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=no";
    swin = window.open(mypage, myname, settings);
    if (infocus == null || infocus == "front") {
        swin.focus()
    };
    return false;
}
<!--/Simple Popup Plugin-->

OGP設定の確認とまとめ


最後に自分が設定したものが正しく機能しているか確認します。

下記2つのLinkでホーム、アーカイブ、個別ページのURLを入力してエラーが出なければ成功です。

Debugger - Facebook開発者

Input URL or Access Token
Enter a URL to see some helpful feedback about your page markup. Enter an access token to see its expiry and user. ...



2012/02/05 追記

現在、FacebookのURLリンターの仕様が変更され、<p>タグで囲んだ部分がog:descriptionとして認識されることで「metaではない違うタグで指定されていますよ」と注意が表示されますが、動作上は問題ないのでご安心下さい。

上手く設定できていれば、自分のBlog(いいね!ボタン)のアクセス解析ができます。

http://www.facebook.com/insights/

こちらのページで自分のサイトを登録するとFacebookからのトラフィックを確認できます。
  • どのくらいの人が「いいね!ボタン」を押しているのか
  • 誰が「いいね!ボタン」を押しているのかなど

少し長くなりましたが、実際に設置するのには時間は掛からないかと思いますので、まだ設置されていない方は参考にして頂ければと思います( ̄ー ̄)b

関連記事