{% raw %}

Twig 教程

原文: https://zetcode.com/php/twig/

Twig 教程展示了如何在 PHP 应用中使用 Twig 模板引擎来生成文档。

枝条

Twig 是一个 PHP 模板引擎。 它是由 Symfony 开发者创建的。 Twig 文件的扩展名为.html.twig; 它们是静态数据(例如 HTML 和 Twig 构造)的混合。

Twig 使用双大括号分隔符{{ }}进行输出,并使用大括号百分比定界符{% %}进行逻辑运算。 {# #}用于注释。

  1. <ul>
  2. {% for word in words %}
  3. <li>{{ word }}</li>
  4. {% endfor %}
  5. </ul>

此代码是示例 Twig 语法。 在此代码中,我们使用for标签创建一个循环。

Twig 语法由标签,过滤器,函数,运算符和测试组成。

安装 Twig

首先,我们设置了 Twig。

  1. $ composer require twig/twig

我们用 Composer 安装 Twig。

  1. $ mkdir templates

我们将模板文件放入template目录。

  1. require __DIR__ . '/vendor/autoload.php';

我们需要将autoload.php文件添加到脚本中。

模板引擎

模板引擎或模板处理器是一个旨在将模板与数据模型结合以生成文档的库。 模板引擎通常用于在源代码预处理或生成动态 HTML 页面中生成大量电子邮件。

我们创建一个模板引擎,在其中定义静态零件和动态零件。 动态部分随后将替换为数据。 渲染函数随后将模板与数据结合在一起。

Twig 第一个例子

以下是 Twig 模板系统的简单演示。

first.php

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. use Twig\Environment;
  4. use Twig\Loader\FilesystemLoader;
  5. $loader = new FilesystemLoader(__DIR__ . '/templates');
  6. $twig = new Environment($loader);
  7. echo $twig->render('first.html.twig', ['name' => 'John Doe',
  8. 'occupation' => 'gardener']);

我们使用FilesystemLoader从指定目录加载模板。

  1. echo $twig->render('first.html.twig', ['name' => 'John Doe',
  2. 'occupation' => 'gardener']);

输出通过render()生成。 它带有两个参数:模板文件和数据。

templates/first.html.twig

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. <p>
  10. {{ name }} is a {{ occupation }}
  11. </p>
  12. </body>
  13. </html>

这是模板文件。 变量以{{}}语法输出。

  1. $ php first.php
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <p>
  11. John Doe is a gardener
  12. </p>
  13. </body>
  14. </html>

这是输出。

Twig 过滤器

过滤器使我们能够以各种方式修改数据。

filters.php

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. use Twig\Environment;
  4. use Twig\Loader\FilesystemLoader;
  5. $loader = new FilesystemLoader(__DIR__ . '/templates');
  6. $twig = new Environment($loader);
  7. $words = ['sky', 'mountain', 'falcon', 'forest', 'rock', 'blue'];
  8. $sentence = 'today is a windy day';
  9. echo $twig->render('filters.html.twig',
  10. ['words' => $words, 'sentence' => $sentence]);

在示例中,我们有一个数组和一个字符串作为模板数据。

templates/filters.html.twig

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Filters</title>
  7. </head>
  8. <body>
  9. <p>
  10. The array has {{ words | length }} elements
  11. </p>
  12. <p>
  13. Joined array elements: {{ words | join(',') }}
  14. </p>
  15. <p>
  16. {{ sentence | title }}
  17. </p>
  18. </body>
  19. </html>

过滤器应用|字符。 该示例使用length对单词进行计数,使用join连接数组元素,并使用title修改字符。

Twig 自定义过滤器

我们可以使用Twig_Filter创建自定义过滤器。

customfilter.php

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. use Twig\Environment;
  4. use Twig\Loader\FilesystemLoader;
  5. $loader = new FilesystemLoader(__DIR__ . '/templates');
  6. $twig = new Environment($loader);
  7. $twig->addFilter(new Twig_Filter('accFirst', 'accFirst'));
  8. $sentence = 'šumivé víno';
  9. echo $twig->render('customfilter.html.twig',
  10. ['sentence' => $sentence]);
  11. function accFirst($value, $encoding = 'UTF8')
  12. {
  13. $strlen = mb_strlen($value, $encoding);
  14. $firstChar = mb_substr($value, 0, 1, $encoding);
  15. $rest = mb_substr($value, 1, $strlen - 1, $encoding);
  16. return mb_strtoupper($firstChar, $encoding) . $rest;
  17. }

我们添加了一个名为accFirst的新过滤器。 它仅修改第一个字母,也可以处理重音。

templates/customfilter.html.twig

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Custom filter</title>
  7. </head>
  8. <body>
  9. <p>
  10. {{ sentence | accFirst }}
  11. </p>
  12. </body>
  13. </html>

这是模板文件,使用自定义accFirst过滤器。

Twig 循环

要创建循环,我们使用for标签。

looping.php

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. use Twig\Environment;
  4. use Twig\Loader\FilesystemLoader;
  5. $loader = new FilesystemLoader(__DIR__ . '/templates');
  6. $twig = new Environment($loader);
  7. $words = ['sky', 'mountain', 'falcon', 'forest',
  8. 'rock', 'blue', 'solid', 'book', 'tree'];
  9. echo $twig->render('words.html.twig', ['words' => $words]);

我们将循环一个单词数组。

templates/words.html.twig

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Words</title>
  7. </head>
  8. <body>
  9. <ul>
  10. {% for word in words %}
  11. <li>{{ word }}</li>
  12. {% endfor %}
  13. </ul>
  14. <ul>
  15. {% for word in words|slice(2, 4) %}
  16. <li>{{ word }}</li>
  17. {% endfor %}
  18. </ul>
  19. </body>
  20. </html>

在模板文件中,我们遍历words数组并生成 HTML 列表。 使用slice()过滤器,我们可以遍历数组的一部分。

Twig 循环和if else

我们可以将for标签与if标签和else标签结合在一起。

looping2.php

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. use Twig\Environment;
  4. use Twig\Loader\FilesystemLoader;
  5. $loader = new FilesystemLoader(__DIR__ . '/templates');
  6. $twig = new Environment($loader);
  7. $users = [
  8. ['name' => 'John Doe', 'active' => false],
  9. ['name' => 'Lucy Smith', 'active' => false],
  10. ['name' => 'Peter Holcombe', 'active' => false],
  11. ['name' => 'Barry Collins', 'active' => false]
  12. ];
  13. echo $twig->render('activeusers.html.twig', ['users' => $users]);

我们向模板文件发送用户数组。

templates/activeusers.html.twig

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. <p>Active users</p>
  10. <ul>
  11. {% for user in users if user.active %}
  12. <li>{{ user.name }}</li>
  13. {% else %}
  14. <li>No users found</li>
  15. {% endfor %}
  16. </ul>
  17. </body>
  18. </html>

我们输出的用户名称user.active属性为true。 当没有活动用户时,将显示else标记的输出。

Twig set标签

set标签允许将值设置为模板内的变量。

  1. $words = ['sky', 'mountain', 'falcon', 'forest',
  2. 'rock', 'blue', 'solid', 'book', 'tree'];
  3. echo $twig->render('test.html.twig', ['words' => $words]);

我们有一个单词表。

  1. {% set sorted = words | sort %}
  2. <ul>
  3. {% for word in sorted %}
  4. <li>{{ word }}</li>
  5. {% endfor %}
  6. </ul>

我们使用sort过滤器对数组进行排序,并使用set将排序后的数组分配给sorted变量。

Twig verbatim标签

verbatim将部分标记为不应该分析的原始文本。

  1. {% verbatim %}
  2. <ul>
  3. {% for word in words %}
  4. <li>{{ word }}</li>
  5. {% endfor %}
  6. </ul>
  7. {% endverbatim %}

例如,如果我们有一个讲解 Twig 标签的教程,则无需分析一部分演示。

Twig 格式过滤器

format过滤器通过替换占位符来格式化给定的字符串。 它的作用类似于sprintf()函数。

  1. $name = "John Doe";
  2. $age = 34;
  3. echo $twig->render('formatfil.html.twig', ['name' => $name, 'age' => $age]);

我们向模板发送两个变量。

  1. {{ "%s is %d years old" | format(name, age) }}

我们使用format构建字符串。

Twig 日期函数

date()函数将参数转换为日期以允许进行日期比较。

  1. $user = ['name' => 'John Doe', 'created_at' => '2011/11/10'];
  2. echo $twig->render('datefun.html.twig', ['user' => $user]);

用户数组具有created_at键。

  1. {% if date(user.created_at) < date('-5years') %}
  2. <p>{{ user.name }} is a senior user</p>
  3. {% endif %}

在模板中,我们比较两个日期。

Twig 自动转义

Twig 自动转义某些字符,例如<>

  1. $twig = new Environment($loader, [
  2. 'autoescape' => false
  3. ]);

可以使用autoescape选项关闭自动转义。

  1. $data = "<script src='http::/example.com/nastyscript.js'></script>";
  2. echo $twig->render('autoescape.html.twig', ['data' => $data]);

用户可能会有意向应用添加危险的输入。 通过自动转义可以防止包含未知的 JS 文件。

  1. <p>
  2. The data is {{ data }}
  3. </p>
  4. <p>
  5. The data is {{ data | raw }}
  6. </p>

如果启用了自动转义,我们可以使用raw过滤器显示原始输入。

  1. <p>
  2. The data is <script src="http:/example.com/nastyscript.js"></script>
  3. </p>
  4. <p>
  5. The data is <script src='http:/example.com/nastyscript.js'></script>
  6. </p>

此部分输出显示字符如何转义。

Twig 测试

Twig 测试允许测试数据。 使用is运算符进行测试。

  1. $words = ['', null, 'rock', ' ', 'forest'];
  2. echo $twig->render('tests.html.twig', ['words' => $words]);

我们有一个包含空,空和空白元素的单词数组。

  1. <ul>
  2. {% for word in words %}
  3. {% if word is null %}
  4. <p>null element</p>
  5. {% elseif word | trim is empty %}
  6. <p>Empty element</p>
  7. {% else %}
  8. <li>{{ word }}</li>
  9. {% endif %}
  10. {% endfor %}
  11. </ul>

为了处理空,空和空元素,Twig 进行了emptynull测试。

Twig 继承

Twig 的模板继承是一项强大的函数,可消除重复并促进维护。

inheritance.php

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. use Twig\Environment;
  4. use Twig\Loader\FilesystemLoader;
  5. $loader = new FilesystemLoader(__DIR__ . '/templates');
  6. $twig = new Environment($loader);
  7. echo $twig->render('derived.html.twig');

这是inheritance.php文件。 它呈现derived.html.twig,它从base.html.twig扩展。

templates/base.html.twig

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>{% block title %}{% endblock %}</title>
  7. </head>
  8. <body>
  9. {% block body %}{% endblock %}
  10. </body>
  11. </html>

基本布局定义了两个由子代替换的块:titlebody

templates/derived.html.twig

  1. {% extends 'base.html.twig' %}
  2. {% block title %}Some title{% endblock %}
  3. {% block body %}
  4. The body contents
  5. {% endblock %}

派生的子模板使用extends关键字从基本模板继承。 这两个块定义了自定义文本。

  1. $ php inheritance.php
  2. <!DOCTYPE html><html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Some title</title>
  7. </head>
  8. <body>
  9. The body contents
  10. </body>
  11. </html>

This is the output.

Symfony 的例子

Twig 是 Symfony 框架的组成部分。 下一个示例显示在 Symfony 骨架应用中使用 Twig 的步骤。

  1. $ composer create-project symfony/skeleton simple
  2. $ cd simple

我们创建一个新的 Symfony 框架应用,然后移至项目目录。

  1. $ composer require server --dev

我们包括开发服务器。

  1. $ composer require maker annotations twig

我们包括一些基本的 Symfony 组件,包括 Twig。

  1. $ php bin/console make:controller HomeController

我们创建一个家庭控制器。

src/Controller/HomeController.php

  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\Routing\Annotation\Route;
  5. class HomeController extends AbstractController
  6. {
  7. /**
  8. * @Route("/home", name="home")
  9. */
  10. public function index()
  11. {
  12. $words = ['sky', 'blue', 'cloud', 'symfony', 'forest'];
  13. return $this->render('home/index.html.twig', [
  14. 'words' => $words
  15. ]);
  16. }
  17. }

在家庭控制器中,我们渲染index.html.twig模板,并将其传递给$words数组进行处理。

templates/base.html.twig

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>{% block title %}Welcome!{% endblock %}</title>
  6. {% block stylesheets %}{% endblock %}
  7. </head>
  8. <body>
  9. {% block body %}{% endblock %}
  10. {% block javascripts %}{% endblock %}
  11. </body>
  12. </html>

这是基本布局页面。

templates/home/index.html.twig

  1. {% extends 'base.html.twig' %}
  2. {% block title %}Home page{% endblock %}
  3. {% block body %}
  4. <h2>List of words</h2>
  5. <ul>
  6. {% for word in words %}
  7. <li>{{ word }}</li>
  8. {% endfor %}
  9. </ul>
  10. {% endblock %}

这是主页模板。 它使用for标记遍历单词,然后将它们输出到无序列表中。

  1. $ php bin/console server:run

我们启动服务器。

我们导航到http://localhost:8000/home以查看结果。

在本教程中,我们使用了 Twig 从模板和数据生成文档。 我们介绍了 Twig 标签,过滤器,测试和继承。 我们在 Symfony 应用中显示了 Twing。

您可能也对以下相关教程感兴趣: PHP Faker 教程Respect 验证教程Symfony 入门Rakit 验证教程PHP PDO 教程PHP 教程

{% endraw %}