8. Routingとリンク
Laravelのリンク
相対パスの問題
システム開発でURLリンクする時は、相対パスが一般的ですが、プログラムで相対リンクをするには現在のURLから見て、どこのURLにアクセスするかが重要です。
「/search」から「/item/1」
例えば、現在のURLが「http://localhost:8000/search」から、「http://localhost:8000/item/1」へのアクセスリンクは以下のようになります。
<a href="./item/1">詳細</a>
「/item/1」から「/item/edit/1」
次に、現在のURLが「http://localhost:8000/item/1」から、「http://localhost:8000/item/edit/1」へのアクセスリンクは以下のようになります。このように、現在のパスを意識しながらプログラミングするのはとても非効率です。
<a href="../edit/1">編集</a>
ルート名
LaravelのRouting設定では、ルート名というラベルのようなものを設定でき、現在のパスを意識することなくリンクできます。
nameメソッド
「Routing」クラスの「name」メソッドでルート名を設定できます。
Route::get(パス, ルーティング)->name(ルート名);
routeヘルパー
routeヘルパーは、設定したルート名でURLリンクを自動生成してくれるメソッドです。
route(ルート名);
aリンク
aリンクでリンクする場合、「href」プロパティに「route」を指定します。
<a href="{{ route(ルート名) }}">リンク</a>
routeのGETパラメータ
リンクにGETパラメータをつけることもできます。パラメータは、route() の第2引数に連想配列で指定するのが基本です。
<a href="{{ route(ルート名, [キー1 => 値1, キー2 => 値2, ...]) }}">リンク</a>
idパラメータ
リンクにGETパラメータをつけることもできます。パラメータは、route() の第2引数に連想配列で指定するのが基本です。
<a href="{{ route(ルート名, ID) }}">リンク</a>
Routeでリンク
ファイル構成
/
├── about.blade.php
├── components/
│ ├── head.blade.php
│ └── nav.blade.php
├── item
│ ├── edit.blade.php
│ └── show.blade.php
├── layouts
│ └── app.blade.php
├── search.blade.php
└── welcome.blade.php
トップページリンク
ナビゲーションコンポーネント作成
ナビゲーション用のコンポーネント「components/nav.blade.php」を作成して、ページリンクします。ナビゲーションの構成はBootstrap5を利用します。
nav.blade.php
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Home</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link" href="#">About</a>
<a class="nav-link" href="#">Search</a>
</div>
</div>
</div>
</nav>
ルーティング設定
トップページのルーティング「 / 」に、ルート名「 / 」を設定します。
web.php
Route::get('/', function () {
return view('welcome');
})->name('/');
リンク設定
ナビゲーションコンポーネントの「Home」リンクをルート名「 / 」で設定します。
nav.blade.php
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="{{ route('/') }}">Home</a>
...
リンク確認
「Home」リンクをクリックしてトップページにリンクするか確認してみましょう。
その他ページリンク
「About」ページ、「Search」ページにリンクしてみましょう。
ルーティング設定
ルート名はできるだけ、URLパターンとあわせつつ意味を持つキーワードにすると管理しやすくなります。また、パラメーター部分は不特定な値なのでルート名に追加はしません。
web.php
Route::get('/about', [HomeController::class, 'about'])->name('about');
Route::get('/search', [HomeController::class, 'search'])->name('search');
Route::get('/item/{id}', [ItemController::class, 'show'])->name('item.show');
Route::get('/item/edit/{id}', [ItemController::class, 'edit'])->name('item.edit');
ルーティング一覧
ページ | URL | ルート名 |
---|---|---|
トップ | / | / |
About | /about | about |
検索 | /search | search |
商品詳細 | /item/{id} | item.show |
商品編集 | /item/edit/{id} | item.edit |
リンク作成
ナビゲーションコンポーネントに、「About」「検索」ページのリンクを追加します。
nav.blade.php
<a class="nav-link" href="{{ route('about') }}">About</a>
<a class="nav-link" href="{{ route('search') }}">Search</a>
フォーム
FormタグのactionでURLを指定し、検索をしてみましょう。
search.blade.php
<form action="{{ route('search') }}" method="get">
<input class="form-control" type="text" name="keyword">
<button class="btn btn-primary">検索</button>
</form>
パラメータつきリンク
編集リンク
ルーティング設定
「ItemController」クラスの「show」メソッドで、「id」パラメータをBladeに受け渡します。
ItemController.php
public function show(int $id)
{
$items = [
1 => "コーヒー",
2 => "紅茶",
3 => "ほうじ茶",
];
$item = "";
if ($id > 0 && array_key_exists($id, $items)) $item = $items[$id];
$data = ['item' => $item, 'id' => $id];
return view('item.show', $data);
}
リンク追加
「item/show.blade.php」に編集リンクを追加します。
item/show.blade.php
パラメータ
@extends('layouts.app')
@section('content')
<h2 class="mt-2">商品名</h2>
<p>{{ $item }}</p>
<div>
<a href="{{ route('item.edit', $id) }}">編集</a>
</div>
@endsection
編集画面
パラメータ取得
「ItemController」クラスの「edit」メソッドで、「id」パラメータをBladeに受け渡します。
public function edit(int $id)
{
$data = ['id' => $id];
return view('item.edit', $data);
}
パラメータ確認
「item/show.blade.php」でID表示と戻るリンクを追加します。
item/edit.blade.php
@extends('layouts.app')
@section('content')
<h2 class="mt-2">商品編集</h2>
<p>{{ $id }}</p>
<div>
<a href="{{ route('item.show', $id) }}">戻る</a>
</div>
@endsection
動作確認してみましょう。