Psst. EU dotace 85 % pro OSVČ a firmy lze nyní čerpat i na e-learning. Více informací
Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij halloweenské akce 80% výuky zdarma!
Python týden

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\[email protected]   | web        |
|        | POST      | article                | article.store   | App\Http\Controllers\[email protected]   | web        |
|        | GET|HEAD  | article/create         | article.create  | App\Http\Controllers\[email protected]  | web        |
|        | GET|HEAD  | article/{article}      | article.show    | App\Http\Controllers\[email protected]    | web        |
|        | PUT|PATCH | article/{article}      | article.update  | App\Http\Controllers\[email protected]  | web        |
|        | DELETE    | article/{article}      | article.destroy | App\Http\Controllers\[email protected] | web        |
|        | GET|HEAD  | article/{article}/edit | article.edit    | App\Http\Controllers\[email protected]    | 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í metody PUT, PATCH ani DELETE, 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 funkci route() (například route('article.index') vygeneruje http://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.

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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:

Použití PHP konzole v Laravel frameworku pro vytvoření článku

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:

Zobrazení úvodního článku v PHP frameworku Laravel

Úplný základ článků máme zprovozněný.

V příští lekci, Jednoduchý redakční systém v Laravel - Tvorba článků, se podíváme na vytváření článků a zobrazení jejich seznamu v administraci.


 

Stáhnout

Staženo 74x (46.78 MB)
Aplikace je včetně zdrojových kódů v jazyce php

 

Předchozí článek
Jednoduchý redakční systém v Laravel - Migrace
Všechny články v sekci
Laravel framework pro PHP
Článek pro vás napsal Jan Lupčík
Avatar
Jak se ti líbí článek?
6 hlasů
Autor se primárně věnuje vývoji webových stránek a aplikacích v PHP (framework Laravel) a je jedním z herních vývojářů komunitní modifikace TruckersMP.
Aktivity (16)

 

 

Komentáře
Zobrazit starší komentáře (15)

Avatar
Jan Štěch
Super redaktor
Avatar
Jan Štěch:15. června 22:02

Jaký má význam umisťovat csrf token jako <meta> do <head>? Aplikuje se tak pro všechny formuláře, co se mohou na stránce vyskytovat? Fungoval by zde zkrácený zápis @csfr stejně jako kdybychom token vložili někam do <body>?

 
Odpovědět
15. června 22:02
Avatar
Jan Lupčík
Super redaktor
Avatar
Odpovídá na Jan Štěch
Jan Lupčík:16. června 10:06

CSRF token nastavený jako meta informace je užitečný pro odesílání požadavků přes JavaScript, který si ho může takto natáhnout z hlavičky stránky :)
Direktiva @csrf by pro to nefungovala, jelikož ta vygeneruje skrytý <input /> políčko, nikoliv <meta> tag.

Odpovědět
16. června 10:06
TruckersMP vývojář
Avatar
Jan Štěch
Super redaktor
Avatar
Odpovídá na Jan Lupčík
Jan Štěch:16. června 19:41

Jasný. Díky za vysvětlení.

 
Odpovědět
16. června 19:41
Avatar
Martin Šebek:16. června 21:19

Ahoj všem,
nevíte kde může být chyba? Pracuji v ubuntu, mám rozběhnutý apache2 server a téměř vše mi funguje až do chvíle, než se chci podívat někam jinam, než na stránku http://laravel-cms. Jakmile za tuto adresu, která mi aktuálně vyhazuje správně 404 error (nastylovaný laravelem), přidám třeba právě /article/uvod, tak dostanu klasickou chybu 404, kterou generuje přímo apache. Díky

 
Odpovědět
16. června 21:19
Avatar
Jan Lupčík
Super redaktor
Avatar
Odpovídá na Martin Šebek
Jan Lupčík:17. června 17:42

Zřejmě máš špatně nastavený web server. Pokud chceš stále využívat vlastní doménu na lokálním stroji, podívej se na nastavení do lekce o instalaci projektu: https://www.itnetwork.cz/…eni-projektu
Pokud se v dané problematice neorientuješ, myslím si, že není důležité se tím aktuálně podrobněji zabývat a můžeš zvolit možnost s vestavěným serverem.

Odpovědět
17. června 17:42
TruckersMP vývojář
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Odpovídá na Jan Lupčík
Martin Šebek:17. června 21:13

Ahoj,
díky moc za odpověď. Hodně mi pomohlo, že jsem se ujistil, že mám hledat problém v nastavení apache. Problém jsem vyřešil - apache nenačítal modul mod_rewrite. Proto fungoval jen index a věci umístěné v root složce. Po spuštění už to jede v pohodě.

 
Odpovědět
17. června 21:13
Avatar
dehtak
Člen
Avatar
dehtak:28. září 11:39

Ahoj
Kdyz zadam do routru Route::resource('ar­ticle', 'ArticleContro­ller');
a pote dam prikaz artisan route:list tak to vyhodi chybovou hlasku ze ArticleController neexistuje. Pritom ho tam mam.

 
Odpovědět
28. září 11:39
Avatar
dehtak
Člen
Avatar
dehtak:3. října 0:33

tak nic no, premejslel jsem ze si koupim ten kurz ale presvedcili jste me abych to nedelal.

 
Odpovědět
3. října 0:33
Avatar
Jan Lupčík
Super redaktor
Avatar
Odpovídá na dehtak
Jan Lupčík:4. října 14:09

Ahoj, seriál ještě nebyl aktualizovaný na nejnovější verzi frameworku Laravel. Na začátku seriálu v první lekci je zmíněná verze, která byla zde použitá.
U verze 8.x se však routování řeší jinak. Jedním z řešení je dosazení odkazu na třídu a jméno metody akce v poli. U resource kontroleru stačí pouze předat odkaz na kontroler následujícím způsobem:

use App\Http\Controllers\ArticleController;

Route::resource('article', ArticleController::class);

Druhou možností je odkomentování proměnné $namespace ve třídě RouteServiceProvider. Aktuálně totiž není nastaven žádný namespace, a proto framework hledá kontrolery v kořenové složce projektu.

Též bych se chtěl omluvit za pozdější odpověď, avšak poslední týden jsem toho měl hodně a nestíhal jsem tak na nic reagovat. Na aktualizaci seriálu bych se rád podíval v následujících dvou týdnech.

Odpovědět
4. října 14:09
TruckersMP vývojář
Avatar
dehtak
Člen
Avatar
Odpovídá na Jan Lupčík
dehtak:7. října 9:35

to uz je stejne jedno pouzivam nette

 
Odpovědět
7. října 9:35
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 25. Zobrazit vše