<? phpukraine ДОКУМЕНТАЦІЯ
⌕Пошук по платформі
Документація українською

Переклад офіційної документації українською. Кожен розділ показує стан готовності: недоперекладене позначене відкрито, а не приховане.

ВЕРСІЯ
АКТУАЛЬНА Актуальний реліз. Переклад наздоганяє оригінал, розділи з низьким відсотком позначені у змісті.
ОСНОВИ · ЧАСТКОВО частковий переклад, оновлено 29 вересня 2026

Шаблони Twig · Symfony

ПЕРЕКЛАД НЕПОВНИЙ

Частину підрозділів ще не перекладено, вони показані англійською нижче в тексті або лишились в оригіналі. Готові фрагменти вже перевірені редактором.

Шаблон - найкращий спосіб організувати й відрендерити HTML усередині застосунку, байдуже, рендерите ви HTML із контролера чи генеруєте вміст листа. Шаблони в Symfony створюються за допомогою Twig: гнучкого, швидкого й безпечного шаблонізатора.

Встановлення

У застосунках, що використовують Symfony Flex, виконайте таку команду, щоб встановити і підтримку мови Twig, і її інтеграцію з застосунками Symfony:

$ composer require symfony/twig-bundle

Мова шаблонів Twig

Мова шаблонів Twig дозволяє писати лаконічні, читабельні шаблони, які зручніші для вебдизайнерів і в кількох аспектах потужніші за PHP-шаблони. Погляньте на приклад шаблону Twig нижче. Навіть якщо ви бачите Twig уперше, ви, найімовірніше, зрозумієте більшу його частину:

