A note of a person who is learning programming, SakaTaQ

ロック好きのプログラミング学習

railsのパンくず機能[gem 'gretel']

スクールの最終課題で気になっていたgemその2。
Webサイトで複数のページ構造をしている時によくある、TOP > 概要 > 会社理念みたいな足跡を表示するパンくず機能と言うのですが、これを実現する際に使用するgem 'gretel'について少し調べました。

由来は、グレーテルといえばたしか童話ですよね。センスとボキャブラリー豊富。

導入、準備

gem導入方法は公式GitHub

「Gemfile」
gem 'gretel'

// ターミナル
% bundle install

パンくずリスト構成ファイル、と言うものを生成するコマンド

$ rails g gretel:install

config/breadcrumbs.rbファイルが生成されます。
(生成されたファイルの下の方の注釈に、パンくずリスト設定ファイルを分割する場合にはconfigディレクトリ下にbreadcrumbsディレクトリを置いてその中に設定ファイルを置いてができるそうですが、それはまた別の機会に...)

設定ファイルbreadcrumbs.rbを追記

# ルート
crumb :root do
  link "トップページ", root_path
end

# マイページ
crumb :user_show do
  link "マイページ", user_path
end

# 出品商品詳細
crumb :product_show do
  link "出品商品詳細", products_path
  parent :user_show
end

一番上のcrumbの後ろは(viewから)設定ファイルで記述したリストを呼び出す際に使用する引数みたいなもの(というイメージ、後述)。 linkの部分の""の中はパンくずリストに表示されるリンクの名称、その後に記述されているのはそのページ(呼び出し元)のprefix。% rails routesを参照して書いていく。
(クリックした際にリンク先に移動するという実装をしない場合はprefixは省略してしまっても問題ないみたいです)
parentでは親の設定を行っている。ここで記入されている:user_showも先ほど同様に設定したものを書いている。マイページの上のルートは親として設定する必要はないみたいです。

今回の設定ファイルの構成での最終的な表示イメージは
トップページ > マイページ > 出品商品詳細
マイページにそのユーザーの出品した商品一覧があり、名前をクリックするとその商品の詳細が見れる、そんな変遷イメージです。

view側を追加していく

パンくずリストを表示されるページごとに記述する場合は

-# 「app/views/users/show.html.haml」
- breadcrumb :user_show
= breadcrumbs separator: " › "

1行目にある:user_showは先ほど設定ファイルにて記述した呼び出し用の引数みたいなもの。
こちらは設定されたパンくず- breadcrumb :{各crumb名}を表示する場所に記載します。
separatorオプションで、パンくずリストを区切る際に使います。
" &rsoquo; "はブラウザ上で出力されると > となります。HTMLにあるメタ文字>のように使えます。前後に入れている空白がそのまま適用されないなら&nbspを前後に入れてあげると幸せになれるのかもしれない。

= breadcrumbs pretext: "閲覧場所:", separator: " › "のように書くと、パンくずリストの前に閲覧場所:というテキストを挿入することができます。指定がない場合はデフォルトでは表示されないようになっているので、特に必要ないのであれば省略してもOK。

パンくずリストは殆どのページにて表示されるので呼び出し部分をテンプレート化してrenderを使用して呼び出すようにする、とよりいいのかもしれない。

-# 下記コードを「layouts/_breadcrumbs.html.haml」に移行
= breadcrumbs separator: " › "

-# 「app/views/users/show.html.haml」移行した部分の書き換え
- breadcrumb :user_show
= render "breadcrumbs"

今回既に用意している「app/views/products/show.html.haml」などでも

- breadcrumb :product_show
= render "breadcrumbs"

と書くことで部分テンプレートを追記する必要なく、呼び出すことができる。

renderを繰り返し書いているのでリファクタリング

今回は一例として用意してるので2つしかないですが、パンくずリストはその仕様としてこれより多くの複数のページに表示されるので、この書き込みも省略できるように書き換えていく。

パンくずリストlayouts/application.html.hamlなどで記述されるヘッダーの直下によく見かけるので各ビューで用意していたrenderをこちらに移行させる。

-# 「layouts/application.html.haml」
= render "breadcrumbs"

-# 「app/views/users/show.html.haml」、「app/views/products/show.html.haml」の render部分を削除

application.html.hamlの記述によってはパンくずリストの表示の書き込みが、各ビューより上に来てしまうので、設定ファイルから読み込む記述が後になるとエラーが出ると思います。
ので、case文などでその時使用しているコントローラー、アクションを条件分岐するための引数として渡してあげるようにして、パンくずリストの設定ファイルの呼び出しも部分テンプレート内で書き換えます、こちらの記事を参考にさせていただきました。

-# 「app/views/layouts/_breadcrumbs.html.haml」 (部分テンプレート)
- case params.value_at :controller, :action

- when ['users', 'show'] 
  - breadcrumb :user_show

- when ['products', 'show']
  -breadcrumb :product_show

= breadcrumbs separator: " › "

-# 「app/views/users/show.html.haml」、「app/views/products/show.html.haml」の - breadcrumb :〜 を削除

使用する(paramsから取得された)インスタンスやオブジェクトは設定ファイル側かview側で書かれていたので、ユーザー毎の商品詳細ページに飛ぶ際にエラーがでるのであれば
-breadcrumb :product_show, @product
と書くか、あるいは link "出品商品詳細", product_path(product) のように書いてDBからの情報を渡してあげる必要があります。


参考にさせていただいた記事
公式GitHub
【Rails】gretelを使ってパンくずリストを作成
一番わかりやすいパンくずの実装(gem 'gretel')


今回はここまで。

プロジェクトによって見ることも知ることもないgemがたくさん存在するので、よく使われているgemを一通り調べて見るのも面白いのかもしれません。
でもFWばっかり使っていて基本のrubyの部分が理解できているのか怪しい時があるため、あんまり固執しすぎない程度に学んで行ければな、と思います。

したらな❗️ 👋