PHPPamokos.lt


3. Views ir Blade šablonai

Jau matėte praeitoje pamokoje, kas yra Views ir kaip jie veikia. Laikas pažvelgti giliau ir susipažinti su Blade šablonais - jie padeda patogiau suderinti PHP ir HTML kodą Views failuose.

Pradėsiu nuo to, kad priminsiu, jog View failas gali būti vien tik HTML kodas su reikalingomis
<?php echo $var;?>
komandomis. Bet neišvengiamai su laiku atsiranda poreikis panaudoti kokį IF sakinį ar FOREACH ciklą, ir maišyti PHP kalbą su HTML nelabai patogu. Būtent tam Laravel turi savo vidinę "kalbą" pavadinimu Blade.

Pavyzdys - ta pati struktūra su PHP ir su Blade.

PHP:
<?php foreach ($exams as $exam): ?>
  <h1>Laba diena</h1>
<?php endforeach; ?>
Blade:
@foreach ($exams as $exam)
  <h1>Laba diena</h1>
@endforeach
Blade atrodo šiek tiek trumpiau, ar ne? Bet net ne tame yra šios kalbos didžiausi privalumai, juos pamatysite kiek žemiau.

Svarbus dalykas - kad galėtumėte panaudoti Blade savo šablonuose, turite View failus vadinti taip, kad pabaigoje būtų ".blade.php":
  • users.blade.php
  • shops.blade.php
  • books_edit.blade.php
Taigi, kokius patogumus siūlo Blade?
 

Kintamųjų išvedimas

Kaip mes PHP kalboje išvedame kintamuosius į naršyklę? Su funkcijomis echo arba print, ar ne? Taip pat galimas sutrumpinimas <?=$value;?>. Blade gi siūlo kintamuosius tiesiog patalpinti tarp figūrinių skliaustų.

PHP:
<?php echo $value; ?>
<?php print $value; ?>
<?=$value;?>
Blade:
{{ $value }}
Taip, tiesiog tarp figūrinių skliaustų. Tarpas tarp jų nebūtinas - jį mėgstu palikti tiesiog skaitymo patogumui ateityje. Bet veikia ir taip:
{{$value}}
 
Taip pat įdomus dalykas - galima skliaustų viduje rašyti ir PHP funkcijas (kabliataškis po jų nereikalingas):
{{ date('Y-m-d') }}
 
Turėkite omenyje, kad kintamieji tarp skliaustų automatiškai praeina per PHP funkciją htmlentities(), kas reiškia kad jei kintamuosiuose bus HTML ar JavaScript kodo - jis nebus automatiškai įvykdomas. Tai yra apsauga nuo XSS atakų. PHP:
<?php $var = '<script>alert("Hello!");</script>'; ?>
<?php echo $var; ?>
Šiuo atveju bus įvykdytas JavaScript kodas, kuris potencialiai gali būti saugumo spraga. Bet Laravel atveju, į naršyklę bus išvesta:
<script>alert("Hello!");</script>
Bet jei jums reikia, kad HTML kodas būtų vykdomas ir htmlentities() funkcija nebūtų vykdoma, reikia naudoti kitokio tipo skliaustus:
{!! $value !!}
Apie tokio varianto pritaikymą kalbėsime kiek vėliau kai prieisime prie formų valdymo.
 
Dar vienas įdomus Laravel patogumas - išvesti kažkokią reikšmę, jeigu kintamasis nėra apibrėžtas:

PHP:
<?php if (isset($var)): echo $var; else: echo 'Laba diena'; endif; ?>
Arba trumpiau:
<?php echo (isset($var)) ? $var : 'Laba diena'; ?>
Laravel:
{{ $var or 'Laba diena' }}
Negi ne trumpiau?
 

IF sakiniai

Blade sistema turi ir savo būdą rašyti IF-ELSE struktūras. Mano asmenine nuomone, ji nesuteikia didelio patogumo prieš paprastą PHP sintaksę, bet gera praktika būtų tokia - jeigu jau naudojame Blade šablonus, tai geriau PHP kodo ten nenaudojame.

PHP:
if ($var > 10) {
  echo '10+';
} elseif ($var > 5) {
  echo '5+';
} else {
  echo '5-';
}
Laravel:
@if ($var > 10)
  10+
@elseif ($var > 5)
  5+
@else
  5-
@endif
 

Ciklai: FOR ir FOREACH

Čia labai panašiai į ką tik paminėtus IF-ELSE sakinius - sintaksė labai panaši ir sutaupo vos keletą simbolių rašymo, bet atrodo kiek tvarkingiau.

