【Rails】パンくずリストを作るgretelとbreadcrumbs_on_railsの使い方

WEBサイトにパンくずリストを実装します。
ここではパンくずリストの目的、SEOを意識した効果的な設置方法、私が最終的にbreadcrumbs_on_railsを使った理由、使い方を記しています。

パンくずリストの目的

昨今のWEBサイトには必ずといって良いと思うのですが「パンくずリスト」が設置されています。

これは2つの目的がありまして
・アクセスユーザーに今自分がどこにいるのかをお知らせする
・Googleクローラーにサイトの構造を理解してもらう
この2つですね。

アクセスユーザーに自分の位置をお知らせする

良質なWEBサイトの多くはTOPページだけでなく個別ページ(下層ページ)にも豊富なコンテンツが用意されており、アクセスユーザーはその下層ページの方からも流入してきます。

料理
┝ 和食
│ ┝煮物
│ ┝焼き物
│ │ ┝魚料理
│ │ ┝卵料理
│ │ │ └だし巻き卵
│ │ └肉料理
│ └炒めもの
┝ 洋食
└ 中華

このような階層構造になってた場合に、だし巻き卵のページにアクセスしてきた場合なんかは料理→和食→焼き物→魚料理→だし巻き卵 とかなり深い階層にあるページなんだなと理解する事ができます。そしてパンくずリストを見ることでその上の階層にどんなジャンルの記事があるかをたどっていくことも出来ます。他のジャンルに興味が有ればそちらにアクセスを誘導する事もできるという訳ですね。

Googleクローラーにサイトの構造を理解してもらう

こちらも重要な話です。そもそもユーザーにアクセスしてきてもらうためには何らかのキーワードでSEOで上位表示していないと厳しい訳です。サイトのブランド名を広告して広く知られているなら別ですけど、そうでなければ良質なコンテンツ、ユーザーを楽しませるコンテンツを用意して検索エンジンから呼び込まないといけません。

その時に重要なのがGoogleに適切にサイト内部をインデックスしてもらう、という事です。Googleクローラーが適切にサイト全体構造を理解するためには3つの要素があるとよくて、それが①サイトマップ②パンくずリスト③適切な内部リンク です。ここでパンくずリストを適切に設置しておくことでクローラーの読み込みを促す事につながります。

またこれが検索エンジンの結果にも現れてきます。

これがパンくずリストの目的となります。

SEOを意識した効果的なパンくずリストの設置方法

世界で標準的なパンくずリストの利用にはschema.orgを使用する事だろうと思います。Googleもこのschema.orgのパンくずリストのサポートをしています。

海外SEOで有名なSuzuki Kenichi氏のブログ

2つのやり方が記述されていますが、JSON-LDの方は自分にはレベルが高いので、microdataの方で実装します。

<ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a itemprop="item" href="/"><span itemprop="name">Home</span></a>
    <meta itemprop="position" content="1">
</li>
<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a itemprop="item" href="users_path"><span itemprop="name">ユーザー一覧</span></a>
    <meta itemprop="position" content="2">
</li>
<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <span itemprop="name">本田宗一郎</span>
    <meta itemprop="position" content="3">
</li>
</ul>

ulあるいはolタグにitemscope itemtype=”http://schema.org/BreadcrumbList”を記述。
liタグにはitemprop=”itemListElement” itemscope itemtype=”http://schema.org/ListItem”を記述。
aタグはitemprop=”item”でURLをマークアップして、
文字にはitemprop=”name”でマークアップします。
また順番をmetaタグにitemprop=”position”でマークアップ、content=で順番を記述します。ドメインTOPなら1で、階層を下るごとに2→3→4…となっていきます。

ちなみにドメインTOPのラベルは以下のようなもので構いません。

・サイトタイトル
・ブランド名
・TOP
・HOME

あまり長すぎるとスマホで見た時に最初に目に飛び込んでくる画面が見にくくなるのでシンプルで分かりやすくする方が良いでしょう。

Railsでパンくずリストを実現するbreadcrumbs_on_rails

幾つか参考サイトを見ていてRailsでパンくずリストを実現するには

・gretel gem
・breadcrumbs_on_rails

のいずれかが良いと書いてありました。特徴としてはgretelはシンプルでController側に記述せずView側に記述するシンプルなやり方なので使いやすい。breadcrumbs_on_railsはController側に記述が必要、カスタマイズがしやすい。とのこと。

gretelとbreadcrumbs_on_railsでソースはどうなるか

gretelをインストールしてパンくずリストを出してみました。

<div class="breadcrumbs"><a href="/">Home</a> &rsaquo; <a href="/users">ユーザー一覧</a> &rsaquo; <span class="current">@本田宗一郎</span></div>

このような形で出力されました。

breadcrumbs_on_railsは

<a href="/">Home</a> > <a href="/users">ユーザー一覧</a> > 本田宗一郎

という事なのでどっちにしろschema.orgに合わせて最適化を行わないといけないと思いました。結局私が選んだのはカスタマイズ方法がある参考サイトの多いbreadcrumbs_on_railsの方でした。gretelも改変できると思うのですが、自分にその技術は無く‥なので。

breadcrumbs_on_railsで最適なパンくずリストを作る方法

ここからは実際に手順を追っていきます。

1.breadcrumbs_on_railsをインストールする

Gemfileに以下を追記

gem 'breadcrumbs_on_rails'

2.バンドルインストール

$bundle install

3.コントローラーに記述

今回はテストで作ったusers_controllerに記述しました。

add_breadcrumbでドメインTOPからの階層を追記していく形で構成します。

