Twig 模板引擎实用技巧

Twig 是 PHP 生态中最流行的模板引擎之一,本文分享在实际项目中的实用技巧。

Twig 模板引擎实用技巧

Twig 是 PHP 生态中最流行的模板引擎之一,被 Symfony、Drupal 等知名项目采用。本文分享在实际项目中的实用技巧。

基础语法

变量输出

{# 输出变量 #}
{{ article.title }}

{# 输出数组/对象属性 #}
{{ user.name }}
{{ articles[0].title }}

{# 使用过滤器 #}
{{ article.content|striptags|truncate(100) }}
{{ price|number_format(2, '.', ',') }}

控制结构

{# 条件判断 #}
{% if articles|length > 0 %}
    {% for article in articles %}
        <article>
            <h2>{{ article.title }}</h2>
            <p>{{ article.excerpt }}</p>
        </article>
    {% endfor %}
{% else %}
    <p>暂无文章</p>
{% endif %}

实用技巧

1. 模板继承

模板继承是 Twig 最强大的特性之一,可以实现页面结构的复用:

{# base.html.twig #}
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}CodeSpace{% endblock %}</title>
    {% block styles %}{% endblock %}
</head>
<body>
    {% include 'partials/header.html.twig' %}
    <main>{% block content %}{% endblock %}</main>
    {% include 'partials/footer.html.twig' %}
</body>
</html>

{# article/detail.html.twig #}
{% extends 'base.html.twig' %}

{% block title %}{{ article.title }} - {{ parent() }}{% endblock %}

{% block content %}
    <article>
        <h1>{{ article.title }}</h1>
        {{ article.content_html|raw }}
    </article>
{% endblock %}

2. 自定义过滤器

// 注册自定义过滤器
$twig->addFilter(new \Twig\TwigFilter('markdown', function ($string) {
    return (new \League\CommonMark\MarkdownConverter())->convert($string);
}));

// 模板中使用
{{ article.content_md|markdown|raw }}

3. 宏定义复用组件

{# macros/article.html.twig #}
{% macro article_card(article) %}
    <article class="card">
        <h3><a href="/article/{{ article.slug }}">{{ article.title }}</a></h3>
        <p>{{ article.excerpt }}</p>
        <time>{{ article.published_at|date('Y-m-d') }}</time>
    </article>
{% endmacro %}

{# 使用宏 #}
{% import 'macros/article.html.twig' as macros %}
{% for article in articles %}
    {{ macros.article_card(article) }}
{% endfor %}

4. 安全输出

Twig 默认对输出进行 HTML 转义,防止 XSS 攻击:

{# 默认转义,安全的 #}
{{ user_input }}

{# 明确输出原始 HTML(仅在可信内容时使用)#}
{{ article.content_html|raw }}

{# 强制转义 #}
{{ content|e('html') }}

5. 上下文变量

{# 获取循环索引 #}
{% for article in articles %}
    <article class="item item-{{ loop.index }}">
        {# loop.index 从1开始, loop.index0 从0开始 #}
        {# loop.first / loop.last 判断首尾 #}
        {% if loop.first %}首发{% endif %}
    </article>
{% endfor %}

{# 设置变量 #}
{% set total = articles|length %}
{% set isActive = current_tag == tag.slug %}

性能优化

开启缓存

$twig = new \Twig\Environment($loader, [
    'cache' => '/path/to/cache',  // 编译缓存
    'auto_reload' => true,        // 开发环境自动重载
    'strict_variables' => false,   // 生产环境关闭严格模式
]);

减少模板嵌套

过深的模板继承和 include 会影响渲染性能。建议:

  • 继承层级不超过 3 层
  • 合理使用 include 复用片段
  • 避免在循环中 include

常见陷阱

1. raw 过滤器与安全

{# 危险!如果 content_html 来自用户输入且未净化 #}
{{ content|raw }}

{# 正确做法:存储前净化,渲染时再 raw #}
{{ purified_html|raw }}

2. 日期格式化

{# Twig 的 date 过滤器使用 strtotime 解析 #}
{{ article.published_at|date('Y年m月d日') }}

{# 处理 null 值 #}
{{ article.published_at ? article.published_at|date('Y-m-d') : '未发布' }}

3. 默认值处理

{# 使用 default 过滤器 #}
{{ article.cover|default('/images/default-cover.jpg') }}

{# 使用 ?? 运算符(Twig 2.x+) #}
{{ article.cover ?? '/images/default-cover.jpg' }}

总结

Twig 提供了安全、灵活、高效的模板渲染能力。掌握模板继承、宏、过滤器和安全输出,可以大幅提升开发效率。在生产环境中别忘了开启缓存,享受编译后的极致性能。

评论

加载中...