Laravel開発、パンくずリストを利用して現在いるページを分かりやすくする
今まで散々本番環境に載せる為にS3の処理をしていたので、他が止まってしまっています。
今回はまずパンくずリストを実装して、いまどのページにいるのか?が分かりやすいようにしました。
途中で作成サイトの構造に問題があることが分かったため、レイアウトの修正も併せて記載しています。
今回の目的
現在表示のページを分かりやすくする為のリスト表示を追加する
なぜやるか
誰が見てもどのページを表示しているか分かるようにする為
やりたいこと
パンくずリスト利用によるページ位置を表示させる
やったこと
- パンくずリスト用ライブラリを実装
- テキスト表示できるか確認する
- ヘッダ内部に組み込む
- ルート表示を利用してパンくずリストを書く
- Route::currentRouteName()とは?
- パンくずリストのレイアウトを変更する
- 引数を追加してパンくずリストで本のタイトルを出す
- レイアウトとコンポーネントの扱い方を見直す
- 見直したレイアウトでパンくずリストを実装する
実施内容
パンくずリスト用ライブラリを実装
パンくずリストを実装するために、まずは必要となるlaravel-breadcrumbsを実装しました。
実装にあたっては下記サイトを参考にさせて頂きました、ありがとうございます。
インストールコマンド実行して組み込みます。
$ composer require davejamesmiller/laravel-breadcrumbs:5.x
これで元となるライブラリは適用完了です。
パンくず用テキストを表示させる
まずパンくずの内容を最低限かいて、実際に必要なテキストが表示できるかを確認することから始めました。
パンくずルート設定を記載するファイルを新規作成します。
# ~/routes/breadcrumbs.php
トップページと書籍を扱うbookのindexページをまず記載しました。
これで、まず'トップページ'が表示されることを確認します。
# ~/resouces/views/index.blade.php
8行目の記述になります。
'toppage'を指定することで、対象のページで設定したテキストが表示される流れとなります。
今回、トップページではパンくずリストは表示しないのですが、きちんと動作していることを確認する為にも上位ページから試すことにしました。
# トップページ
ちょっと見づらいですが、"トップページ"のテキスト表示ができました。
次にbook.indexページでテキスト表示できることを確認します。
# ~/resouces/views/book/index.blade.php
14行目の記述になります。パンくず設定を入れて上げることで、トップページ同様に動作することを期待して、表示を確認します。
# book.index
上の"トップページ>書籍"が最終的に表示させたいパンくずリストですが、あれはまだ仮置きです。
今回設定したパンくずリスト表示は
トップページ
書籍トップ
と下の方に表示されている部分です。
まず最低限のコード記述でテキスト表示できていることが確認できたので、これを仮置きテキスト部分に反映させていきます。
ヘッダ内部に組み込む
ヘッダはレイアウトファイルからコンポーネントを参照しているのでコンポーネントファイル内の仮置きテキスト部分をまず変更してみます。
# ~/resouces/views/components/header.blade.php
仮置していたテキストのすぐ下に先程のパンくず表示コードをとりあえず入れてみて表示を確認。
# book.index
表示できました。
この調子で他も書いていけばできそうです。
ルート表示を利用してパンくずリストを書く
レイアウト内にパンくずリストを記載しているので、他のページを表示させると、パンくずリストの表示先も変わります。
最初に紹介した参考サイト内でページ毎に対応したパンくず表示をさせる記述があったので、利用してみることにしました。
これができれば、ぐっと楽に作成できそうです。
# ~/resouces/views/components/header.blade.php
21行目が元々記載していな内容です。
22行目が変更後のコード。こうすることで自動対応するようです。
想定ではどちらもパンくず表示ができるので、このまま表示させれば同じ物が2つ出てくると考えました。
しかし、エラーとなってしまいました。
Breadcrumb not found with name "book.index"
"book.index"がありませんという内容です。
先程つくっていたパンくずリストでは"book.index"ではなく"book"で作成していました、indexページなので".index"省略して記述していました。
パンくずリスト設定とrender設定の名前が一致してれば動くようなのですが、この標記にするのであれば"book.index"にパンくず側を合わせて上げれば良さそうです…が、
Route::currentRouteName()が何をしているか
ここで、そもそもRoute::currentRouteName()が分かっていなかったので確認したのですが、現在のページのルート情報が表示されるようです。確認してみました。
bookディレクトリのindexアクションなので"book.index"です。
# ~/resouces/views/book/index.blade.php
php記述で書いて実際に動かしてみました。
# book.index
"book.index"と表示されました。
この"book.index"という標記でパンくず側を作成すれば、ヘッダ側は特に変更させることなくパンくずを全ページで実装できそうです。
というわけで、ヘッダを修正
# ~/resouces/views/components/header.blade.php
この一文のみで全ページに対応できます。
パンくず設定を先程のルート表示に修正。
# ~/routes/breadcrumbs.php
設定反映内容を確認します。
# book.index
これでルート表示からとっていた値を利用してパンくず表示ができそうです。
パンくずリストのレイアウトを変更する
後はパンくずリストの表示がテキストで縦にならんで表示されているので、これを最初に仮置していた、横に階層構造のような順序で表示されるように変更します。
まずコンフィグ設定をするために、コンフィグファイルを生成します。
生成にはコマンドを実行してあげると出来るようなので、早速実施。
$ php artisan vendor:publish --provider="DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider"
# ~/config/breadcrumbs.php
26行目の表示を変更します。
ここで指定したファイルのレイアウトを参照してパンくず表示されるようになります。
指定した場所でコンポーネントを作成します
# ~/resouces/views/components/breadcrumbs.blade.php
$breadcrumbsにパンくずのルートがはいっており、foreachで繰り返し取り出してパンくずリストを作成しています。リストタグを利用しており、これにスタイルシート設定を加えることで仮置テキストと同様の形に合わせていきます。
$breadcrumbsで値が取り出せているかの確認もしてみました。
# ~/resouces/views/components/breadcrumbs.blade.php
ヘッダにブレークポイントを設定して一時的に処理を中断させてみました。
ビューファイルではできないかと思いましたが、phpコードで埋め込んでみたらできました。
# ターミナル
ローカルサーバ起動しているターミナルで$breadcrumbsに値がセットされていることを確認しました。
さらに、配列ですので内部の値を順番に指定することで、トップページから書籍のトップページへと情報が格納されていることを確認しました。
# book.index
後はスタイルシートによる記述を変更することで、パンくずらしい表示になってきました。
引数を追加してパンくずリストで本のタイトルを出す
ベースはできたので、後は現在実装済みの他のページについてもパンくずリスト設定を作成します。
書籍の新規登録と詳細ページの記述を増やしてみました。
# ~/routes/breadcrumbs.php
まず、書籍新規登録は単純に新規登録の表示ができればいいので、これですんなり完成しました。
書籍詳細情報ページについては書籍タイトルをパンくずに表示させる為に$bookと本の情報を追加で引き渡すことにしました、この情報はコントローラ上で詳細ページに表示する本の情報が格納されているので、それを使い回す記述です。
これで表示…される予定が表示されず。
確認してみると、たしかにコントローラで$bookの情報は渡されていました。
しかし、コンポーネントには引数として値を渡して上げないと変数として扱えないことが分かりました。
そこで、レイアウト内のヘッダコンポーネント参照箇所で$bookを扱えるようにしました。
# ~/resouces/views/layouts/layout.blade.php
これでパンくずリスト参照する為のコードで$bookの情報が反映されるはずです。
しかし、まだエラーの状況は変わりませんでした。
そもそもパンくずに対しての呼び出しをしている所で対象の引数として加える必要があることが分かりました。
記述を下記の通り変えてみます。
{{ Breadcrumbs::render(Route::currentRouteName()) }}
↓
{{ Breadcrumbs::render(Route::currentRouteName(),$book }}
ここで使用する変数がなかった為、扱う情報ないまま表示しようとしていました、これでは動きませんね…。しかし、上位で順番に変数を引き渡すも必要でした。
これで表示できるか確認します。
# book.show
テスト登録本1というタイトルが表示できました。
これで、今までのページは$bookという引数は必要なかったのですが、book.showでは$bookが必要となります。
これを分岐させて一度コードを書いてみました。
# ~/resouces/views/layouts/layout.blade.php
しかしこの記述にはいろいろと問題があります。
現時点ではこれで確かに動作しますが、作成済みのページを考えると編集ページでのパンくず表示で「編集:タイトル」などするとなるとif文にshowとeditを許容するパターンで書くことになります。
また、マイページで例えばユーザ名を表示するなどと考えると、さらに複雑になります。
この手順のまま実装するには問題がありそうです。
レイアウトとコンポーネントの扱い方を見直す
パンくずリストの内容を扱っている中で、ルート表示名を利用した標記を扱っていましたが、各ページ毎にパンくず設定を追加するパターンにすれば、設定毎に追加変数を個別作成出来そうでした。
そこで、せっかくルート表示名を利用していたのですが、それぞれのページにパンくずリストを書き込む手順に見直しができないか検討することにしてみました。
そしてここである問題点に着目しました。
何が問題かというとレイアウトとコンポーネントの構成です。
レイアウトファイルを利用してビューファイル上で対応するコードを書き込む形をとっていたのですが、見ての通りコンポーネントの呼び出し元がバラバラになっています。
呼び出し先についても後からbookメニューだけを実装した為単独表示になっていますが、他は一括で呼び出すような仕様になっており、自分でも分かりにくい仕様になっていました。
まず、これを見直し、併せてページ毎にパンくずを呼び出せるようにして、ページによっては追加で引数をもたせるように変更することにしました。
まず、構成を見直します。
タイトル名はどのページにも表示される仕様として考えていたのでレイアウトファイルに直接書き込みました。
その次にくるパンくずリストですが、これをページ毎に引数をもたせるなど設定を柔軟にする為に、ビューファイル上で記述する方式とし、そこからパンくずを参照する形にしました。
メニュー表示については、種類によってコンポーネント化することで、後から編集するときに必要なパーツのみが編集できるようにしました。
これで、ファイル構成とパンくずリストの柔軟な表示対応が解決できそうです。
新たな仕様で実装する
まず先程のbook.showページに新仕様で実装を行い、パンくずリストで本のタイトルを表示できる仕様にしました。
# ~/resouces/views/layouts/layout.blade.php
サイトタイトルやログアウト表示はそのまま記載する形に変更。
パンくずリストはレイアウト参照先で指定する形"@yield"として指定。
サイト内全体のメニューは新たにコンポーネントを作成しました。
そして、このレイアウトを利用してshowページを修正。
# ~/resouces/views/book/show.blade.php
10行目の記述、@section('breadcrumbs')を作成し、ここでパンくず設定として表示ページ情報と必要な場合は追加引数をいれることにしました。
これで表示ページ毎に設定できるのでif処理も必要なくなり、なにより分かりやすくなりました。
これで表示を確認します。
# book.show
見た目は変わっていませんが内部のコードを変更してもきっちり今まで通りの表示となりました、これで引数を個別に渡せなかった問題も解決し、テンプレート・ビュー・コンポーネント間の関係性も直すことができました。
後は、今まで作成してきたページについても仕様を合わせていくことでパンくず表示をさせて完了となりました。