Widoki w PHP - Kompleksowy Przewodnik po Twig
Czym są widoki w aplikacjach PHP?
Widoki stanowią warstwę prezentacji w architekturze MVC (Model-View-Controller). Odpowiadają za renderowanie danych i generowanie HTML wysyłanego do przeglądarki użytkownika. W kursie PHP 8.4 prezentujemy kompleksowe podejście do budowania systemu widoków - od integracji z gotowymi silnikami renderującymi jak Twig, przez implementację własnego silnika inspirowanego Blade, aż po nowoczesne SPA z Inertia.js i Vue 3.
Dlaczego warto nauczyć się systemu widoków?
Kluczowe korzyści
- Separacja logiki biznesowej od warstwy prezentacji
- Możliwość współpracy programistów z projektantami
- Wielokrotne wykorzystanie komponentów UI (DRY principle)
- Zwiększenie bezpieczeństwa dzięki automatycznemu escapowaniu
Twig - Popularny Silnik Szablonów
Twig to jeden z najpopularniejszych silników szablonów w ekosystemie PHP. Został zaprojektowany z myślą o prostocie, elastyczności i wydajności. W kursie dowiesz się, jak zintegrować Twig z własnym frameworkiem poprzez stworzenie adaptera zgodnego z wzorcami projektowymi.
Główne zalety Twig
- Elastyczność - możliwość tworzenia niestandardowych rozszerzeń i funkcji
- Wydajność - widoki kompilowane do zoptymalizowanego kodu PHP
- Bezpieczeństwo - automatyczne escapowanie zmiennych
- Czytelność - składnia zaprojektowana dla projektantów
Podstawowa składnia Twig
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>Witaj, {{ name|capitalize }}!</h1>
{% if user.isLoggedIn %}
<p>Zalogowany jako: {{ user.email }}</p>
{% else %}
<p>Proszę się zalogować.</p>
{% endif %}
<ul>
{% for post in posts %}
<li>{{ post.title }} - {{ post.created_at|date("d-m-Y") }}</li>
{% endfor %}
</ul>
</body>
</html>
Architektura systemu widoków w kursie
W kursie PHP 8.4 budujesz kompletny, modularny system widoków składający się z kilku kluczowych komponentów:
1. Adapter Twig - Integracja z silnikiem
TwigRendererAdapter implementuje interfejs adaptera i wykorzystuje klasę Twig\Environment
do renderowania widoków. Adapter odpowiada za:
- Renderowanie szablonów z przekazanymi danymi
- Zarządzanie pamięcią podręczną (cache)
- Konfigurację środowiska (development/production)
<?php
class TwigRendererAdapter extends BaseAdapter implements RendererInterface
{
public function __construct(
private readonly Environment $twig,
private readonly string $cacheDir
) {}
public function render(string $template, array $data = []): string
{
return $this->twig->render($template, $data);
}
public static function buildDefault(): self
{
$config = config('views.twig');
$loader = new FilesystemLoader($config['paths']);
$twig = new Environment($loader, [
'cache' => $config['cache'],
'auto_reload' => $config['auto_reload'],
]);
return new self($twig, $config['cache']);
}
}
2. Klasa View - Abstrakcja nad rendererami
Klasa View pełni rolę pośrednika między kontrolerem a adapterem renderującym. Implementuje wzorzec projektowy Facade, upraszczając interfejs do renderowania widoków.
<?php
class View
{
public function __construct(
private readonly RendererInterface $renderer,
private readonly string $template,
private array $data = []
) {}
public function with(string|array $key, mixed $value = null): self
{
if (is_array($key)) {
$this->data = array_merge($this->data, $key);
} else {
$this->data[$key] = $value;
}
return $this;
}
public function render(): ResponseInterface
{
$content = $this->renderer->render($this->template, $this->data);
return new Response(body: $content);
}
}
3. Integracja w kontrolerze
Bazowa klasa Controller zapewnia wygodne metody do renderowania widoków. Możesz w łatwy sposób zmienić domyślny renderer dla konkretnego kontrolera.
<?php
abstract class Controller
{
protected ViewManager $viewManager;
protected string $defaultRenderer = 'twig';
public function __construct(ViewManager $viewManager)
{
$this->viewManager = $viewManager;
}
protected function render(string $template, array $data = []): ResponseInterface
{
return $this->viewManager
->withRenderer($this->defaultRenderer)
->make($template, $data)
->render();
}
protected function withRenderer(string $renderer): self
{
$this->defaultRenderer = $renderer;
return $this;
}
}
Layouty i dziedziczenie w Twig
Twig umożliwia tworzenie layoutów, które mogą być wspólne dla wielu szablonów. Layout to szkielet HTML z zdefiniowanymi sekcjami do wypełnienia.
Przykładowy layout (layouts/app.twig)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Moja aplikacja{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
{% block styles %}{% endblock %}
</head>
<body>
<nav >
<div >
<a href="/">MasterPHP</a>
</div>
</nav>
<main >
{% block content %}{% endblock %}
</main>
<footer >
<div >
{% block footer %}
<p>© 2025 MasterPHP</p>
{% endblock %}
</div>
</footer>
{% block scripts %}{% endblock %}
</body>
</html>
Widok wykorzystujący layout (home.twig)
{% extends "layouts/app.twig" %}
{% block title %}Strona główna - MasterPHP{% endblock %}
{% block content %}
<h1>{{ pageTitle }}</h1>
<p>{{ welcomeMessage }}</p>
<div >
{% for feature in features %}
<div >
<div >
<div >
<h5 >{{ feature.title }}</h5>
<p >{{ feature.description }}</p>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
{% block scripts %}
<script src="/js/app.js"></script>
{% endblock %}
Formattery i filtry w Twig
Formattery w Twig pozwalają na przekształcanie danych bezpośrednio w szablonach. Są szczególnie przydatne do formatowania dat, liczb czy operacji na tekście.
Przykłady użycia filtrów
{# Formatowanie dat #}
{{ post.created_at|date("d-m-Y H:i") }}
{{ "now"|date("Y-m-d") }}
{# Formatowanie liczb #}
{{ 1234.567|number_format(2, ',', ' ') }} {# 1 234,57 #}
{# Operacje na tekście #}
{{ "witaj w aplikacji"|capitalize }} {# Witaj w aplikacji #}
{{ user.email|lower }}
{{ content|truncate(150) }}
{{ html_content|striptags }}
{# Operacje na tablicach #}
{{ items|length }}
{{ items|first }}
{{ items|last }}
{{ items|join(', ') }}
Kompilacja i cache widoków twig
Twig kompiluje szablony do zoptymalizowanego kodu PHP i przechowuje je w pamięci podręcznej. Dzięki temu renderowanie jest bardzo szybkie - parsowanie odbywa się tylko raz.
Konfiguracja cache
<?php
// config/views.php
return [
'default' => 'twig',
'twig' => [
'paths' => [
base_path('resources/views/twig'),
],
'cache' => base_path('storage/cache/twig'),
'auto_reload' => env('APP_ENV') === 'local',
'debug' => env('APP_DEBUG', false),
],
];
Czyszczenie cache
Adapter Twig zawiera metodę clearCache()
, która usuwa wszystkie skompilowane widoki. Jest to przydatne podczas deployment lub debugowania.
<?php
public function clearCache(): void
{
if (!is_dir($this->cacheDir)) {
return;
}
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$this->cacheDir,
FilesystemIterator::SKIP_DOTS
),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iterator as $file) {
$file->isDir() ? rmdir($file) : unlink($file);
}
}
Wzorce projektowe w systemie widoków
Implementacja systemu widoków wykorzystuje sprawdzone wzorce projektowe:
- Adapter - TwigRendererAdapter adaptuje interfejs Twig\Environment
- Facade - Klasa View upraszcza interfejs renderowania
- Factory - ViewManager tworzy odpowiednie adaptery
- Strategy - Możliwość wyboru różnych rendererów (Twig, Blade, Inertia)
- Template Method - BaseAdapter definiuje wspólne metody dla adapterów
Testowanie widoków
System widoków jest w pełni testowalny. W kursie znajdziesz testy integracyjne sprawdzające poprawność renderowania szablonów.
<?php
class TwigControllerTest extends TestCase
{
public function testRenderingTwigView(): void
{
$_SERVER['REQUEST_METHOD'] = 'GET';
//kontroler wywołujący widok z użyciem twig
$_SERVER['REQUEST_URI'] = '/twig-test';
$app = Application::getInstance();
$response = $app->handle($request);
$this->assertEquals(200, $response->getStatusCode());
$this->assertStringContainsString('<h1>Test Title</h1>', (string)$response->getBody());
// Cleanup
unset($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
}
}
Dla kogo jest ten kurs?
- Programiści PHP chcący zrozumieć, jak działają silniki szablonów
- Developerzy Laravel/Symfony pragnący poznać mechanizmy pod maską
- Osoby tworzące własne frameworki i biblioteki
- Architekci oprogramowania szukający wzorców projektowych w praktyce
🎓 Zbuduj system widoków od zera!
W kursie PHP 8.4 implementujesz kompletny system widoków - od adaptera Twig, przez własny silnik Blade, aż po nowoczesne SPA z Inertia.js i Vue 3. Każdy komponent testowany i zgodny z najlepszymi praktykami.