+8613426109659
webmaster@21cto.com

Twig——最受欢迎的独立 PHP 模板引擎

资讯 0 8945 2018-12-01 11:57:06

图片


本文关键要点


  • Twig 是一个流行的 PHP 模板引擎,由 Sensio Labs 开发,它提供了一种消除 PHP 冗长性并添加安全性和调试功能等功能的方法。
  • Twig 在项目的前端和后端运行,可以从两个角度来看:Twig 适用于模板设计人员,Twig 适用于开发人员。
  • Twig 使用一个名为 Environment 的中心对象来存储配置、扩展,并从文件系统或其他位置加载模板。
  • Twig 提供了在模板内部嵌套模板(称为块)的功能,以避免模板中元素的重复,还提供了缓存已编译模板的功能,以便更快地进行后续请求。
  • Twig 支持条件、循环和过滤器来控制模板中信息的显示,并提供调试功能来转储有关模板变量的所有信息。

Twig 是 PHP 的一个模板引擎。但是 ,PHP 本身不就是一个模板引擎吗?

是也不是!

尽管 PHP 最初也是一个模板引擎,但它并没有像模板引擎那样发展,虽然我们仍然可以使用它,但请告诉我你更喜欢哪个版本的“Hello world”:

<?php echo "<p> Hello " . $name "</p>"?>

或者:

<p> Hello {{ name }} </p>

PHP 是一种“冗长”的语言,当尝试输出 HTML 内容时,这种特性会被放大。

现代模板系统会去掉一些冗长的代码,同时仍然添加相当一部分功能。安全和调试等功能是现代模板引擎的支柱。

今天,我们来重点关注 Twig。

Twig 是由Sensio Labs(Blackfire和 Symfony背后的科技公司)创建的模板引擎。让我们来看看它的主要优势以及如何在项目中使用它。

安装


安装 Twig 有两种方法。我们可以使用他们网站上提供的 tar 包,也可以使用Composer,就像我们一直推荐的那样。

composer require twig/twig

我们假设您运行的环境已设置好 PHP 并全局安装了Composer

最佳选择项是使用Homestead Improved,它可以让您在与我们完全相同的机器上 5 分钟内上手,因此我们都能保持一致。

在我们继续之前,我们需要先澄清一些事情。

作为模板引擎,Twig 既可以在项目的前端运行,也可以在项目的后端运行。因此,我们可以从两个不同的角度来看待 Twig:面向模板设计人员的 Twig 和面向开发人员的 Twig。

一方面,我们准备好所有需要的数据,然后渲染所有数据。

基本用法


为了演示 Twig 的基本用法,我们来创建一个简单的项目。首先,我们需要引导 Twig。

创建一个bootstrap.php包含以下内容的文件:

<?php
// Load our autoloaderrequire_once __DIR__.'/vendor/autoload.php';
// Specify our Twig templates location$loader new Twig_Loader_Filesystem(__DIR__.'/templates');
 // Instantiate our Twig$twig new Twig_Environment($loader);

Twig 使用一个名为中心对象的环境(Environment)。该类的实例用于存储配置、扩展以及从文件系统或其他位置加载模板。

随着我们的 Twig 实例引导,可以继续创建一个index.php文件,下面将在其中加载一些数据并将其传递给 Twig 模板。


<?php
require_once __DIR__.'/bootstrap.php';
// Create a product list$products = [    [        'name'          => 'Notebook',        'description'   => 'Core i7',        'value'         =>  800.00,        'date_register' => '2017-06-22',    ],    [        'name'          => 'Mouse',        'description'   => 'Razer',        'value'         =>  125.00,        'date_register' => '2017-10-25',    ],    [        'name'          => 'Keyboard',        'description'   => 'Mechanical Keyboard',        'value'         =>  250.00,        'date_register' => '2017-06-23',    ],];
// Render our viewecho $twig->render('index.html', ['products' => $products] );

以下是一个简单的代码例子:

我们创建一个包含产品(例如机械键盘)的数组,以便在模板中使用。然后,我们使用一个render()渲染方法,它接受一个模板名称(这是我们之前定义的模板文件夹中的一个文件)以及我们想要传递给模板的数据。

为了完成我们的示例,让我们进入/templates文件夹并创建一个index.html文件。首先,让我们看一下模板本身。

<!DOCTYPE html><html lang="zh-CN">    <head>        <meta charset="UTF-8">        <title>Twig Example</title>    </head>    <body>    <table border="1" style="width: 80%;">        <thead>            <tr>                <td>Product</td>                <td>Description</td>                <td>Value</td>                <td>Date</td>            </tr>        </thead>        <tbody>            {% for product in products %}                <tr>                    <td>{{ product.name }}</td>                    <td>{{ product.description }}</td>                    <td>{{ product.value }}</td>                    <td>{{ product.date_register|date("m/d/Y") }}</td>                </tr>            {% endfor %}        </tbody>    </table>    </body></html>

在浏览器中打开index.php(通过访问localhosthomestead.app,取决于你如何设置主机和服务器),现在应该会产生以下的画面:

图片

但是让我们回过头来仔细看看模板代码。

有两种类型的分隔符:{{ ... }}用于打印表达式或运算的结果,以及{% ... %}用于执行条件语句和循环语句。这些分隔符是 Twig 的主要语言结构,Twig 用它来“通知”模板需要渲染一个 Twig 元素。

布局


为了避免模板中元素(如页眉和页脚)的重复,Twig 提供了在模板中嵌套模板的功能。这些被称为

为了举例说明,我们将示例中的实际内容与 HTML 定义分开。创建一个新的 HTML 文件并将其命名为layout.html


<!DOCTYPE html><html lang="zh-CN">    <head>        <meta charset="UTF-8">        <title>Tutorial Example</title>    </head>    <body>        {% block content %}        {% endblock %}    </body></html>

