Laravel-Breadcrumbが便利だった

今とあるプロジェクトで現行サイトをLaravelに載せ替える作業をしているのですが、そのさい、べた書きで実装されていたパン屑をどうやって実装しようかとPackagistを漁っていたところ、laravel-breadcrumbsという超便利ライブラリがあったので、早速使ってみました。

作業環境

  • Laravel: 5.5
  • PHP: 7.1.5
  • laravel-breadcrumbs: 4.2.0

Laravelインストール

以下でLaravelプロジェクトを作成します。

$ composer create-project --prefer-dist laravel/laravel breadcrumbs_test

laravel-breadcrumbsインストール

以下でlaravel-breadcrumbsをインストールします。

$ cd breadcrumbs_test
$ composer require davejamesmiller/laravel-breadcrumbs

config/breadcrumbs.phpを作成

以下でbreadcrumbsの設定ファイルを作成します。

$ php artisan vendor:publish --provider='DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider'

routes/breadcrumbs.phpを作成

上で作ったconfig/breadcrumbs.phpを見ると分かるのですが、パン屑設定を記述するファイルはroutes/breadcrumbs.php というファイルになります。

なので、routes/ にファイルを作成します。

$ touch routes/breadcrumbs.php

パン屑の設定を書いていく

作成したroutes/breadcrumbs.phpにパン屑の設定を書いていきます。

せっかくなので、公式に書いてあったものの似たような感じで作ってみます。

<?php

// Home
Breadcrumbs::register('home', function ($breadcrumbs) {
    $breadcrumbs->push('Home', route('home'));
});

// Home > About
Breadcrumbs::register('about', function ($breadcrumbs) {
    $breadcrumbs->parent('home');
    $breadcrumbs->push('About', route('about'));
});

// Home > Blog
Breadcrumbs::register('blog', function ($breadcrumbs) {
    $breadcrumbs->parent('home');
    $breadcrumbs->push('Blog', route('blog'));
});

// Home > Blog > [Category]
Breadcrumbs::register('category', function ($breadcrumbs, $category) {
    $breadcrumbs->parent('blog');
    $breadcrumbs->push($category->title, route('category', $category->name));
});

// Home > Blog > [Category] > [Post]
Breadcrumbs::register('post', function ($breadcrumbs, $post) {
    $breadcrumbs->parent('category', $post->category);
    $breadcrumbs->push($post->title, route('post', [$post->category->name, $post->id]));
});

パン屑に対応するrouteを書いていく

せっかくパン屑の設定を書いても、laravelのプロジェクトを作ったばかりの場合は、対応するrouteが存在しません。

なので、ルーティングファイルを編集します。

今回はパン屑設定に対応するルーティングを設定しました。

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('home');
})->name('home');

Route::get('/about', function () {
    return view('about');
})->name('about');

Route::get('/blog', function () {
    return view('blog');
})->name('blog');

Route::get('/blog/{category_name}', function ($category_name) {
    $category        = new StdClass;
    $category->title = 'カテゴリ1';
    $category->name  = $category_name;
    return view('category', ['category' => $category]);
})->where('category_name', '[A-Za-z]+')->name('category');

Route::get('/blog/{category_name}/{id}', function ($category_name, $id) {
    $category        = new StdClass;
    $category->id    = 1;
    $category->title = 'カテゴリ1';
    $category->name  = $category_name;

    $post            = new StdClass;
    $post->id        = $id;
    $post->title     = "ポスト{$id}";
    $post->category  = $category;
    return view('post', ['post' => $post]);
})->where('category_name', '[A-Za-z]+')->where('id', '[0-9]+')->name('post');

カテゴリやポストは本来はDBから取得するものですが、今回はテストなのでべた書きしています。

viewファイル作成

ルーティングに対応するbladeファイルを作成してください。

$ touch resources/views/home.blade.php
$ touch resources/views/about.blade.php
$ touch resources/views/blog.blade.php
$ touch resources/views/category.blade.php
$ touch resources/views/post.blade.php

各ファイルは以下みたいな感じで書いておきます。

h1やtitle部分は脳内補完してください。

<!DOCTYPE html>
<html>
<head>
    <title>home</title>
</head>
<body>
    <h1>Home</h1>
</body>
</html>

テンプレートにパン屑を表示する

早速表示してみます。

例えばaboutページであれば、h1の下に以下を記述してください。

{{ Breadcrumbs::render('about') }}

早速確認してみます。

f:id:kojirooooocks:20180111004816p:plain

パン屑表示されてますね!!

引数も渡せます。categoryページの場合は、以下のように記述します。

{{ Breadcrumbs::render('category', $category) }}

f:id:kojirooooocks:20180111004821p:plain

表示されてます!

テンプレートの切り替え

スタイルを効かせたい場合など当然あると思います。

その場合は、設定ファイルでパン屑が表示されるテンプレートを変更することが出来ます。

config/breadcrumbs.php の以下の項目を変更します。

'view' => 'breadcrumbs::bootstrap4',
    ↓
'view' => 'elements/breadcrumbs'

上のように変更すると、laravel-breadcrumbsは resources/views/elements/breadcrumbs.blade.phpを見るようになります。

新たにファイルを作り、以下のように記述します。

@if (count($breadcrumbs))
    <ul class="breadcrumb">
        @foreach ($breadcrumbs as $breadcrumb)
            @if ($breadcrumb->url && !$loop->last)
                <li class="breadcrumb-item"><a href="{{ $breadcrumb->url }}">{{ $breadcrumb->title }}</a></li>
            @else
                <li class="breadcrumb-item active">{{ $breadcrumb->title }}</li>
            @endif
        @endforeach
    </ul>
@endif

f:id:kojirooooocks:20180111004827p:plain

ulに変更したとことで、ナンバリングがなくなっています。

新しいテンプレートが使われていることがわかると思います。

JSON-LDでのパンくずリスト対応

ここまでやったのでschema.orgパンくずリストも一緒に実装してみます。

上で作った、新たなテンプレート(elements/breadcrumbs.blade.php)に記述する感じで実装します。

@if (count($breadcrumbs))
    <ul class="breadcrumb">
        @foreach ($breadcrumbs as $breadcrumb)
            @if ($breadcrumb->url && !$loop->last)
                <li class="breadcrumb-item"><a href="{{ $breadcrumb->url }}">{{ $breadcrumb->title }}</a></li>
            @else
                <li class="breadcrumb-item active">{{ $breadcrumb->title }}</li>
            @endif
        @endforeach
    </ul>
    <script type="application/ld+json">
    {
      "@context": "http://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement":
      [
        @foreach ($breadcrumbs as $k => $breadcrumb)
        {
          "@type": "ListItem",
          "position": {{ $k + 1 }},
          "item":
          {
            "@id": "{{ $breadcrumb->url }}",
            "name": "{{ $breadcrumb->title }}"
          }
        }
        @if (!$loop->last)
        ,
        @endif
        @endforeach
      ]
    }
    </script>
@endif

f:id:kojirooooocks:20180111004830p:plain

問題なく表示されてますね。

感想

laravelはいろんなライブラリがあって面白いですね。

こらからどんどん移植をしていくうちに、他にもいいライブラリをみつけたら、また紹介したいと思います。