Ciklas FOR - PHP:
for ($i = 0; $i < 10; $i++) {
  echo 'Numeris ' . $i;
}
Ciklas FOR - Laravel:
@for ($i = 0; $i < 10; $i++)
  Numeris {{ $i }}
@endfor
 
Ciklas FOREACH - PHP:
foreach ($rows as $row) {
  echo 'Numeris ' . $row['number'];
}
Ciklas FOREACH - Laravel:
@foreach ($rows as $row)
  Numeris {{ $row['number'] }}
@endforeach
 

Laravel Ciklas: FORELSE

Taip pat yra dar vienas Laravel Blade triukas: patikrinimas, ar masyvas nėra tuščias, priešingu atveju kažkokio teksto įvedimas. Kaip mes tai rašytume dažniausiai:
@if ($cities->count() > 0)
  @foreach ($cities as $city)
    {{ $city->title }}
  @endforeach
@else
  No cities.
@endif
Blade siūlo šiek tiek sutrumpinti:
@forelse ($cities as $city)
  {{ $city->title }}
@empty
  No cities.
@endforelse
Negi ne gražiau?
 

Pagalbinės Laravel funkcijos Blade šablonuose

Kadangi Blade šablonuose tarp figūrinių skliaustų {{ ... }} galima naudoti ir PHP funkcijas, galima naudoti ir Laravel funkcijas, taip vadinamus Helpers. Jų yra labai nemažai, tad čia paminėsiu tik tas, kurių mums gali prireikti nuo pat pradžių - atskirai dar jas pakartosime toliau kurso eigoje.

Funkcija URL:
<a href="{{ url('/') }}">Pagrindinis</a>
<a href="{{ url('apie') }}">Apie mus</a>
<a href="{{ url('katalogas/audi') }}">Audi</a>
Ši funkcija reikalinga tam, kad sudarytų teisingą nuorodą, skaičiuojant nuo pagrindinio katalogo, net jei jūsų projektas fiziškai yra kažkokio kito katalogo viduje - url() sudarys nuorodą nuo jūsų /public katalogo.
 
CSS ir JS užkrovimas:
<link rel="stylesheet" href="{{ asset('css/style.css') }}">
<script src="{{ asset('js/script.js') }}"></script>
Tad šiuo atveju jūsų CSS failai turėtų būti /public/css kataloge, o JS failai - atitinkamai /public/js kataloge.
 

Blade šablonų struktūra projekte

Be abejo, rimtesniame projekte Views katalogo struktūra turėtų susidaryti iš daugybės failų. Turi būti bendras "header", "footer", gali būti "sidebar" ir kiti atskirai kraunami failai. Tai Blade tam irgi turi savo gan patogią sintaksę.

Pradėkime nuo paprasčiausio "include" - į vieną Blade failą galima įkelti kitą:
@include('header')
Main part.
@include('footer')
Šiuo atveju bus įkelti failai resources/views/header.blade.php ir resources/views/footer.blade.php

Taip pat galima įkelti šabloną, perduodant jam parametrų masyvą:
@include('header', ['title' => 'Mano projektas'])
 
Bet patogesnis būdas struktūrizuoti Blade šablonus yra sukurti vieną "bazinį" šabloną su jau sukurtomis "header", "footer" ir kitomis sekcijomis, ir nuo jo paveldėti visus likusius puslapius.
Pavyzdys:
resources/views/base.blade.php:
<html>
<head>
<title>Mano projektas</title>
</head>
<body>
@yield('main')
</body>
</html>
Struktūra @yield reiškia, kad šioje vietoje reikia sukurti skiltį, kurią vėliau galėsime skirtingai užpildyti skirtinguose puslapiuose.

Galbūt skamba painiai - bet štai pavyzdys dviejų šablonų, kurie sukurti paveldint "base" šabloną.

resources/views/about.blade.php:
@extends('base')

@section('main')
<h1>About us</h1>
<p>A text about us</p>
@stop
resources/views/contact.blade.php:
@extends('base')

@section('main')
<h1>Contact us</h1>
<p>Please fill in the form below...</p>
@stop
Ar pagavote logiką? Komanda @extends praneša, kokį šabloną užkrauti, o tada su komanda @section ... @stop nurodome konkretų turinį reikiamos skilties.
 

Katalogai su Blade

Didesniame projekte būtų nepatogu, jeigu visi Views failai būtų tiesiog viename resources/views kataloge - juk būtų suprantamiau suskirstyti juos į pakatalogius. Nėra jokių problemų - resources/views katalogo viduje kurkite kiek tik norite vidinių katalogų, ir į juos saugokite Blade šablonus su plėtiniu .blade.php!