class UsersController < ApplicationController

  # 第一引数にラベル、第二にパスを入れる
  add_breadcrumb 'Home', '/'
  add_breadcrumb 'ユーザー一覧', :users_path


  def show
    
    @user = User.find(params[:id])
    
    # 第二引数を省くとリンクではない階層を作れる、最後の階層はリンク不要なのでパスは書かない
    add_breadcrumb @user.name

  end

end

4.VIEW側に記述

共通レイアウトのapplication.htmlに以下を記述しました。

/app/views/layouts/application.html

<%= render_breadcrumbs separator: ' > ' %>

5.一旦完成

これで出来ました。
でも、このままだとschema.orgのパンくずリストの仕様にはなっていないので、ここから改変していきます。

参考にさせいただいたサイト:http://nishio.hateblo.jp/entry/2013/08/24/233004

6.custom builderを作成します

/lib/custom_breadcrumbs_builder.rbを作成します。

class CustomBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder

  def render
    @context.render "/layouts/breadcrumbs", elements: @elements
  end
end

@elementsには、先程controllerで追記した
Home /
ユーザー一覧 :users_path
ユーザー名 nil

がハッシュで入っています。

7.パンくずリストのVIEW部分を作ります

layouts/_breadcrumbs.html.erbをを作成します

<% if elements.present? %>
  <ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
    <% elements.each_with_index do |element, i| %>
    <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <% if element.path.present? %>
        <% if element.equal?(elements.last) %>
          <span itemprop="name"><%= element.name %></span>
        <% else %>
          <a itemprop="item" href="<%= element.path %>"><span itemprop="name"><%= element.name %></span></a>
        <% end %>
        <meta itemprop="position" content="<%= i+1 %>">
      <% else %>
        <span itemprop="name"><%= element.name %></span>
        <meta itemprop="position" content="<%= i+1 %>">
      <% end %>
    </li>
    <% end %>
  </ul>
<% end %>

これさっきのschema.orgを利用した構造です。全てのelementsをeach_with_indexで回してliタグでリストします。ラベルはelement.nameで取り出せるし、パスはelement.pathで取り出せますので、それをaタグに入れています。metaタグのitemprop=”position”には順番を記述するのでトップから1→2→3となるようにインデックス(i)を出力させています。

<% if element.equal?(elements.last) %>

これが何をやってるのかというと、最後の要素だったらリンクタグを生成しないように条件を入れています。

controller側で

    # 第二引数を省くとリンクではない階層を作れる、最後の階層はリンク不要なのでパスは書かない
    add_breadcrumb @user.name

とやってるのでもともと問題ありませんが、間違って以下のようになっても大丈夫です。

    add_breadcrumb @user.name, :user_path

8.VIEWの呼び出し部分を変更します

/app/views/layouts/application.htmlの修正です。

<%= render_breadcrumbs separator: ' > ' %>

<%= render_breadcrumbs builder: ::CustomBreadcrumbsBuilder %>

としました。セパレーターはデフォルトだと / みたいです。>にするんだったら_breadcrumbs.html.erbをいじれば良いと思います。

9.Railsを起動したらエラーが出た

uninitialized constant CustomBreadcrumbsBuilder

ここで1時間彷徨いました(汗

このエラー、「定数CustomBreadcrumbsBuilderが初期化されてないよ」と読めます。このクラスは先程のサイト様を拝見して作ったのでここでエラーが出ちゃうとどうしようかな、という感じ。

あれこれ調べていたらlib配下に作った自作クラスは標準では読み込んでくれないらしいですね。

lib配下を読み込んでくれるように、config/application.rbに以下を追記しました。

config.autoload_paths += %W(#{config.root}/lib)

が‥駄目っ‥‥!

同じエラーが出ます。テックアカデミーの先生に泣きついたら解決しました^p^
application.rbに追記するのでは駄目で、今回のプロジェクトのmoduleの中に入れないと駄目なんだそう。。

module Microoposts
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    #lib以下の自作クラスを読ませるため
    config.autoload_paths += %W(#{config.root}/lib)
  end
end

これでパンくずリストの実装が完成しました!

10.herokuにデプロイしたらエラーが

「heroku We’re sorry, but something went wrong.」

(´;ω;`)なんでこうエラーばかり出るんだろう。
新しいことをやる→エラー→対処法探す→エラー→心折れそうになる→ついに正解を実装!→開発環境ではOK→herokuにアップ→エラー(´Д⊂グスン

Railsってこんなんばっかりや。

今回のWEBアプリ完成したらもうRailsもRubyもさわらんぞ。(●`ε´●)ワイはPHPに行くんや。

で、herokuにデプロイしてエラー出たので‥またかよ(#^ω^)

$ heroku logsでログを確認しました。

ActionView::Template::Error (uninitialized constant CustomBreadcrumbsBuilder):

ん?またもや自作のlib配下のクラスCustomBreadcrumbsBuilderが読めないと言われてる。。

こちらを参考にしました。↓
HerokuでRailsアプリのlibフォルダが読み込まれない時の対処法

config/environments/production.rbのファイルを編集。最後のendの前に追記しました。

  #herokuでlib以下を読ませる
  config.eager_load_paths += %W( #{config.root}/lib )
  
end

最後に構造化データテストツールに入れてチェックです。

Schema Markup Testing Tool | Google Search Central  |  Google for Developers
Use the Rich Result Test to see what Google results can be generated for your pages and the schema markup validator for generic schema validation.

これでパンくずリストがheroku環境でもできました。

ということで今日は以上です。