はじめに
先日初めて「パンくずリスト」というものの実装に挑戦したので、
備忘録的にGretelによるパンくずリストの実装について以下にまとめます。
筆者は、エンジニアを目指して学習中の初学者です。
内容に誤りや分かりにくい表現、初歩的な内容が含まれている可能性がありますが、ご容赦いただけますと幸いです。
パンくずリストって?
実物(画像)を見ると「これパンくずっていうんや〜」ってなりました。
「マイドライブ > 〇〇フォルダ > 〇〇フォルダ」みたいなやつのことです。

このような現在ユーザーがいるページの階層構造を表したものを、通称「パンくず」と呼びます。
開発環境
- Ruby: 3.1.4
- Ruby on Rails: 7.0.4
- Gretel(パンくずリスト)
パンくず実装のための使用技術
パンくず実装のために使用した技術が、Gretel(グレーテル)というgemです。
(名前がオシャレすぎて驚きました...)
https://github.com/kzkn/gretel
公式ドキュメントの内容も初学者の私でもなんとな〜〜〜くわかるくらいの内容で、
そんなに複雑な実装手順ではありません。
今回の実装状況
【現状】管理画面のタグページに、パンくずが設定されていない
【目標】既存のパンくずに合わせた設定を行い、「タグ一覧ページ」と「タグ編集ページ」にパンくずを表示させる改修
「一部パンくずが実装できてないページがあるから、実装していくぞ」という内容です。
viewファイルの構造が以下です。
app/
└── views/
└── admin/
| └── tags/
| ├── edit.html.slim (タグ編集ページ)
| └── index.html.slim (タグ一覧ページ)
└── layouts/
└── admin.html.slim(管理画面のレイアウト)
パンくずの実装手順
パンくずの実装手順は大まかに3ステップです。
- breadcrumb(パンくず)をconfigで定義する
- 「このページではこのパンくずを使う」と宣言する
- 「宣言したパンくずを実際に画面に表示する」記述をする
1. breadcrumbの定義
まずはパンくずの定義をしていきます。
定義する項目は以下の4つです。
- パンくずを呼び出す時の「定義の名前」
- 実際にページに表示する「ページ(パンくず)の名前」
- 表示時に参照する「ページのパス」
- 階層構造の一つ上の親がいるなら「親のパス」
# config/breadcrumbs.rb
# Home
crumb :admin_dashboard do
link '<i class="fa fa-dashboard"></i> Home'.html_safe, admin_dashboard_path
end
# タグ一覧ページ
crumb :admin_tags do
link 'タグ', admin_tags_path
parent :admin_dashboard
end
# タグ編集ページ
crumb :edit_admin_tags do |tag|
link 'タグ編集', edit_admin_tag_path(tag.id)
parent :admin_tags
end
タグ編集ページを例にすると、
:edit_admin_tags : 定義の名前。viewファイルでの呼び出しに使用する
link 'タグ編集' : 「〇〇 > タグ > タグ編集」と表示する時の表示文字列です。クリック時にページ遷移できるようにlinkとしています。
edit_admin_tag_path(tag.id) :もしクリックされたらこのページに遷移しなさい。という指示です。
parent :admin_tags : このパンくずの親は、「タグ(admin_tags)」だよ。という指示です。
2. 「このページではこのパンくずを使う」と宣言する
これは一文追記するだけです。
例えば、「タグ編集ページでパンくずを表示したいぞ〜」であれば、一つ前のステップで定義したedit_admin_tagsのパンくずの設定を参照する!と宣言するだけです。
# app/views/admin/tags/edit.html.slim
= content_for 'content-header' do
| タグ編集
# これが宣言(定義の名前を呼び出すだけ)
- breadcrumb :edit_admin_tags, @tag
注意点ですが、この記述は表示処理を行っているわけではありません。
あくまで宣言のみをしており、別のファイルで実際の表示をしています。
3. 「宣言したパンくずを実際に画面に表示する」記述をする
こちらは管理画面のレイアウトを一手に担っているファイルに記述します。
こちらも追記するのは一文です。
main.content-wrapper
section.content-header
h1
= yield 'content-header'
# この一文が表示の追記
== breadcrumbs style: :ol, class: 'breadcrumb'
breadcrumbsというメソッドが、パンくずの文字列を表示するHTMLを自動生成してくれる便利メソッドです。
実際のパンくずの画面出力はこの一文が担っています。
処理の流れ
これら3つのファイルがパンくずを表示するに至るまでの流れが以下になります。
1. ビューで「このページではこのパンくずを使う」と宣言
# app/views/admin/tags/edit.html.slim
- breadcrumb :edit_admin_tags, @tag
するとGretelはこう読みます。
【Gretel】「なるほど。このページでは、:edit_admin_tagsってパンくずを使うんだな。定義を見に行こう」
2. Gretelが config/breadcrumbs.rb を参照
crumb :edit_admin_tags do |tag|
link 'タグ編集', edit_admin_tag_path(tag.id)
parent :admin_tags
end
【Gretel】「:edit_admin_tags は、'タグ編集' というリンクを持っていて、親は:admin_tags なんだな。じゃあ、親も読み込もう…」
3. 親のパンくず定義も再帰的に読み込む
crumb :admin_tags do
link 'タグ', admin_tags_path
parent :admin_dashboard
end
【Gretel】「:admin_tags は、'タグ' というリンクを持っていて、さらに:admin_dashboardという親がいるんだな。じゃあもう一つ上を読み込もう...」
crumb :admin_dashboard do
link '<i class="fa fa-dashboard"></i> Home'.html_safe, admin_dashboard_path
end
【Gretel】「:admin_dashboard は、'Home' というリンクを持っていて、さらに親はいないんだな(parent がない)。じゃあ、これがパンくずのルート(一番上)だな」
4. breadcrumbs メソッドが呼ばれたときに、HTMLを生成
# app/views/layouts/admin.html.slim
== breadcrumbs style: :ol, class: 'breadcrumb'
この一文が読み込まれた時点で、Gretelは以下のようなHTMLを生成します。
<ol class="breadcrumb">
<li><a href="/admin/dashboard">Home</a></li>
<li><a href="/admin/tags">タグ</a></li>
<li class="active">タグ編集</li>
</ol>
-
親から順番に HTML要素が生成される(
:admin_dashboard→:admin_tags→:edit_admin_tags) - 各
linkメソッドで指定された文字列が、<a>タグの中身になる -
.html_safeがついている文字列は、そのままHTMLとして解釈される(エスケープされない)
実際にこんなふうに表示される
今までの実装内容を経て、画面に表示されるパンくずがこちらです。

