2012年2月25日土曜日

Pinterestのピン避け(nopin)がお粗末だった件

ヘルプの「What if I don't want images from my site to be pinned?」のところに書いてあるように、Pinterestは、以下の1行がHTMLに含まれているページではpinできないようにする対策を実施しました。

<meta name="pinterest" content="nopin" />

ところが、これは簡単に突破することができます。

実験用ページを作りました。確認方法を簡単にまとめます。

  • 実験用ページはnopinコードを含むため、初期状態ではpinできません。「Pin It」ボタンを押すとアラートが出ます。
  • いったんpin不能状態になると以後は動作しなくなるので、ページをリロードします。
  • 「Remove "nopin"」ボタンを押します。
  • 「Pin It」ボタンを押すと、今度はpin可能になります。

「Remove "nopin"」ボタンのイベントハンドラで、nopinコードを動的に取り除いています。そういうブックマークレットを書けば、他のページでもnopinが突破できるわけです。

nopinコードがあればpinできませんよっていうのは、そういうことじゃないだろうと言っておきたいと思います。

pinmarkletでpinできないページがあって、DOMをゴニョゴニョして無理やりpinした時に疑惑が発生して、やっぱりそうだったかって話。localhostからもpinできるしね。

そのうち真っ当に対策されることを期待します。

参考までに、nopinと公式の「Pin It」プラグインが同一ページに共存してる場合は、pinできました。意味的には矛盾している状態ですし、pinできてもできなくても、どちらでも問題ないでしょう。

2012年2月21日火曜日

BloggerへのDISQUS導入メモ

このブログにDISQUSコメントを導入した手順のメモです。

DISQUSの方でウィジェットとして簡単に追加する手順が用意されているのですが、以下の対応を追加しています。

  • モバイルテンプレートにも対応
  • ページにも対応
  • 編集中のプレビューでの発動を抑止

まずはウィジェットの追加の手順を、次にカスタマイズの手順を説明します。

1. ウィジェットの追加

ずばり、以下のページで「Add site "◯◯◯" to Blogger」というボタンを押すだけで、ウィジェットが追加されます。
Install Disqus on Blogger

ブログを表示して確認してみます。このブログでは右サイドバーに追加されていたので、ダッシュボードの「レイアウト」で、「Disqus for ◯◯◯」というウィジェットを記事の下に移動しました。

2. モバイルテンプレート対応

単にウィジェットを追加した状態では、PCでしかDISQUSコメント欄が表示されませんので(モバイルではBloggerのコメント欄のまま)、手動でテンプレートを書き換えました。

ダッシュボードの「テンプレート」から「HTMLの編集」に進み、「ウィジェットのテンプレートを展開」のチェックボックスをONにしして、「Disqus for ◯◯◯」という箇所を探します。

<b:widget id='HTML1' locked='false' title='Disqus for ◯◯◯' type='HTML'>

この行に、以下の青字部分を追加します。

<b:widget id='HTML1' locked='false' mobile='yes' title='Disqus for ◯◯◯' type='HTML'>

以上でモバイル対応は完了です。テンプレートを保存して、記事ページにコメント欄が表示されるか確認しましょう。

なお、普通に記事ページでコメント欄が表示できればよくて後は気にしないという場合は、ここまでの対応で十分かと思います。

3. 編集中のプレビューでの発動を抑止

編集中のプレビューでDISQUSコメントが発動すると、余計なスレッドが作成されてしまうので、それを抑止します。テンプレートで抑止する方法もあると思いますが、ここでは以下の青字部分のように、JavaScriptで抑止しています。(インデント少し変えています)