<!DOCTYPE html>
<html>
    <head>
        <title>Welcome to Symfony!</title>
    </head>
    <body>
        <h1>{{ page_title }}</h1>

        {% if user.isLoggedIn %}
            Hello {{ user.name }}!
        {% endif %}

        {# ... #}
    </body>
</html>

Синтаксис Twig побудований на трьох конструкціях:

  • {{ ... }} - виводить вміст змінної або результат обчислення виразу;
  • {% ... %} - виконує якусь логіку, наприклад умову чи цикл;
  • {# ... #} - додає коментарі до шаблону (на відміну від HTML-коментарів, ці коментарі не потрапляють у відрендерену сторінку).

Виконувати PHP-код усередині шаблонів Twig не можна, натомість Twig дає інструменти для невеликої логіки в шаблонах. Наприклад, фільтри змінюють вміст перед рендерингом, як-от фільтр upper, що переводить вміст у верхній регістр:

{{ title|upper }}

Twig має довгий перелік тегів, фільтрів і функцій, доступних за замовчуванням. У застосунках Symfony ви також можете користуватися фільтрами та функціями Twig, які визначає Symfony, і створювати власні фільтри й функції Twig.

Twig швидкий в оточенні prod (бо шаблони компілюються в PHP і кешуються автоматично) і зручний в оточенні dev (бо шаблони перекомпільовуються автоматично, щойно ви їх змінюєте).

Конфігурація Twig

Twig має кілька опцій конфігурації, які задають формат виведення чисел і дат, кешування шаблонів тощо. Про них читайте в довіднику конфігурації Twig.

Створення шаблонів

Перш ніж детально розбирати створення й рендеринг шаблонів, погляньте на приклад нижче, щоб побачити весь процес цілком. Спершу створіть новий файл у теці templates/, де зберігатиметься вміст шаблону:

{# templates/user/notifications.html.twig #}
<h1>Hello {{ user_first_name }}!</h1>
<p>You have {{ notifications|length }} new notifications.</p>

Далі створіть контролер, який рендерить цей шаблон і передає в нього потрібні змінні:

// src/Controller/UserController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class UserController extends AbstractController
{
    // ...

    public function notifications(): Response
    {
        // якось отримуємо інформацію про користувача та сповіщення
        $userFirstName = '...';
        $userNotifications = ['...', '...'];

        // шлях до шаблону - це відносний шлях до файлу від `templates/`
        return $this->render('user/notifications.html.twig', [
            // цей масив визначає змінні, які передаються в шаблон,
            // де ключ - це імʼя змінної, а значення - її значення
            // (Twig рекомендує імена змінних у snake_case: 'foo_bar' замість 'fooBar')
            'user_first_name' => $userFirstName,
            'notifications' => $userNotifications,
        ]);
    }
}

Іменування шаблонів

Symfony рекомендує таке для імен шаблонів:

  • Використовуйте snake case для імен файлів і тек (наприклад, blog_posts.html.twig, admin/default_theme/blog/index.html.twig тощо);
  • Задавайте два розширення в іменах файлів (наприклад, index.html.twig або blog_posts.xml.twig), де перше розширення (html, xml тощо) - це кінцевий формат, який згенерує шаблон.

Хоча зазвичай шаблони генерують HTML-вміст, вони можуть згенерувати будь-який текстовий формат. Саме тому угода про два розширення спрощує створення й рендеринг шаблонів для кількох форматів.

Розташування шаблонів

За замовчуванням шаблони зберігаються в теці templates/. Коли сервіс або контролер рендерить шаблон product/index.html.twig, насправді йдеться про файл <your-project>/templates/product/index.html.twig.

Типову теку шаблонів можна змінити опцією twig.default_path, а додаткові теки шаблонів додаються так, як описано далі в цій статті.

Змінні шаблону

Типова потреба в шаблонах - вивести значення, збережені в шаблонах, які передав контролер або сервіс. Змінні зазвичай містять обʼєкти й масиви, а не рядки, числа чи булеві значення. Тому Twig дає швидкий доступ до складних PHP-змінних. Розгляньмо такий шаблон:

<p>{{ user.name }} added this comment on {{ comment.publishedAt|date }}</p>

Запис user.name означає, що ви хочете вивести якусь інформацію (name), збережену в змінній (user). user - це масив чи обʼєкт? name - властивість чи метод? У Twig це не має значення.

Коли ви використовуєте запис foo.bar, Twig намагається отримати значення змінної в такому порядку:

  1. $foo['bar'] (масив і елемент);
  2. $foo->bar (обʼєкт і публічна властивість);
  3. $foo->bar() (обʼєкт і публічний метод);
  4. $foo->getBar() (обʼєкт і метод-getter);
  5. $foo->isBar() (обʼєкт і метод-isser);
  6. $foo->hasBar() (обʼєкт і метод-hasser);
  7. Якщо нічого з переліченого не існує, використовується null (або викидається виняток Twig\Error\RuntimeError, якщо ввімкнено опцію strict_variables).

Це дозволяє розвивати код застосунку без змін у коді шаблону (можна почати зі змінних-масивів для proof of concept застосунку, а потім перейти на обʼєкти з методами тощо).

Замість того щоб писати URL посилань вручну, використовуйте функцію path(), яка генерує URL на основі конфігурації маршрутизації.

Згодом, якщо захочете змінити URL конкретної сторінки, достатньо буде змінити конфігурацію маршрутизації: шаблони автоматично згенерують новий URL.

Розгляньмо таку конфігурацію маршрутизації:

// src/Controller/BlogController.php
namespace App\Controller;

// ...
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class BlogController extends AbstractController
{
    #[Route('/', name: 'blog_index')]
    public function index(): Response
    {
        // ...
    }

    #[Route('/article/{slug}', name: 'blog_post')]
    public function show(string $slug): Response
    {
        // ...
    }
}
# config/routes.yaml
blog_index:
    path:       /
    controller: App\Controller\BlogController::index

blog_post:
    path:       /article/{slug}
    controller: App\Controller\BlogController::show
// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\BlogController;

return Routes::config([
    'blog_index' => [
        'path' => '/',
        'controller' => [BlogController::class, 'index'],
    ],
    'blog_post' => [
        'path' => '/article/{slug}',
        'controller' => [BlogController::class, 'show'],
    ],
]);

Щоб зробити посилання на ці сторінки, використовуйте функцію Twig path(): першим аргументом передайте імʼя маршруту, а другим (необовʼязковим) - параметри маршруту:

<a href="{{ path('blog_index') }}">Homepage</a>

{# ... #}

{% for post in blog_posts %}
    <h1>
        <a href="{{ path('blog_post', {slug: post.slug}) }}">{{ post.title }}</a>
    </h1>

    <p>{{ post.excerpt }}</p>
{% endfor %}

Функція path() генерує відносні URL. Якщо вам потрібні абсолютні URL (наприклад, коли ви рендерите шаблони для листів або RSS-стрічок), використовуйте функцію url(), яка приймає ті самі аргументи, що й path() (наприклад, <a href="{{ url('blog_index') }}"> ... </a>).

Якщо шаблону потрібно послатися на статичний ресурс (наприклад, зображення), Symfony дає функцію Twig asset(), яка допомагає згенерувати цей URL. Спершу встановіть пакет asset:

$ composer require symfony/asset

Тепер можна користуватися функцією asset():

{# the image lives at "public/images/logo.png" #}
<img src="{{ asset('images/logo.png') }}" alt="Symfony!">

{# the CSS file lives at "public/css/blog.css" #}
<link href="{{ asset('css/blog.css') }}" rel="stylesheet">

{# the JS file lives at "public/bundles/acme/js/loader.js" #}
<script src="{{ asset('bundles/acme/js/loader.js') }}"></script>

Функцію asset() рекомендовано використовувати з таких причин:

  • Версіонування ресурсів: asset() додає до URL ресурсу хеш версії, щоб скидати кеш. Це працює і через AssetMapper, і через компонент Asset (дивіться також опції конфігурації ресурсів, як-от version і version_format).

  • Переносимість застосунку: незалежно від того, розміщений ваш застосунок у корені (наприклад, https://example.com) чи в підтеці (наприклад, https://example.com/my_app), asset() автоматично згенерує правильний шлях (/images/logo.png проти /my_app/images/logo.png) на основі базового URL застосунку.

Якщо вам потрібні абсолютні URL для ресурсів, використовуйте функцію Twig absolute_url() ось так:

<img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!">

<link rel="shortcut icon" href="{{ absolute_url('favicon.png') }}">

Не перекладено підрозділи: The App Global Variable, Rendering Templates (Rendering a Template in Controllers, Rendering a Template in Services, Rendering a Template in Emails, Rendering a Template Directly from a Route), Checking if a Template Exists, Debugging Templates (Linting Twig Templates, Inspecting Twig Information), Reusing Template Contents (Including Templates, Embedding Controllers), Template Inheritance and Layouts, Output Escaping, Template Namespaces (Bundle Templates), Twig Extensions (Creating Extensions, Lazy-Loaded Twig Extensions), Learn more.

Стан перекладу

Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.

46%
Готовності
2
У роботі
14
Ще не перекладено
Глосарій термінів