Aišku, tada kyla klausimas, kaip šiuos šablonus iškviesti. Jie kviečiami, atskiriant kagalogus taško pagalba. Sakykime, jeigu yra šablonas resources/views/includes/header.blade.php, tai iš kitų šablonų jį galima iškviesti kaip @include('includes.header'). Taip pat panašiai ir iš routes/web.php failo galime kviesti view('includes.header').

Tiesa, mūsų projekto atveju tokios struktūros nenaudosime, nes pats projektas gan mažas - bus patogiau viską matyti vienoje vietoje. Bet ateityje galite patys spręsti, ties kur yra ta riba, kai verta resources/views kataloge kurti pakatalogius.

 
Tai tiek teorijos apie Blade. Reikia pridurti, kad visgi vyksta aktyvios diskusijos, ar tikrai verta perprasti dar vieną papildomą kalbą, kurios nepanaudosite jokiame kitame frameworke. Tai jei Blade privalumai jums neatrodo patrauklūs, viskas ok - galite Views failuose naudoti įprastą PHP kodą, ir viskas veiks gerai.

Dabar, kad būtų aiškiau - pereikime prie praktikos ir sukurkime mūsų krepšinio aikštelių projekto Blade šablonų struktūrą.
 

Praktika: mūsų projekto Blade šablonų struktūra

Visų pirma, sudėliokime mūsų projekto bazinio šablono struktūrą HTML formatu.
resources/views/base.blade.php:
<html>
  <head>
    <title>{{ $meta_title or 'Krepšinio aikštelės' }}</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
  </head>
  <body>
    <div id="wrapper">
      <div id="header">
        <a id="logo" href="{{ url('/') }}">KREPŠINIO AIKŠTELĖS</a>
      </div>
      <div id="main_menu">
        <ul>
          <li><a href="{{ url('/') }}">Pagrindinis</a></li>
          <li><a href="{{ url('aiksteles') }}">Aikštelių paieška</a></li>
          <li><a href="{{ url('apie') }}">Apie projektą</a></li>
          <li><a href="{{ url('kontaktai') }}">Kontaktai</a></li>
        </ul>
        <div class="clear"></div>
      </div>
      <div id="content">
        @yield('content')
      </div>
      <div id="footer">
        © {{ date('Y') }} PHPPamokos.lt. Visos teisės saugomos.
      </div>
    </div>
  </body>
</html>
Kaip matote, panaudojome praktiškai visas struktūras, kurias aptarėme šiame skyrelyje:
  • Kintamųjų išvedimas su {{ $var or '' }}
  • Pagalbines funkcijas {{ asset() }} ir {{ url() }}
  • Struktūra @yield, kurią netrukus panaudosime kituose šablonuose
resources/views/home.blade.php:
@extends('base')

@section('content')
<h2>Aikštelės paieška</h2>
<form action="{{ url('aiksteles') }}" method="post">
  <input type="text" name="search" />
  <input type="submit" name="search_submit" value=" Ieškoti " />
</form>
@stop
Štai taip atrodo pagrindinio puslapio šablonas. Tiesa, su formomis tvarkytis Laravel irgi turi kitokių patogesnių priemonių, bet tam bus skirtas atskiras skyrelis. Kol kas gi - pažiūrėkime, kaip kviečiamas reikalingas View failas, t.y. iš failo routes/web.php:
Route::get('/', function()
{
  return view('home');
});
Veiksmų seka tokia:
  • Pagal Route komandą bus iškviestas "resources/views/home.blade.php"
  • Nurodyta, kad "home.blade.php" praplečia "base.blade.php", tad bus užkraunamas tas šablonas
  • Tame šablone esanti @yield('content') komanda bus apdorota pagal "home.blade.php" aprašytą @section('content') turinį
  • Į naršyklę išvedamas galutinis visų šių funkcijų HTML rezultatas
Atrodo daugmaž taip: Beje, CSS failo css/style.css kodo specialiai čia nedėjau, nes čia nėra CSS kursas - kodas yra labai elementarus, galite parsisiųsti jį iš čia ir pasiredaguoti pagal save.

Atitinkamai reikėtų sukurti ir kitus tris Blade šablonus - puslapiams "Aikštelių paieška", "Apie mus" ir "Kontaktai". Bet būtent tai palikime jūsų namų darbams!
 

Namų darbai

Kaip jau paminėjau, prieš kitą pamoką pasitreniruokite kurti Views šablonus pagal pavyzdį:
  • Sukurkite šablonus puslapiams "Aikštelių paieška", "Apie mus", "Kontaktai"
  • Pabandykite į vieną iš šablonų perduoti $meta_title parametrą
Pasitikrinimui - paruošiau jums "teisingą atsakymą": galite parsisiųsti šiuos Views failus čia. Bet sutariame, kad pradžioje patys pasibandysite, gerai?


(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com