<b:widget id='HTML1' locked='false' mobile='yes' title='Disqus for ◯◯◯' type='HTML'>
<b:includable id='main'>
...
      <b:if cond='data:blog.pageType == &quot;item&quot;'>
        <style type='text/css'>
          #comments {display:none;}
        </style>
        <script type='text/javascript'>
          location.pathname !== &#39;/b/post-preview&#39; &amp;&amp; (function() {
            var bloggerjs = document.createElement(&#39;script&#39;);
            bloggerjs.type = &#39;text/javascript&#39;;
            bloggerjs.async = true;
            bloggerjs.src = &#39;http://&#39;+disqus_shortname+&#39;.disqus.com/blogger_item.js&#39;;
            (document.getElementsByTagName(&#39;head&#39;)[0] || document.getElementsByTagName(&#39;body&#39;)[0]).appendChild(bloggerjs);
          })();
        </script>
      </b:if>
...
        <script type='text/javascript'>
          location.pathname !== &#39;/b/post-preview&#39; &amp;&amp; (function() {
          var bloggerjs = document.createElement(&#39;script&#39;);
          bloggerjs.type = &#39;text/javascript&#39;;
          bloggerjs.async = true;
          bloggerjs.src = &#39;http://&#39;+disqus_shortname+&#39;.disqus.com/blogger_index.js&#39;;
          (document.getElementsByTagName(&#39;head&#39;)[0] || document.getElementsByTagName(&#39;body&#39;)[0]).appendChild(bloggerjs);
        })();
        </script>
    </b:includable>
</b:widget>

4. ページ対応

次に、記事だけでなく、固定ページでもDISQUSコメントを使うようにします。blog.pageTypeがitemの場合のみ実行されているところが該当部分ですので、static_pageに対しても適用します(青字部分)。

      <b:if cond='data:blog.pageType == &quot;item&quot;'>
        <style type='text/css'>
          #comments {display:none;}
        </style>
        <script type='text/javascript'>
          location.pathname !== &#39;/b/post-preview&#39; &amp;&amp; (function() {
            var bloggerjs = document.createElement(&#39;script&#39;);
            bloggerjs.type = &#39;text/javascript&#39;;
            bloggerjs.async = true;
            bloggerjs.src = &#39;http://&#39;+disqus_shortname+&#39;.disqus.com/blogger_item.js&#39;;
            (document.getElementsByTagName(&#39;head&#39;)[0] || document.getElementsByTagName(&#39;body&#39;)[0]).appendChild(bloggerjs);
          })();
        </script>
      </b:if>
      <b:if cond='data:blog.pageType == &quot;static_page&quot;'>
        <style type='text/css'>
          #comments {display:none;}
        </style>
        <script type='text/javascript'>
          location.pathname !== &#39;/b/post-preview&#39; &amp;&amp; (function() {
            var bloggerjs = document.createElement(&#39;script&#39;);
            bloggerjs.type = &#39;text/javascript&#39;;
            bloggerjs.async = true;
            bloggerjs.src = &#39;http://&#39;+disqus_shortname+&#39;.disqus.com/blogger_item.js&#39;;
            (document.getElementsByTagName(&#39;head&#39;)[0] || document.getElementsByTagName(&#39;body&#39;)[0]).appendChild(bloggerjs);
          })();
        </script>
      </b:if>

5. 課題

ページ対応で、次のように||(or)を使って書いてみたのですが、動作せず、正しい書き方が分かりませんでした。

<b:if cond='data:blog.pageType == &quot;item&quot; || data:blog.pageType == &quot;static_page&quot;'>

次に、以下のように書いてみたところ、PCでは動作したのですが、モバイルではBloggerのコメント欄が出てしまいました。

<b:widget id='HTML1' locked='false' mobile='yes' title='Disqus for ◯◯◯' type='HTML'>
<b:includable id='disqus_item_js'>
  <style type='text/css'>
    #comments {display:none;}
  </style>
  <script type='text/javascript'>
    location.pathname !== &#39;/b/post-preview&#39; &amp;&amp; (function() {
      var bloggerjs = document.createElement(&#39;script&#39;);
      bloggerjs.type = &#39;text/javascript&#39;;
      bloggerjs.async = true;
      bloggerjs.src = &#39;http://&#39;+disqus_shortname+&#39;.disqus.com/blogger_item.js&#39;;
      (document.getElementsByTagName(&#39;head&#39;)[0] || document.getElementsByTagName(&#39;body&#39;)[0]).appendChild(bloggerjs);
    })();
  </script>
</b:includable>
<b:includable id='main'>
...
      <b:if cond='data:blog.pageType == &quot;item&quot;'>
          <b:include name='disqus_item_js'/>
      </b:if>
      <b:if cond='data:blog.pageType == &quot;static_page&quot;'>
          <b:include name='disqus_item_js'/>
      </b:if>
...
</b:includable>
</b:widget>

ということで、残念ながら、非常に冗長な記述になっています。

2012年2月13日月曜日

ブログの記事をFacebookのAdd To Timeline(タイムラインに追加)に対応させる

Open Graph対応の何となくソーシャル風味なブログを作ってみた」で書いたように、このブログの記事を読んだことがFacebookのタイムラインに表示されるようなOpen Graph対応アプリを作成しましたので、作り方をまとめます。

Facebookアプリとしては最も簡単な部類に入るでしょうが、初めてだとそれなりに勉強になるかとは思います。

1. Open Graphを理解する

まずはFacebook開発者サイトの、以下のチュートリアルを読み、やるべきことを理解します。

Tutorial - Facebook開発者

2. アプリを作成

Facebookアプリの作成方法については割愛し、ブログを使ったウェブアプリの作成に必要な項目だけにとどめます。

まずは基本設定で以下を入力します。それぞれの環境に合わせて読み替えてください。

  • アプリのドメイン: ovreneli.blogspot.com
  • アプリをFacebookに結合する方法→ウェブサイト
    サイトURL: http://ovreneli.blogspot.com/

次に、[オープングラフ]-[Getting Started]でアクションとオブジェクトを定義します。

このアプリでは「read a article」としましたが、それだとニュースという扱いになるようです。

3. OGPの記述を追加

ここからはブログ側での作業になります。

OGPって何?って方は、以下のリンクに詳しくまとまっていますので、ぜひお読みください。

フェイスブック、ミクシィ、グリーで使われている OGP (Open Graph Protocol) とは何か - IT戦記

「いいね!」ボタン導入の際にすでにOGPを記述されている場合でも、オブジェクトの定義は追加する必要があるかと思います。「read a article」のarticleです。

Bloggerの場合、index(トップページ、ラベル)、item(記事ページ)、archive(アーカイブ)、static_page(固定ページ)の4種類のページタイプがあるみたいですが、itemのページでog:typeをarticleに設定する必要があります。

以下、Bloggerテンプレートでの記述例です。他のテンプレートをお使いの場合は読み替えてください。

名前空間の追加(青字の部分)

<html b:version='2' class='v2' expr:dir='data:blog.languageDirection'
  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#'>

OGPの追加(<head>と</head>の間、<b:skin>の上あたりがよさそう)

<b:if cond='data:blog.pageType == &quot;index&quot;'>
    <meta expr:content='data:blog.title' property='og:title'/>
<b:else/>
    <meta expr:content='data:blog.pageName' property='og:title'/>
</b:if>
<b:if cond='data:blog.pageType == &quot;item&quot;'>
    <meta content='article' property='og:type'/>
<b:else/>
    <meta content='blog' property='og:type'/>
</b:if>
    <meta expr:content='data:blog.url' property='og:url'/>
    <meta expr:content='data:blog.title' property='og:site_name'/>
    <meta content='画像のURL' property='og:image'/>
    <meta content='アプリケーションID' property='fb:app_id'/>
    <meta content='ja_JP' property='og:locale'/>

4. Add To Timelineプラグインを設置

<body>のすぐ下あたりに、以下を追加します。
「いいね!」ボタンをiframe以外で設置している場合は、window.fbAsyncInitの追加だけで済むと思います。

<div id='fb-root' style='display:none;'></div>
<script>
window.fbAsyncInit = function() {
  FB.init({
    appId: 'アプリケーションID',
    status: true,
    cookie: true,
    oauth: true
  });
};

(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = '//connect.facebook.net/ja_JP/all.js#xfbml=1&amp;appId=アプリケーションID';
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>

次に、サイドバーなどにHTML/JavaScriptガジェットを追加します。

<fb:add-to-timeline></fb:add-to-timeline>

テンプレートを保存して、プラグインの表示を確認します。

また、この時点で、curlを使って動作確認することが可能です。
確認方法は、アプリのページの[オープングラフ]-[Dashboard]で、Action Types: Readの「Get Code」を参照してください。

5. publishの実装

最後に、fbAsyncInit内に「read a article」をpublishする実装を追加します(青字の部分)。

publishする条件は以下です。

  • ページのog:typeがarticleであること
  • ユーザーが「タイムラインに追加」でアプリを許可していること

og:typeの判定はBloggerテンプレートのページタイプで代替していますが、環境によってはJavaScriptで判定するなど、いくつかの方法が考えられると思います。

<div id='fb-root' style='display:none;'></div>
<script>
window.fbAsyncInit = function() {
  FB.init({
    appId: 'アプリケーションID',
    status: true,
    cookie: true,
    oauth: true
  });
<b:if cond='data:blog.pageType == &quot;item&quot;'>
  FB.getLoginStatus(function(response) {
    if (response.status === 'connected') {
      setTimeout(function() {
        FB.api('/me/news.reads', 'post', { article: '<data:blog.url/>' }, function(response) {
          /*window.console &amp;&amp; console.log(response);*/
        });
      }, 15000);
    }
  });
</b:if>
};

(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = '//connect.facebook.net/ja_JP/all.js#xfbml=1&amp;appId=アプリケーションID';
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>

テンプレートを保存して、動作確認をします。

うまくいくと、15秒後にタイムラインに出るはずです。Washington Post Social Readerなどのニュースと一緒になってしまうんですけど…

成功した場合、FB.apiのコールバックでresponse.idがセットされていますので、動作しなければresponseを確認しましょう。

まとめ

最も簡単なFacebookアプリの作り方を紹介しました。

日本でもそろそろOpen Graph対応アプリの開発が活発になると面白いなと思っています。

2012年2月12日日曜日

Open Graph対応の何となくソーシャル風味なブログを作ってみた

設定方法など、解説エントリーは後で追加していきたいと考えていますが、今回はひとまず、カスタマイズした内容をまとめておきます。

1. タイムラインに追加

FacebookのOpen Graph活用事例です。

ブログの右側にある「タイムラインに追加」ボタンを押すと、以後、このブログの記事を読んだというアクティビティが、タイムラインに表示されるようになります。

今のところ控えめに、15秒以上読んでいただいた場合に限定しています(笑)

ぜひ「タイムラインに追加」を押して、15秒以上読んでいただければと思います。

2. DISQUSコメントシステム

どうしてFacebookのコメント使わないの?って言われそうですが、Facebook以外のアカウントでもコメントできる方がいいと考えて、DISQUSを選択しました。

Twitter、Facebook、Googleなどのアカウントでコメントできます。

また、モバイルでも利用可能です。

3. ソーシャルボタン

共有ボタン類

Blogger標準の共有ボタンは挙動も含めイマイチなので、自分で設置しました。

技術的な内容を書いていくつもりなので、LinkedInも含めています。

フォローボタン類

右側に各種SNSのフォロー系ボタンをまとめてみました。

どれもフォロアーが多くないですが、そこは今回の主題ではありませんし、設置すると効果があるかという実験でもありますので、気にしないでください><

4. Google+連携

読者の方には関係のない話ですが、投稿後に投稿をGoogle+で共有するのが、非常に簡単になっています。

5. 今後の課題

  • 「タイムラインに追加」のモバイル対応
  • 「ソーシャルボタン」のモバイル対応
  • 共有ボタンの追加の検討(はてなブックマーク、mixiチェックなど)

まずは形だけ整えてみたって状態ですので、内容のあるエントリーを書き続けていくのが、最大の課題ですけどね(苦笑)