survey.js アプリもろもろ改造 -breadclumbを追加 (inertia-breadcrumbs)

パッケージ概要とinstall

このパッケージはlaravelの他のbreadcrumbs生成パッケージをwrapしてinertiaで使えるようにしたものである。データー自体はbackendにてlaravelの他のパッケージで組み立てる必要がある

install

% ./vendor/bin/sail composer require robertboes/inertia-breadcrumbs
% ./vendor/bin/sail artisan vendor:publish --tag="inertia-breadcrumbs-config"

   INFO  Publishing [inertia-breadcrumbs-config] assets.

  Copying file [vendor/robertboes/inertia-breadcrumbs/config/inertia-breadcrumbs.php] to [config/inertia-breadcrumbs.php]  DONE

これはバックエンドを

のいずれからから選べるみたいなんだけど、diglactic/laravel-breadcrumbsしか使った事ないからこれで行く。

configはパッケージの説明の通り以下のようなものをセットするのだが

// diglactic/laravel-breadcrumbs
use RobertBoes\InertiaBreadcrumbs\Collectors\DiglacticBreadcrumbsCollector;

return [
    'collector' => DiglacticBreadcrumbsCollector::class,
];

defaultの設定がlaravel-breadcrumbsで組まれているのでconfigを変更する必要は無い。

diglactic/laravel-breadcrumbsの設定

% ./vendor/bin/sail composer require diglactic/laravel-breadcrumbs

このパッケージは routes/breadcrumb.php に設定情報を書く仕様になっている。以下のようにsurveyなどもroutes/web.phpの設定次第だが、自動的に注入される

<?php
use Diglactic\Breadcrumbs\Breadcrumbs;
use Diglactic\Breadcrumbs\Generator as BreadcrumbTrail;

use App\Models\Survey;
Breadcrumbs::for('surveys.index', function(BreadcrumbTrail $trail)
{
    $trail->push(__('Surveys'), route('surveys.index'));
});
Breadcrumbs::for('surveys.show', function (BreadcrumbTrail $trail, Survey $survey) {
    $trail->parent('surveys.index');
    $trail->push($survey->title, route('surveys.show', $survey));
});

これは非常に便利でノーコードでブレッドクラムデーターが生成される。

view への注入

コードをよく理解してないが、middlewareが自動的にやってるみたいなので特に必要ない。なのでlayoutだろうが個別Pageだろうがどこでも基本的に発動できると思う。ただ、個別に一々毎回書くのはダルいので通常はレイアウトに適用するだろう。

レイアウトへの適用

ってわけだから resources/js/Layouts/AuthenticatedLayout.jsx を開く

export default function Authenticated({ user, header, children }) {
    const [showingNavigationDropdown, setShowingNavigationDropdown] = useState(false);

    const { props: { flash, breadcrumbs } } = usePage();
    console.log(breadcrumbs);

このようにしてbreadcrumbsを確認してみるといい、が、とりあえず初手でbreadcrumbs自体コンポーネントにしちゃおう。これを元に戻し、headerタグのところ

            {header && (
                <header className="bg-white shadow">
                    <div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">{header}</div>
                    <Breadcrumbs />
                </header>
            )}

このように <Breadcrumbs /> を追加挿入した、ってことはモジュールがないとエラーになるので、とりあえず冒頭で

import Breadcrumbs from '@/Components/Breadcrumbs';

のように定義して resources/js/Components/Breadcrumbs.jsx を作成しよう

import React from 'react';
import { usePage } from '@inertiajs/react';

const Breadcrumbs = () => {
  const { props: { breadcrumbs } } = usePage();

  if (!breadcrumbs) {
    return null;
  }

  return (
     <></>
  );
};

export default Breadcrumbs;

エラーにならんように空の<></>を書いている。では何かしら書いていこう。小さいコードなので全文を

import React from 'react';
import { usePage } from '@inertiajs/react';

const Breadcrumbs = () => {
  const { props: { breadcrumbs } } = usePage();

  if (!breadcrumbs) {
    return null;
  }

  return (
    <div className="border-t border-gray-200 py-2">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <ol className="flex space-x-4">
                {breadcrumbs.map((breadcrumb, index) => (
                    <li key={index}>
                        <a href={breadcrumb.url} className={breadcrumb.current ? "border-b-2 border-blue-400" : ""}>
                            {breadcrumb.title}
                        </a>
                    </li>
                ))}
            </ol>
        </div>
    </div>
  );
};

export default Breadcrumbs;


このようにバッチリである。ちなみにBreadcrumb定義のないDashboardとかは表示されない。大概これが好ましい動きなので問題はないだろう。

dashboardには表示されていない

breadcrumbsのセパレーター

Surveysとデモ1とかの間にセパレーター 「 / 」を挿入するなら

import React from 'react';
import { usePage } from '@inertiajs/react';

const Breadcrumbs = () => {
  const { props: { breadcrumbs } } = usePage();

  if (!breadcrumbs) {
    return null;
  }

  return (
    <div className="border-t border-gray-200 py-2">
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <ol className="flex space-x-4">
          {breadcrumbs.map((breadcrumb, index, arr) => (
            <React.Fragment key={index}>
              <li>
                <a href={breadcrumb.url} className={breadcrumb.current ? "border-b-2 border-blue-400" : ""}>
                  {breadcrumb.title}
                </a>
              </li>
              {index < arr.length - 1 && <li className="text-gray-300">/</li>}
            </React.Fragment>
          ))}
        </ol>
      </div>
    </div>
  );
};

export default Breadcrumbs;

こんな感じになるだろうね

セパレーター 「/」 が表示された

というわけで結構大型アプリっぽくなってきた。次回はsurvey自体のCRUDも考えてみよう


この記事が気に入ったらサポートをしてみませんか?