Homeの左横の画像は、<i class="fa fa-dashboard"></i> Homeの<i>タグが解釈され、しっかり画像として表示されています。
まとめ
改めて処理の流れをまとめると以下になります。
1. 各crumbのlinkを取得
- :admin_dashboard → '<i>...</i> Home'.html_safe
- :admin_tags → 'タグ'
- :edit_admin_tags → 'タグ編集'
↓
2. breadcrumbsメソッドが、これらを組み合わせてHTMLを生成
- html = '<ol class="breadcrumb">...'
- html += '<li><a href="...">Home</a></li>'
- html += '<li><a href="...">タグ</a></li>'
- html += '<li class="active">タグ編集</li>'
- html += '</ol>'
↓
3. 最終的なHTML全体にhtml_safeを適用
- html.html_safe
↓
4. レイアウトファイルで出力
- == breadcrumbs → HTMLとして解釈されて画面に表示
定義と宣言、最後にbreadcrumbsメソッドの一言を記述するだけで
ページ遷移に合わせて動的に「パンくず」を表示してくれるGretelの便利さに驚きました。
「パンくず」リストを実装するためのgemの名前を「グレーテル」にしたセンスにも感動しすぎて、忘れられないgemの名前としてがっちり記憶されてしまいました。
将来エンジニア同士で好きなgemの話題があがれば「Gretel」を真っ先に挙げようと思います笑
...もしかして鉄板すぎるでしょうか?