Pouze tento týden sleva až 80 % na e-learning týkající se Javy
Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij slevové akce 50% výuky zdarma!
Java 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.


 

Měla 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 110x (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í v PHP (framework Laravel) a je jedním z herních vývojářů komunitní modifikace TruckersMP.
Aktivity (17)

 

 

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

Avatar
Jan Lupčík
Super redaktor
Avatar
Jan Lupčík:17.6.2020 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.6.2020 17:42
TruckersMP vývojář
Avatar
Odpovídá na Jan Lupčík
Martin Šebek:17.6.2020 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.6.2020 21:13
Avatar
dehtak
Člen
Avatar
dehtak:28.9.2020 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.9.2020 11:39
Avatar
dehtak
Člen
Avatar
dehtak:3.10.2020 0:33

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

 
Odpovědět
3.10.2020 0:33
Avatar
Jan Lupčík
Super redaktor
Avatar
Odpovídá na dehtak
Jan Lupčík:4.10.2020 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.10.2020 14:09
TruckersMP vývojář
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
dehtak
Člen
Avatar
Odpovídá na Jan Lupčík
dehtak:7.10.2020 9:35

to uz je stejne jedno pouzivam nette

 
Odpovědět
7.10.2020 9:35
Avatar
Matúš Jumperis:25. března 11:44

Nazdar, prosim Vas viete mi poradit preco mi to pod nginx nefunguje a podn apache ano? Pri nginx mi funguje len homepage pri apache v pohode slape vsteko. Na lokal server pouzivam svoje NASko Synology. Dakujem za kazdu radu.

P.S.: nepodarilo sa mi nainstalovat ten boostrap :-D ale tomu sa este povenujem

 
Odpovědět
25. března 11:44
Avatar
Matúš Jumperis:7. dubna 16:06

Ahoj, mam teraz uplne iny problem. Tinker:
>>> $inOrder = new App\InOrder();
PHP Error: Class 'App\InOrder' not found in Psy Shell code on line 1

vobc tomu nechapem. Skusal aj google ale nic mi nepomaha co tam pisu

 
Odpovědět
7. dubna 16:06
Avatar
Jan Lupčík
Super redaktor
Avatar
Odpovídá na Matúš Jumperis
Jan Lupčík:7. dubna 22:44

Ahoj, ujisti se, že existuje model InOrder. Pokud ano, ve verzi 8.0 a výš jsou modely umístěné ve složce app/Models/. Tudíž celý příkaz by měl vypadat následovně:

$inOrder = new App\Models\InOrder();
Odpovědět
7. dubna 22:44
TruckersMP vývojář
Avatar
Odpovídá na Jan Lupčík
Matúš Jumperis:9. dubna 10:13

ano dik uz mi to funguje - cital som aj docs :D

 
Odpovědět
9. dubna 10:13
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 29. Zobrazit vše