Programowanie

Twig od podstaw — szablony, filtry, makra i dziedziczenie

Anna Nowak 17.10.2026 165 wyświetleń 0 komentarzy
Dostępne w językach: 🇵🇱 PL 🇬🇧 EN

Trzy rodzaje tagów Twig

{# komentarz — nie trafia do HTML #}

{{ zmienna }}
{{ artykul.tytul }}
{{ user.getName() }}

{% if warunek %}...{% endif %}
{% for item in kolekcja %}...{% endfor %}
{% block content %}...{% endblock %}

Dziedziczenie layoutów

To najważniejsza funkcja Twig — unikasz powielania HTML:

{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}FactoryCode{% endblock %}</title>
    {% block stylesheets %}{% endblock %}
</head>
<body>
    {% block body %}{% endblock %}
    {% block javascripts %}{% endblock %}
</body>
</html>
{# templates/blog/show.html.twig #}
{% extends 'base.html.twig' %}

{% block title %}{{ article.title }} — Blog{% endblock %}

{% block body %}
    <h1>{{ article.title }}</h1>
    <div class="content">
        {{ article.content|markdown }}
    </div>
{% endblock %}

Filtry

{{ 'hello world'|upper }}              {# HELLO WORLD #}
{{ 'HELLO'|lower }}                    {# hello #}
{{ article.content|length }}           {# liczba znaków #}
{{ article.content|truncate(200) }}    {# skróć do 200 znaków #}
{{ price|number_format(2, ',', ' ') }} {# 1 234,56 #}
{{ date|date('d.m.Y H:i') }}           {# 23.06.2025 14:30 #}
{{ article.content|nl2br }}            {# \n → <br> #}
{{ article.content|markdown }}         {# Markdown → HTML #}
{{ rawHtml|raw }}                      {# wyłącz escapowanie #}

Warunki i pętle

{% if article.isPublished %}
    <span class="badge bg-success">Opublikowany</span>
{% elseif article.status == 'draft' %}
    <span class="badge bg-secondary">Szkic</span>
{% else %}
    <span class="badge bg-warning">{{ article.status }}</span>
{% endif %}

{% for tag in article.tags %}
    <span class="tag">#{{ tag.name }}</span>
{% else %}
    <span class="text-muted">Brak tagów</span>
{% endfor %}

Makra — wielokrotne użycie

{% macro alert(message, type = 'info') %}
    <div class="alert alert-{{ type }}">
        {{ message }}
    </div>
{% endmacro %}

{# użycie #}
{{ _self.alert('Artykuł zapisany!', 'success') }}
{{ _self.alert('Błąd walidacji', 'danger') }}

include vs embed

{# include — wstawia szablon, dziedziczy wszystkie zmienne #}
{% include 'components/_card.html.twig' with {article: article} %}

{# embed — wstawia szablon i pozwala nadpisywać jego bloki #}
{% embed 'components/_modal.html.twig' %}
    {% block title %}Potwierdzenie usunięcia{% endblock %}
    {% block body %}Czy na pewno chcesz usunąć ten artykuł?{% endblock %}
{% endembed %}

Własne rozszerzenie Twig

// src/Twig/AppExtension.php
class AppExtension extends AbstractExtension
{
    public function getFilters(): array
    {
        return [
            new TwigFilter('reading_time', function (string $content): int {
                $words = str_word_count(strip_tags($content));
                return (int) ceil($words / 200); // ~200 słów/min
            }),
        ];
    }
}
{# użycie #}
<span>{{ article.content|reading_time }} min czytania</span>
Tagi: #PHP #Symfony #Twig
Udostępnij: Facebook X LinkedIn

Komentarze (0)


Bądź pierwszy — zostaw komentarz!

Zaloguj się, aby dodać komentarz.