我们创建了一个名为content的文件块。也就是说,每个从 扩展的模板layout.html都可以实现一个content将显示在该位置的文件块。这样,我们可以多次重用该布局,而无需反复重写它。

在我们的例子中,index.html文件现在如下所示:


{% extends "layout.html" %}
{% block content %}    <table border="1" style="width: 80%;">        <thead>            <tr>                <td>Product</td>                <td>Description</td>                <td>Value</td>                <td>Date</td>            </tr>        </thead>        <tbody>            {% for product in products %}                <tr>                    <td>{{ product.name }}</td>                    <td>{{ product.description }}</td>                    <td>{{ product.value }}</td>                    <td>{{ product.date_register|date("m/d/Y") }}</td>                </tr>            {% endfor %}        </tbody>    </table>{% endblock %}

Twig 还允许我们只渲染单个块。为此,我们需要先加载模板,然后渲染该块。


$template $twig->load('index.html');echo $template->renderBlock('content'array('products' => $products));
此时,我们仍然拥有相同的页面,但我们通过分离上下文块来降低其复杂性。

缓存


Environment对象不仅仅可以用于加载模板。


如果我们传递一个与目录关联的cache选项,Twig 将缓存已编译的模板,从而避免在后续请求中再次解析模板。已编译的模板将存储在我们提供的目录中。


请注意,这是已编译模板的缓存,而不是已执行模板的缓存。这意味着 Twig 将解析、编译并保存模板文件。所有后续请求仍然需要执行模板,但第一步已经为你完成了。


让我们通过编辑文件来缓存示例中的模板bootstrap.php

$twig new Twig_Environment($loader, ['cache' => '/templates/cache']);

循环


在示例中,我们已经了解了如何使用 Twig 进行循环,我们使用标签并为指定数组中的每个元素分配一个别名。在本例中,我们为数组for分配了别名。之后可使用运算符访问每个数组元素中的所有属性


我们使用标签来指示循环的结束。

{% for number in 0..100 %}     {{ number }}{% endfor %}

我们还可以使用运算符循环遍历数字或字母。如下代码所示:


{% for number in 0..100 %}     {{ number }}{% endfor %}

或者使用字母:


{% for letter in 'a'..'z' %}     {{ letter }}{% endfor %}

此运算符可以算是range函数的语法糖

向循环添加条件也很有用。通过条件,我们可以过滤要迭代的元素。下面的例子假设要迭代所有价格小于 250 的商品:


<tbody>    {% for product in products if product.value < 250 %}        <tr>            <td>{{ product.name }}</td>            <td>{{ product.description }}</td>            <td>{{ product.value }}</td>            <td>{{ product.date_register|date("m/d/Y") }}</td>    </tr>    {% endfor %}</tbody>

条件语句


ifTwig 还以标签、elseifif not的形式为我们提供了条件else。就像在任何编程语言中一样,我们可以使用这些标签来过滤模板中的条件。

在下面的例子中,我们想显示价值高于 500 的产品。


<tbody>    {% for product in products %}    {% if product.value > 500 %}                <tr>                    <td>{{ product.name }}</td>                    <td>{{ product.description }}</td>                    <td>{{ product.value }}</td>                    <td>{{ product.date_register|date("m/d/Y") }}</td>        </tr>    {% endif %}    {% endfor %}</tbody>

Filter 过滤器


过滤器允许我们过滤传递给模板的信息以及其显示格式。让我们来看看一些最常用和最重要的过滤器。(Twig 过滤器的完整列表请见:https://twig.sensiolabs.org/doc/2.x/filters/index.html)

date 和 date_modify


date过滤器将日期格式化为给定的格式。如我们在示例中所见:


<td>{{ product.date_register|date("m/d/Y") }}</td>
我们正在以某种格式显示日期month/day/year

除了date过滤器之外,我们还可以使用过滤器中的修饰符字符串来更改日期,这就需要动用 date_modify了

例如,如果我们想在日期中添加一天,可以使用以下命令:

<td>{{ product.date_register|date_modify("+1 day")|date("m/d/Y") }}</td>

Format 格式化


通过替换所有占位符来格式化给定的字符串。例如:

<td>{{ "This product description is: %s"|format(product.description) }}</td>
striptags 标签

striptags过滤器会帮助我们删除 SGML/XML 标签,并将相邻的空格替换为一个空格。如下例:

{{ <p>Hello World</p>|striptags }}

Esape 标签


Escape 是最重要的过滤器之一。它过滤字符串以便安全地插入到最终输出中。默认情况下,它使用 HTML 转义策略。因此:


{{ products.description|escape }}

相当于

{{ products.description|escape('html') }}

j转义策略对于js和CSS可用。它们分别针对 Javascript、CSS、URI 和 HTML 属性上下文对字符串进行转义。

调试


最后,我们来看看调试。

有时我们需要访问模板变量的所有信息。为此,Twig 提供了以下dump()函数。默认情况下,此功能不可用。

我们必须使用Twig_Extension_Debug在创建 Twig 环境时添加扩展:


$twig new Twig_Environment($loaderarray('debug' => true));$twig->addExtension(new Twig_Extension_Debug());

这一步是必要的,这样我们就不会在生产服务器上意外泄露调试信息。配置完成后,我们可以使用该dump()函数转储有关模板变量的所有信息。

{{ dump(products) }}

结语


希望本文能帮助各位开发扎实掌握 Twig 的基础知识,并帮你立即开展项目!


你使用模板引擎吗?觉得 Twig 怎么样?你会把它和 Blade 甚至 Smarty 等流行的替代品进行比较吗?欢迎留言!

作者:场长

评论

我要赞赏作者

请扫描二维码,使用微信支付哦。