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とかは表示されない。大概これが好ましい動きなので問題はないだろう。
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も考えてみよう