Rails / Turbolinksに対応したソーシャルボタンを配置する(Facebook, Twitter, Google+, Pocket, はてブ)

Shunsuke Sawada

Railsの強い味方 Turbolinks ですが、イベントが発火しないとか、気をつけるところもあります。今回は、種類も多いし、面倒くさそうだなぁと思っていたソーシャルボタンに手をつけてみました。

参考

Turbolinks Compatibility
Turbolinksで困ったら、いつもここを見ます。
  
最近海外で流行りのTwitter,Facebook,Google+1,Analyticsをまとめる非同期スクリプトにはてなを加えてみた
非同期スクリプト。ヘッダ内に使わせてもらいました。
  
turbolinks対応で「はてブボタン/Twitterボタン/Facebook いいねボタン/Google Analytics」を読み込む[Rails 4]
まさにコレなんですが、種類が少ないのと、自分の環境では動かなかった。
  

試行錯誤

head内で読み込んでいるスクリプトと、page:loadのタイミングで読み込むスクリプトが重複してるんじゃないか…?とか、自信がありませんが動いてます。
詳しい人教えてください :)
  
Screen Shot 2014-05-19 at 12.49.35 AM

HTMLヘッダ

layouts/application.html.erb

html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  <script>
  (function(w,d){
    var s,e = d.getElementsByTagName("script")[0],
    a=function(u,f){if(!d.getElementById(f)){s=d.createElement("script");
    s.async=!0;s.src=u;if(f){s.id=f;}e.parentNode.insertBefore(s,e);}};

    a("https://apis.google.com/js/plusone.js");
    a("//b.st-hatena.com/js/bookmark_button_wo_al.js");
    a("//platform.twitter.com/widgets.js","twitter-wjs");
    a("https://widgets.getpocket.com/v1/j/btn.js?v=1");
  })(this, document);
  </script>

  

Javascript

Facebookのところの、appIdとchannelUrlを変更します。
https://developers.facebook.com にいって、アプリを1つ登録する必要があるようです。
  
facebook
   
それと、channel.htmlもつくってアップ。
中身は一行だけだとな。

html
1
<script src="//connect.facebook.net/ja_JP/all.js"></script>

  
assets/javascripts/social_button.js.coffee

coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
ready = ->

  # Facebook
  loadFacebookSDK()
  bindFacebookEvents() unless fb_events_bound

  # Google
  loadGoogleSDK()
  gapi.plusone.go()

  # Twitter
  loadTwitterSDK()
  bindTwitterEventHandlers() unless twttr_events_bound

  # Hatena
  loadHatenaSDK()

  # Pocket
  loadPocketSDK()

# For turbolinks
$(document).ready(ready)
$(document).on('page:load', ready)



# ----------------------------------------- #
# Facebook
# ----------------------------------------- #

fb_root = null
fb_events_bound = false

bindFacebookEvents = ->
  $(document)
    .on('page:fetch', saveFacebookRoot)
    .on('page:change', restoreFacebookRoot)
    .on('page:load', ->
      FB?.XFBML.parse()
    )
  fb_events_bound = true

saveFacebookRoot = ->
  fb_root = $('#fb-root').detach()

restoreFacebookRoot = ->
  if $('#fb-root').length > 0
    $('#fb-root').replaceWith fb_root
  else
    $('body').append fb_root

loadFacebookSDK = ->
  window.fbAsyncInit = initializeFacebookSDK
  $.getScript("//connect.facebook.net/ja_JP/all.js#xfbml=1")

initializeFacebookSDK = ->
  FB.init
    appId     : 000000000000000
    channelUrl: '//YOURDOMAIN/channel.html'
    status    : true
    cookie    : true
    xfbml     : true

# ----------------------------------------- #
# Twitter
# ----------------------------------------- #

twttr_events_bound = false

bindTwitterEventHandlers = ->
  $(document).on 'page:load', renderTweetButtons
  twttr_events_bound = true

renderTweetButtons = ->
  $('.twitter-share-button').each ->
    button = $(this)
    button.attr('data-url', document.location.href) unless button.data('url')?
    button.attr('data-text', document.title) unless button.data('text')?
  twttr.widgets.load()

loadTwitterSDK = ->
  $.getScript("//platform.twitter.com/widgets.js")

# ----------------------------------------- #
# Google
# ----------------------------------------- #

loadGoogleSDK = ->
  $.getScript("https://apis.google.com/js/plusone.js")

# ----------------------------------------- #
# Hatena
# ----------------------------------------- #

loadHatenaSDK = ->
  $.getScript("//b.st-hatena.com/js/bookmark_button_wo_al.js")

# ----------------------------------------- #
# Pocket
# ----------------------------------------- #

loadPocketSDK = ->
  $.getScript("https://widgets.getpocket.com/v1/j/btn.js?v=1")

  

Viewファイル

@postが渡っているという前提で、twitterの本文には@post.titleを挿入しています。
  

html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<div class="social clearfix">

    <!-- Facebook -->
    <div class="button facebook">
        <div id="fb-root"></div>
        <div class="fb-like"
            data-href="<%= request.original_url %>"
            data-layout="button_count"
            data-send="false"
            data-width="120"
            data-show-faces="false">
        </div>
    </div>

    <!-- Twitter -->
    <div class="button twitter">
        <a href="https://twitter.com/share" class="twitter-share-button"
            data-lang="en"
            data-url="<%= request.original_url %>"
            data-text="<%= @post.title %>"
        >Tweet</a>
    </div>

    <!-- Pocket -->
    <div class="button pocket">
        <a href="https://getpocket.com/save" class="pocket-btn"
            data-lang="en"
        data-save-url="<%= request.original_url %>"
        data-pocket-count="horizontal" 
        data-pocket-align="left"
      >Pocket</a>
    </div>

    <!-- Google plusone -->
    <div class="button google">
        <div class="g-plusone"
            data-size="medium"
            data-href="<%= request.original_url %>">
        </div>
    </div>

    <!-- Hatena -->
    <div class="button hatena">
        <a href="http://b.hatena.ne.jp/entry/<%= request.original_url %>" 
            class="hatena-bookmark-button"
            data-hatena-bookmark-layout="standard"
            data-hatena-bookmark-lang="ja" 
            title="このエントリーをはてなブックマークに追加">
            <img src="http://b.st-hatena.com/images/entry-button/button-only.gif"
            alt="このエントリーをはてなブックマークに追加" width="20" height="20"
            style="border: none">
        </a>
    </div>
</div>

  

CSS

これはおまけ。CSSで奇麗に整えました。
  

scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.social {
    .button {
        float: left;
        overflow: hidden;
        margin-right: 5px;
        margin-bottom: 4px;
        &.facebook {
            margin-right: 17px;
        }
        &.twitter {
            width: 90px;
        }
        &.pocket {
            width: 100px;
        }
        &.google {
            width: 70px;
        }
        &.hatena {
            margin-right: 17px;
        }
    }
}

118
Shunsuke Sawada

おすすめの記事

acts-as-taggable-on タグを表示させる順番を決めたい
Railsを4.2にバージョンアップしたら、Vagrantのローカル開発環境にアクセスできなくなった問題
Railsのバリデーションエラー後にレイアウトが崩れるとき