11. diel - Jednoduchý redakčný systém v Laravel - Práca s dátumom
V minulej lekcii, Jednoduchý redakčný systém v Laravel - Laravel Mix , sme sa venovali najmä front-end časti nášho projektu. S tou sa dnes rozlúčime. Vysvetlíme si prácu s dátumom a následne sa presunieme opäť na vyvíjanie back-endu. Vytvoríme si totiž sľubovanú hlavnú stránku.
Práca s dátumom
Určite ste si už všimli, že dáta v našej aplikácii sa vypisujú vo
východiskovej podobe z databázy a to vo formáte Ymd H:i:s
.
Jedná sa však o niečo, čo naozaj mať nechceme, pretože to nie je zrovna
intuitívne pre používateľov. Navyše sa dáta ukladajú v GMT, aj keď je
celá naša aplikácia v slovenčine (až na výnimky, tj. Chybové hlášky
knižníc či frameworku a URL adresy). Časové pásmo by teda tiež malo byť
najlepšie lokalizované.
V čistom PHP by sme vždy museli volať funkciu date()
a sami
nastavovať formát času. V lepšom prípade by sme na to použili knižnicu. O
to sa však už postaral niekto za nás, pretože Laravel v predvolenom
nastavení používa knižnicu Carbon. Táto knižnica obsahuje
mnoho užitočných metód a aj preklady pre nespočetné množstvo jazykov. Ak
vás zaujíma viac, zavítajte na oficiálne stránky knižnice Carbon.
Nastavenia lokalizácia aplikácie
Carbon si získava hodnoty pre nastavenie z konfiguračného súboru
programu, ktorý je, ako už zrejme tušíte, v priečinku config/
,
presnejšie v súbore app.php
. Nás v tomto prípade zaujímajú
tieto hodnoty:
timezone
- Definuje časové pásmo pre našu aplikáciu. Predvolená hodnota jeUTC
. Pre strednú Európu by sme pokojne mohli použiťCET
(C entral E uropean T ime), tu však bohužiaľ nastáva problém s letným časom. Preto využijeme možnosti definovať kontinent s mestom, v našom prípadeEurope/Prague
, čo vyrieši tento problém za nás.locale
- Skratka pre jazyk, ktorý má naše aplikácie používať. Predvolená hodnota jeen
. My si však nastavímecs
, čím zmeníme nielen konfiguráciu jazyka pre samotný framework, ale aj pre danú knižnicu. Ak nie je možné nájsť frázu pre daný jazyk, použije sa predvolené. Záložný jazyk je definovaný konfiguračné hodnotoufallback_locale
. Táto hodnota je ako predvolené nastavená na angličtinu (en
).
Zmeny v súbore vyzerajú takto:
/* |-------------------------------------------------------------------------- | Application Timezone |-------------------------------------------------------------------------- | | Here you may specify the default timezone for your application, which | will be used by the PHP date and date-time functions. We have gone | ahead and set this to a sensible default for you out of the box. | */ 'timezone' => 'Europe/Prague', /* |-------------------------------------------------------------------------- | Application Locale Configuration |-------------------------------------------------------------------------- | | The application locale determines the default locale that will be used | by the translation service provider. You are free to set this value | to any of the locales which will be supported by the application. | */ 'locale' => 'cs',
Teraz sa už zmeny aplikujú na našej aplikácii. Ak si totiž skúsime editovať nejaký článok, uvidíme, že dátum poslednej zmeny sedí aj s lokálnym časom. Čo ale zatiaľ nesedí, je výpis dáta, pretože stále využíva predvolený formát. Poďme to napraviť.
Ak sa tieto zmeny neprejavili na vašej aplikácii, spustite
príkaz php artisan config:cache
v koreňovom priečinku projektu.
Konfiguračný hodnoty sa totiž ukladajú do vyrovnávacej pamäte a pomocou
tohto príkazu sa naplní novými hodnotami.
Výpis dát v pohľadoch
Začneme najskôr pohľadom pre článok, ktorý nájdeme v zložke
resources/views/article/
s názvom show.blade.php
. Tam
vypisujeme iba jeden dátum a to posledné zmenu daného záznamu v pätičke
článku. Vytvoríme si teda nový objekt triedy knižnice Carbon
a
následne vypíšeme časový rozdiel oproti poslednej zmene pomocou
lokalizovanej metódy diffForHumans()
:
@php $updatedAt = new Carbon\Carbon($article->updated_at); @endphp <footer> <p class="small text-secondary border-top pt-2 mt-4"> <i class="fa fa-calendar"></i> {{ $updatedAt->diffForHumans() }} </p> </footer>
Mimo klasické PHP tagy možno použiť Blade direktívu
@php ... @endphp
. Nie je medzi nimi žiadny rozdiel, iba (a snáď
mi túto pripomienku ostatní vývojári odpustí) ide o skrášlenie kódu
daného pohľadu.
Ak si teraz zobrazíme nejaký článok, uvidíme v pätičke článku výstup podobný tomuto:
Naša aplikácia opäť vyzerá trochu profesionálnejšie. Bohužiaľ naše riešenia už na tom nie je tak dobre. Daný postup je samozrejme bezchybný a funguje presne tak, ako by sme si priali. Predstavte si však, že by ste na jednej stránke mali napríklad 10 rôznych dát a pre všetky tieto dáta ste museli vždy vytvoriť nový objekt triedy knižnice Carbon. To by bolo trochu zdĺhavé a zároveň by sa kód stal neprehľadným.
Dáta záznamu ako inštancia knižnice Carbon
Ako ste si už určite všimli v predchádzajúcich lekciách, vždy sa dá
všetko zjednodušiť. To isté platí pre dáta záznamov, ktoré sú v
inštancii modeli vždy reprezentovaná ako objekt triedy Carbon
dedič PHP triedu DateTime
. My sa teda vytváraním nového objektu
zaťažovať nemusíme a ihneď môžeme pristupovať k metódam tejto
knižnice.
Ďalšie dátumy, ktoré majú fungovať na rovnakom princípe v
danom modeli, sa definujú v premennej $dates
.
Atribúty created_at
a updated_at
už sú automaticky
zahrnuté. Ak by ste teda chceli definovať ďalšie dáta, je zbytočné ich
znovu špecifikovať.
Časť pohľade s pätičkou si teda môžeme upraviť do nasledujúcej podoby:
<footer> <p class="small text-secondary border-top pt-2 mt-4"> <i class="fa fa-calendar"></i> {{ $article->updated_at->diffForHumans() }} </p> </footer>
Lokalizované dátum
Pravdepodobne sa zhodneme na tom, že v článku by sa užívateľovi malo
zobrazovať presný dátum. Na to môžeme použiť jednu z mnohých dostupných
metód a to isoFormat()
, keďže jedna z výhod je lokalizovaný
výstup (čo neplatí napríklad pre metódu format()
):
<footer> <p class="small text-secondary border-top pt-2 mt-4"> <i class="fa fa-calendar"></i> {{ $article->updated_at->isoFormat('LLL') }} </p> </footer>
Výstup môže vyzerať podobne tomuto:
Viac možností pre lokalizovaný výstup možno nájsť v oficiálnej dokumentácii knižnice Carbon.
Následne si tiež upravíme zobrazenie dát v administrácii článkov, aby
sme tieto výstupy mali zjednotenej. Otvoríme si teda pohľad
resources/views/article/index.blade.php
a upravíme nasledujúce
časť tabuľky:
<td>{{ $article->description }}</td> <td>{{ $article->created_at->isoFormat('LLL') }}</td> <td>{{ $article->updated_at->isoFormat('LLL') }}</td> <td>
Hlavná stránka
Zlepšovanie našej aplikácie zakončíme vytvorením hlavnej stránky (homepage) pre náš web. Nám zatiaľ postačí, keď bude obsahovať len výpis najnovších článkov.
Začneme najskôr od kontroleru.
Kontrolér o jedinej akcii
Ako sme si už povedali, kontrolér pre zobrazenie hlavnej stránky bude
definovať iba jednu akciu. Pozastavíme sa však u názvu metódy pre danú
akciu kontroleru. Ako by sme ju totiž mali pomenovať? Názvy ako
show()
alebo index()
sa veľmi nehodí, keďže nejde
o CRUD kontrolér pracujúci s jednou inštanciou modelu (na hlavnej stránke
nemusíme zobrazovať iba výpis článkov a navyše už jeden CRUD kontrolér
pre daný model máme). Možno vás ešte napadne niečo ako
getHome()
, ani to však nie je ten najlepší prístup.
Pre takéto prípady Laravel definuje tzv. Kontrolery jedinej
akcie ( Single
Action Controllers). Tieto kontrolery sa vyznačujú tým, že definujú iba
jedinú metódu __invoke()
, ktorá môže prijímať parametre
rovnako ako akákoľvek iná akcia.
Poďme si teraz taký kontrolér vytvoriť cez Artisan príkaz
make:controller
. Predtým sa však pozrieme na jeho možnosti:
php artisan help make:controller
Možnosť --model[=MODEL]
už poznáme z predchádzajúcich
lekcií. Nás však tentoraz bude zaujímať možnosť --invokable
,
ktorá vytvorí kontrolér jedinej akcie. Ten si pomenujeme ako
WelcomeController
:
php artisan make:controller --invokable WelcomeController
Novo vygenerovaný kontrolér nájdeme v zložke s kontrolery
app/Http/Controllers/
a obsahuje len spomínanú metódu
__invoke()
:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\Response; class WelcomeController extends Controller { /** * Handle the incoming request. * * @param Request $request * @return Response */ public function __invoke(Request $request) { // } }
My si cez túto metódu zobrazíme hlavnú stránku. Bude nám teda stačiť,
aby vracala pohľad, ktorému odovzdáme kolekciu najnovších článkov pomocou
Eloquent metódy latest()
:
/** * Zobraz hlavní stránku webu. * * @param Request $request * @return Response */ public function __invoke(Request $request) { return view('welcome', ['articles' => Article::latest()->get()]); }
Nesmieme zabudnúť importovať náš model:
use App\Article;
Routovanie
Routovanie kontrolerov jediné akcia je trochu rozdielne - nedefinujeme
totiž metódu daného kontroleru, ale iba jeho názov. Pre zobrazenie hlavnej
stránky využívajúce tento kontrolér si musíme do routovacího súboru
routes/web.php
pridať nasledujúce volanie metódy
get()
routovacie triedy Route
:
Route::get('', 'WelcomeController');
Ako si môžete všimnúť, ako URI akciu definujeme len prázdny reťazec.
Tým dosiahneme to, že pri zobrazení webu bez akýchkoľvek iných parametrov
v URL adrese sa vykoná metóda __invoke()
kontroleru pre hlavnú
stránku WelcomeController
.
Nesmieme tiež zabudnúť odkázať na hlavnú stránku v menu našej hlavnej
šablóny resources/views/base.blade.php
. Na to použijeme helper
funkciu url()
:
<nav class="my-2 my-md-0 mr-md-3"> <a class="p-2 text-dark" href="{{ url('') }}">Hlavní stránka</a> <a class="p-2 text-dark" href="{{ route('article.index') }}">Seznam článků</a> <a class="p-2 text-dark" href="#">Kontakt</a> </nav>
Pohľad
Hlavnú stránku zakončíme vytvorením pohľade s názvom
welcome.blade.php
v priečinku s pohľadmi
resources/views/
. Momentálne nebude mať na starosti nič iné ako
obyčajné vypísanie všetkých článkov z našej databázy, ktoré sme
odovzdali v metóde kontroleru akcie:
@extends('base') @section('title', 'Jednoduchý redakční systém v Laravel') @section('description', 'Ukázkový tutoriál pro jednoduchý redakční systém v Laravel frameworku z programátorské sociální sítě itnetwork.cz') @section('content') <h1 class="text-center mb-4">Jednoduchý redakční systém v Laravel</h1> @forelse ($articles as $article) <article class="article mb-5"> <header> <h2> <a href="{{ route('article.show', ['article' => $article]) }}">{{ $article->title }}</a> </h2> </header> <p class="article-content mb-1">{{ $article->description }}</p> <footer> <p class="small text-secondary"> <i class="fa fa-calendar"></i> Naposledy upraveno {{ $article->updated_at->diffForHumans() }} </p> </footer> </article> @empty <p>Zatím se zde nenachází žádné články.</p> @endforelse @endsection
Ak si teraz otvoríme hlavnú stránku cez odkaz v menu alebo pri zadaní URL
adresy našej aplikácie (v prípade zabudovaného web servera
http://127.0.0.1:8000/
), uvidíme výpis najnovších článkov
spolu s odkázaním na ne a ich dátumom posledné úpravy:
Týmto sme dokončili vylepšovanie nášho projektu. Ak sa vám niečo nepodarilo, môžete si stiahnuť projekt z priloženého archívu nižšie alebo sa opýtať v komentároch pod článkom.
V budúcej lekcii, Jednoduchý redakčný systém v Laravel - Emailová správa , budeme opäť vytvárať novú stránku, presnejšie kontaktný formulár. Pozrieme sa tak, ako možno pracovať s emailami v Laravel frameworku.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 92x (52.33 MB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP