Widoki w Laravelu

Czas na kolejną partię wiedzy związanej z Laravelem.

Tym razem zajmiemy się widokami oraz routingiem.

Żeby wyświetlić stronę potrzebujesz jej struktury w postaci kodu HTML. Gdzie jest odpowiednie miejsce w architekturze Laravela na trzymanie kodu HTML?

Oczywiście, w widoku.

Jeśli pamiętasz z poprzedniej części poradnika, widoki znajdują się w katalogu recources/views/.

Wszystkie widoki w Laravelu są plikami z rozszerzeniem .blade.php -> pliki te umożliwiają bardzo zgrabne wzbogacanie kodu HTML własnym kodem PHP. Jeśli podejrzysz sobie jedyny plik widoku, którym dysponuje Twoja goła aplikacja, zauważysz charakterystyczne „łezki”. To podwójny nawias klamrowy, który jest traktowany jako miejsce do wykonania akcji.

Przykładowo, w widoku na linii nr 72 znajdziesz instrukcję:

 <a href="{{ url('/home') }}">Home</a>

Znaczy to mniej więcej tyle: przygotuj mi kompletny URL o adresie /home. Jeśli nasz adres bazowy to https://kursphp.com, to funkcja url(‚/home’) zwróci w wyniku https://kursphp.com/home.

Jest to o tyle przydatne, że zmieniając główny adres URL strony (lub przenosząc ją między środowiskiem lokalnym, testowym i produkcyjnym) wystarczy, że adres zmienisz tylko w jednym miejscu. Reszta kodu pozostaje nietknięta, a wszystkie odnośniki działają poprawnie.

Laravel a adres bazowy URL

Gdzie się ustawia adres bazowy strony w Laravelu?

Służy do tego plik .env w katalogu głównym projektu.

Env to skrót od environment, czyli środowisko. Znajdziesz w nim wszystkie zmienne środowiskowe, które ustawiasz w zależności od środowiska, w którym uruchamiasz aplikację. Przenosząc aplikację z jednego miejsca na drugie, plik .env to jedyne miejsce, gdzie powinieneś (i musisz) coś pozmieniać.

Znajdują się tam adresy i dane logowania do bazy danych, systemu wysyłki maili, Redisa, URL Twojej strony, nazwa aplikacji itp. Jedną flagą ustawia się również wyświetlanie (lub nie) szczegółowych będów na ekranie.

Ustawienia domyślne dla kilku pierwszych parametrów pliku .env wyglądają następująco:

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:xx/xxxxxxxMxFIKxxxxxxxxe4=
APP_DEBUG=true
APP_URL=http://localhost

APP_URL to parametr określający adres URL aplikacji.

Oprócz podwójnego nawiasu klamrowego będziesz korzystał z instrukcji zaczynających się od znaku @.

W widoku welcome.blade.php możesz znaleźć następujący przykład:

@if (Route::has('login'))
                <div class="top-right links">
                    @auth
                        <a href="{{ url('/home') }}">Home</a>
                    @else
                        <a href="{{ route('login') }}">Login</a>
                        <a href="{{ route('register') }}">Register</a>
                    @endauth
                </div>
            @endif

Od małpy zaczynami jednolinijkowe komendy PHP, które wpływają na generowanie naszego widoku. W przykładzie powyżej masz np. sprawdzenie warunkiem if, czy w routingu jest zapisana ścieżka o nazwie ‚login’. Jeśli tak, kod HTML aż do komendy @endif będzie wyświetlony.

Tak samo komenda @auth. Ta komenda jest skrótowym zapisem warunku if, który sprawdza, czy użytkownik jest zalogowany. Jeśli tak, wykona się

<a href="{{ url('/home') }}">Home</a>

Jeśli nie (blok @else):

<a href="{{ route('login') }}">Login</a>
<a href="{{ route('register') }}">Register</a>

Aż do zakończenia bloku @endauth.

Przyjdzie czas na bardziej dogłębne opanowanie wstawek PHP w widokach blade.php. Teraz czas stworzyć swój pierwszy widok i wyświetlić go w aplikacji.

Tworzymy nowy widok

Stwórz plik o nazwie hello.blade.php w folderze /resources/views.

Wypełnij go dowolnym kodem HTML. Ja, na przykład, wypełniłem go w ten sposób:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Hello kursphp.com</title>
    </head>
    <body>
        <h1>Hello world kursphp.com</h1>
    </body>
</html>

Nowy widok stworzony, czas teraz spróbować go wyświetlić.

Routing w Laravelu

Jak Laravel rozpoznaje, który widok załadować bazując na ścieżce URL?

Dzieje się to na podstawie tabeli routingu.

Taka tabela trzyma powiązania między adresem URL a akcją, która ma się wykonać. Czasami może być to wykonanie akcji na konkretnym kontrolerze, czasami wyświetlenie wybranego widoku, a czasami przekierowanie na inny URL.

Wszystkie te powiązania są trzymane w plikach w folderze /routes.

Gdy otworzysz sobie ten folder zobaczysz cztery pliki:

  • api.php
  • channels.php
  • console.php
  • web.php

Są to tabele routingów dla (kolejno): Twojego API, kanałów broadcastingu, aplikacji odpalanej z konsoli i aplikacji webowej. Ciebie obecnie interesuje ta ostatnia.

Otwórz plik web.php i zobacz zawartość:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Jak widzisz, zarejestrowana jest jedna ścieżka – ‚/’ (ukośnik). Ścieżka ta odnosi się do głównego adresu Twojej aplikacji. Co ważne, metoda Route::get oznacza, że akcja podpięta pod ten adres wykona się tylko dla metody HTTP GET. Jeśli spróbujemy odwołać się do niej metodą POST (lub inną) dostaniemy błąd 404 NOT FOUND.

Dodawanie nowej ścieżki (z ang. route) opiera się na podaniu adresu oraz, po przecinku, podaniu akcji do wykonania. W tym przypadku jest to funkcja zwracająca widok o tytule ‚welcome’.

Rozpoznawanie widoków

Z racji, że stworzyliśmy nasz własny widok, jak możemy teraz przypisać jego wyświetlenie do akcji przy danym URL? Jak powiadomić Laravela, że chcemy użyć widoku hello.blade.php?

Bardzo prosto.

Laravel rozpoznaje widoki po nazwie.

Wystarczy, że dodamy nową ścieżkę:

Route::get('/hello', function () {
    return view('hello');
});

Laravel, widząc nazwę widoku ‚hello’, będzie szukał pliku o nazwie hello.blade.php w katalogu /resources/views. Jeśli podalibyśmy inną nazwę, przykładowo view(‚item’), będzie szukał pliku item.blade.php.

Świetnie! Czy to znaczy, że wszystkie pliki z widokiem muszę trzymać w jednym katalogu? Przecież zrobi się z tego niezły bajzel.

Oczywiście, że nie musisz!

Musisz jedynie trzymać się katalogu nadrzędnego /resources/views. Jeśli chcesz podzielić swoje widoki, zrób to wewnątrz tego katalogu. Stwórz np. katalog admin, w którym stworzysz katalog item, w którym będzie widok edit.blade.php. Otrzymasz finalnie ścieżkę /resources/views/admin/item/edit.blade.php.

By wyświetlić ten widok, w funkcji view() podaj następującą ścieżkę:

Route::get('/hello', function () {
    return view('admin.item.edit');
});

Jak widzisz, zagnieżdżenia folderów podajesz używając kropek. Dzięki temu możesz tworzyć tyle katalogów, ile tylko Ci się podoba. Nie warto oczywiście przesadzać. Pracuj tak, by było Ci wygodnie. Narzędzie jest pod tym kątem eastyczne.

Wracając do naszej ścieżki, użyłem w niej adresu /hello.

Oznacza to tyle, że jeśli uruchamiasz stronę lokalnie na adresie http://localhost:8000, to nowy widok będzie dostępny po wpisaniu http://localhost:8000/hello.

U mnie uzyskałem taki efekt:

Na koniec zróbmy płynne przejście między stroną główną a stroną hello.

Otwórz plik welcome.blade.php i dopisz link, który wskazuje na adres /hello.

Ja uzyskałem ten efekt dodając kolejnego linka do linków wyświetlanych na stronie głównej:

<div class="links">
                    <a href="https://laravel.com/docs">Documentation</a>
                    <a href="https://laracasts.com">Laracasts</a>
                    <a href="https://laravel-news.com">News</a>
                    <a href="https://forge.laravel.com">Forge</a>
                    <a href="https://github.com/laravel/laravel">GitHub</a>
                    <a href="{{ url('/hello') }}">HELLO</a>
                </div>

Dzięki użyciu podwójnych nawiasów klamrowych, zmiana adresu głównego strony www nie wpłynie w żaden sposób na działanie linka. Po zapisaniu zmian i odświeżeniu strony, powinieneś zobaczyć szósty link, który wskazuje na naszą nową stronę:

Dla przyzwoitości dopiszmy jeszcze powrót na stronę główną ze strony hello. Wracając do pliku hello.blade.php:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Hello kursphp.com</title>
    </head>
    <body>
        <h1>Hello world kursphp.com</h1>
        <p>
            <a href="{{ url('/') }}">Wróć na główną</a>
        </p>
    </body>
</html>

Pięknie, mamy działającą nawigację między stronami, która w dodatku jest odporna na przyszłe zmiany środowiska!

Podsumowując,

Widoki w Laravelu są trzymane w katalogu /resources/views.

Laravel odszukuje dany widok po nazwie, stąd nie musisz ich nigdzie rejestrować ani konfigurować. Jedyną rzeczą, o której musisz pamiętać, to katalog routes i dodanie nowej ścieżki, która wyświetli dany widok. Docelowo, ścieżka w routingu będzie wykonywać konkretną akcję na kontrolerze. Zwracanie widoków bezpośrednio przez ścieżkę tyczy się wyłącznie prostych stron www pozbawionych kontekstu. Jeśli będziesz potrzebował wypełnić widok danymi z modelu, przyda Ci się kontroler, który zadba o komunikację między jednym i drugim.

Jeśli nie do końca rozumiesz działanie wzorca MVC (Model, View, Controller) zachęcam do zapoznania się z kursem MVC w PHP od zera.

Przy jego pomocy napiszesz własny framework MVC krok po kroku i zrozumiesz podstawy działania MVC.

Tymczasem wszystkiego dobrego i powodzenia!