Lekce 7 - Jednoduchý redakční systém v Laravel - Výpis článku
Minulou lekci, Jednoduchý redakční systém v Laravel - Migrace, jsme věnovali migracím a vytvořili jsme si modelovou vrstvu pro články.
Jak jsem slíbil, dnes budeme v PHP Laravel tutoriálu pokračovat v tvorbě kontroleru a zprovozníme si zobrazení článku.
Routování
Začneme nejdříve tím, že si definujeme routy pro články. Otevřeme si
soubor routes/web.php
a odstraníme výchozí routu pro hlavní
stránku, jelikož ji zatím v našem projektu nebudeme potřebovat. Místo ní
si definujeme, že námi vytvořený CRUD kontroler má zpracovávat požadavky
na články:
Route::resource('article', ArticleController::class);
Musíme si též přidat import třídy kontroleru:
use App\Http\Controllers\ArticleController;
Metodou resource()
jsme definovali routy pro všechny CRUD akce
kontroleru. Již víme, že to jsou akce pro přidání, zobrazení, editaci a
odstranění článku. O výsledku se můžeme přesvědčit příkazem
php artisan route:list
:
+--------+-----------+------------------------+-----------------+------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+------------------------+-----------------+------------------------------------------------+------------+ | | GET|HEAD | api/user | | Closure | api | | | | | | | auth:api | | | GET|HEAD | article | article.index | App\Http\Controllers\ArticleController@index | web | | | POST | article | article.store | App\Http\Controllers\ArticleController@store | web | | | GET|HEAD | article/create | article.create | App\Http\Controllers\ArticleController@create | web | | | GET|HEAD | article/{article} | article.show | App\Http\Controllers\ArticleController@show | web | | | PUT|PATCH | article/{article} | article.update | App\Http\Controllers\ArticleController@update | web | | | DELETE | article/{article} | article.destroy | App\Http\Controllers\ArticleController@destroy | web | | | GET|HEAD | article/{article}/edit | article.edit | App\Http\Controllers\ArticleController@edit | web | +--------+-----------+------------------------+-----------------+------------------------------------------------+------------+
Tabulka výše obsahuje kromě akcí s články i API akci,
která je definovaná v souboru routes/api.php
. Pro nás se
momentálně jedná o nepodstatnou routu, proto ji budeme ignorovat.
Tabulka rout nám popisuje tyto vlastnosti:
Domain
- Pro kterou doménu je daná routa určená. Pokud je hodnota prázdná, platí výchozí doména.Method
- HTTP metoda akce. Jelikož HTML formuláře nepodporují metodyPUT
,PATCH
aniDELETE
, budeme je muset trochu modifikovat. To si ale ukážeme v další lekci.URI
- URI akce (v našem případě část v URL adrese za doménou).Name
- Název akce, který se používá v kódu pro vytvoření odkazu přes helper funkciroute()
(napříkladroute('article.index')
vygenerujehttp://localhost:8000/article
).Action
- Metoda kontroleru zpracovávající danou akci.Middleware
- Výpis middlewarů, přes které požadavek projde.
Také si všimněte, že v akcích, jako je například
zobrazení, je v URI definovaný parametr {article}
. Pokud
používáme stejný název parametru jako proměnné v metodě kontroleru,
můžeme následně získat instanci článku pouze díky dependency
injection, viz dále.
Předpřipravený článek
Do naší tabulky článků si ještě doplníme úvodní článek, abychom měli s čím pracovat, než cokoliv vytvoříme.
Podle oficiálního postupu bychom si měli připravit tzv. seedery. Toho vás chci ale
prozatím ušetřit. Místo toho si ukážeme nový Artisan příkaz -
tinker
. Jedná se o PHP konzoli, přes kterou můžeme provést
jakoukoliv operaci a to i s třídami frameworku. Do konzole poté vložíme
následující kód, skrz který vytvoříme nový článek:
$article = new App\Models\Article(); $article->title = 'Úvod'; $article->url = 'uvod'; $article->description = 'Úvodní článek na webu v Laravel frameworku.'; $article->content = '<p>Vítejte na našem webu!</p><p>Tento web je postaven na <strong>jednoduchém redakčním systému v Laravel frameworku</strong>. Toto je úvodní článek, načtený z databáze.</p>'; $article->save();
Nakonec nám metoda save()
vrátí boolean
hodnotu
úspěchu:
Kontroler
Nyní se přesuneme ke kontroleru. Tam pouze upravíme akci
show()
, aby nám vracela pohled spolu s daty článku:
/** * Načti článek a předej jeho data do šablony. * * @param Article $article * @return View */ public function show(Article $article): View { return view('article.show', ['article' => $article]); }
Nezapomeneme přidat i import pro View
třídu zmíněnou v
dokumentaci:
use Illuminate\Contracts\View\View;
Pohledy
Abychom si článek mohli zobrazit, budeme k tomu potřebovat pohled.
Předtím, než však začneme nějaký vytvářet, si prosím odstraňte
vygenerovaný pohled resources/views/welcome.blade.php
- my ho
totiž potřebovat nebudeme
Šablona webu
Začneme úpravou celkového vzhledu naší aplikace. Ten bude zajišťovat
hlavní pohled base.blade.php
:
<!DOCTYPE html> <html lang="cs-CZ"> <head> <meta charset="utf-8" /> <meta name="csrf-token" content="{{ csrf_token() }}" /> <meta name="description" content="@yield('description')" /> <title>@yield('title', env('APP_NAME'))</title> <link href="{{ asset('css/app.css') }}" rel="stylesheet" /> <script src="{{ asset('js/app.js') }}"></script> </head> <body> <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm"> <h5 class="my-0 mr-md-auto font-weight-normal">{{ env('APP_NAME') }}</h5> <nav class="my-2 my-md-0 mr-md-3"> <a class="p-2 text-dark" href="#">Hlavní stránka</a> <a class="p-2 text-dark" href="#">Seznam článků</a> <a class="p-2 text-dark" href="#">Kontakt</a> </nav> </div> <div class="container"> @if ($errors->any()) <div class="alert alert-danger mb-4"> <ul class="mb-0"> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif @yield('content') <footer class="pt-4 my-md-5 border-top"> <p> Ukázkový tutoriál pro jednoduchý redakční systém v Laravel frameworku z programátorské sociální sítě <a href="http://www.itnetwork.cz" target="_blank">itnetwork.cz</a> </p> </footer> </div> @stack('scripts') </body> </html>
V lekci Jednoduchý redakční systém v Laravel - Struktura projektu jsme si do projektu naimportovali CSS framework Bootstrap. Toho jsem využil při tvorbě této šablony, kdy jsem si stáhl jeden z jejich příkladů a trochu ho upravil, aby naše stránka alespoň trochu vypadala k světu
Na pohledu výše si také všimněte těchto Blade direktiv:
@yield('hodnota')
- Očekává se předání jedné hodnoty z pohledu, který dědí tento pohled. Do hlavní šablony se nám tak např. předá titulek z šablony aktuální podstránky. Můžeme definovat i výchozí hodnotu, toho využíváme zrovna u titulku stránky. Hodnota bloku se přiřazuje Blade direktivami@section
(popř.@endsection
).@stack
- Jedná se o kolekci zásobník na rozdíl od@yield
. To se nám hodí pro přidávání skriptů, jelikož je můžeme předávat ve více pohledech pro jednu stránku. Do zásobníku se přidávají hodnoty pomocí Blade direktiv@push
(popř.@endpush
)
Zobrazení článku
V pohledu pro zobrazení článku, který si vytvoříme ve složce
resources/views/article/
s názvem show.blade.php
,
budeme dědit naší hlavní šablonu a následně využijeme bloků, které
jsme si definovali:
@extends('base') @section('title', $article->title) @section('description', $article->description) @section('content') <h1>{{ $article->title }}</h1> {!! $article->content !!} @endsection
Jelikož framework nás chrání před XSS
útokem pomocí escapování vypsaného textu, musíme pro výpis obsahu
článku použít {!! !!}
namísto {{ }}
. Obsahuje
totiž i HTML kód.
Pokud si však nyní zkusíme zobrazit náš úvodní článek přes stránku
webu /article/uvod
, dostaneme chybu 404 i přes to, že vše
vypadá funkčně. Kde je tedy chyba?
Definování atributu pro parametr routy
Laravel ve výchozím nastavení získává data z databáze pomocí jejich
ID. Pro zobrazení úvodního článku bychom museli použít adresu
/article/1
. Jedná se však o nechtěné chování aplikace,
jelikož každý náš článek má svojí unikátní slovní URL a toho chceme
využít.
Aby se aplikovala hodnota url
článku v routách
používající model Article
(parametr {article}
),
budeme muset v našem modelu přepsat obsah metody
getRouteKeyName()
, která se dědí z třídy
Model
:
/** * Vrať název atributu, podle kterého se získává článek z parametru routy. * * @return string */ public function getRouteKeyName(): string { return 'url'; }
Nyní při navštívení stránky /article/uvod
uvidíme náš
úvodní článek:
Úplný základ článků máme zprovozněný.
V následujícím kvízu, Kvíz - Struktura projektu, migrace a šablony v Laravel, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 209x (46.78 MB)
Aplikace je včetně zdrojových kódů v jazyce PHP