Twig:一款流行的PHP模板引擎
Twig是由Sensio Labs开发的PHP流行模板引擎,它简化了PHP代码,并增加了安全和调试等功能。Twig同时作用于项目的frontend和backend,可以从两个角度来看:模板设计师的Twig和开发者的Twig。Twig使用名为Environment
的核心对象来存储配置、扩展,并从文件系统或其他位置加载模板。Twig支持嵌套模板(块),避免模板中元素重复,并能缓存编译后的模板以加快后续请求速度。Twig支持条件语句、循环和过滤器来控制模板中信息的显示,并提供调试功能来转储模板变量的所有信息。
本文由Wern Ancheta同行评审。感谢所有SitePoint的同行评审员,使SitePoint的内容达到最佳状态!
Twig是PHP的模板引擎。但是,PHP本身不是模板引擎吗?是的,也不是!尽管PHP最初是作为模板引擎,但它的发展并非如此,虽然我们仍然可以将其用作模板引擎,请问您更喜欢哪个版本的“Hello world”:
<code class="language-php"><?php echo "<p> Hello " . $name . "</p>"; ?></code>
还是
<code class="language-twig"><p>Hello {{ name }}</p></code>
PHP是一种冗长的语言,在尝试输出HTML内容时,这种冗长性会被放大。现代模板系统将消除部分冗长性,并在其之上增加相当多的功能。诸如安全和调试功能之类的特性是现代模板引擎的支柱。今天,我们将重点介绍Twig。
Twig是由Sensio Labs(Blackfire和Symfony的开发公司)创建的模板引擎。让我们来看看它的主要优势以及如何在项目中使用它。
安装
安装Twig有两种方法。我们可以使用其网站上提供的tar包,或者像我们一直做的那样,使用Composer。
<code class="language-bash">composer require twig/twig</code>
我们假设您正在运行已设置PHP并全局安装Composer的环境。最好的方法是使用Homestead Improved——它可以让您在5分钟内在与我们使用的完全相同的机器上开始使用,这样我们就能在同一页面上。如果您想了解有关PHP环境的更多信息,我们这里有一本关于此的优秀付费书籍可供购买。
在我们继续之前,我们需要先澄清一些事情。作为模板引擎,Twig同时作用于项目的frontend和backend。因此,我们可以从两个不同的角度来看待Twig:模板设计师的Twig和开发者的Twig。一方面,我们准备所有需要的数据;另一方面,我们呈现所有这些数据。
基本用法
为了举例说明Twig的基本用法,让我们创建一个简单的项目。首先,我们需要引导Twig。让我们创建一个包含以下内容的bootstrap.php
文件:
<code class="language-php"><?php echo "<p> Hello " . $name . "</p>"; ?></code>
Twig使用名为Environment
的核心对象。此类的实例用于存储配置、扩展,并从文件系统或其他位置加载模板。在我们的Twig实例引导后,我们可以继续创建一个index.php
文件,在其中加载一些数据并将其传递给Twig模板。
<code class="language-twig"><p>Hello {{ name }}</p></code>
这是一个简单的示例;我们正在创建一个包含产品的数组,例如我们的机械键盘,我们可以在模板中使用它。然后,我们使用render()
方法,它接受模板名称(这是我们之前定义的模板文件夹中的一个文件)以及我们要传递给模板的数据。为了完成我们的示例,让我们进入我们的/templates
文件夹并创建一个index.html
文件。首先,让我们看看模板本身。
<code class="language-bash">composer require twig/twig</code>
在浏览器中打开index.php
(访问localhost或homestead.app,具体取决于您如何设置主机和服务器)现在应该会显示以下屏幕:
但是让我们回到并仔细看看我们的模板代码。有两种类型的分隔符:{{ ... }}
用于打印表达式或操作的结果,而{% ... %}
用于执行诸如条件语句和循环之类的语句。这些分隔符是Twig的主要语言结构,Twig使用它们来“告知”模板它必须呈现Twig元素。
(以下内容与原文类似,但做了部分语句调整和段落划分,并保持了图片位置不变)
布局
为了避免在模板中重复元素(如页眉和页脚),Twig允许我们将模板嵌套在模板中,这些被称为块。为了举例说明这一点,让我们将实际内容与示例中的HTML定义分开。让我们创建一个新的HTML文件并将其命名为layout.html
:
<code class="language-php"><?php // 加载我们的自动加载器 require_once __DIR__.'/vendor/autoload.php'; // 指定我们的Twig模板位置 $loader = new Twig_Loader_Filesystem(__DIR__.'/templates'); // 实例化我们的Twig $twig = new Twig_Environment($loader);</code>
我们创建了一个名为content
的块。我们的意思是,每个从layout.html
扩展的模板都可以实现一个content
块,该块将显示在该位置。这样,我们可以多次重用布局而无需重写它。在本例中,index.html
文件现在如下所示:
<code class="language-php"><?php require_once __DIR__.'/bootstrap.php'; // 创建产品列表 $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', ], ]; // 渲染我们的视图 echo $twig->render('index.html', ['products' => $products] );</code>
Twig还允许我们只渲染单个块。为此,我们需要首先加载模板,然后渲染块。
<code class="language-html"><!DOCTYPE html> <meta charset="UTF-8"> <title>Twig Example</title> <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> </code>
此时,我们仍然拥有相同的页面,但我们通过分离上下文块来降低了它的复杂性。
缓存
Environment
对象不仅可以用于加载模板。如果我们使用关联目录的cache
选项传递,Twig将缓存编译后的模板,从而避免在后续请求中解析模板。编译后的模板将存储在我们提供的目录中。请注意,这是编译模板的缓存,而不是已评估的模板的缓存。这意味着Twig将解析、编译并保存模板文件。所有后续请求仍然需要评估模板,但第一步已经为您完成。让我们通过编辑bootstrap.php
文件来缓存示例中的模板:
<code class="language-php"><?php echo "<p> Hello " . $name . "</p>"; ?></code>
(以下内容与原文类似,但做了部分语句调整和段落划分,并保持了图片位置不变)
循环
在我们的示例中,我们已经看到了如何使用Twig进行循环。基本上,我们使用for
标签并为指定数组中的每个元素分配一个别名。在本例中,我们为products
数组分配了别名product
。之后,我们可以使用.
运算符访问每个数组元素中的所有属性。我们使用endfor
标签来指示循环的结束。我们还可以使用..
运算符循环遍历数字或字母。如下所示:
<code class="language-twig"><p>Hello {{ name }}</p></code>
或字母:
<code class="language-bash">composer require twig/twig</code>
此运算符只是range
函数的语法糖,其工作方式与本机PHPrange
函数相同。同样有用的选项是向循环添加条件。使用条件,我们可以过滤要迭代的元素。假设我们想要迭代所有值小于250的产品:
<code class="language-php"><?php // 加载我们的自动加载器 require_once __DIR__.'/vendor/autoload.php'; // 指定我们的Twig模板位置 $loader = new Twig_Loader_Filesystem(__DIR__.'/templates'); // 实例化我们的Twig $twig = new Twig_Environment($loader);</code>
条件语句
Twig还以if
、elseif
、if not
和else
标签的形式提供条件语句。就像在任何编程语言中一样,我们可以使用这些标签来过滤模板中的条件。假设在我们的示例中,我们只想显示值高于500的产品:
<code class="language-php"><?php require_once __DIR__.'/bootstrap.php'; // 创建产品列表 $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', ], ]; // 渲染我们的视图 echo $twig->render('index.html', ['products' => $products] );</code>
过滤器
过滤器允许我们过滤传递给模板的信息以及显示信息的格式。让我们看看一些最常用和最重要的过滤器。Twig过滤器的完整列表可以在这里找到。
date_modify
date
过滤器将日期格式化为给定格式。正如我们在示例中看到的:
<code class="language-html"><!DOCTYPE html> <meta charset="UTF-8"> <title>Twig Example</title> <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> </code>
我们以月/日/年的格式显示日期。除了date
过滤器之外,我们还可以使用修饰符字符串使用date_modify
过滤器更改日期。例如,如果我们想向日期添加一天,我们可以使用以下内容:
<code class="language-html"><!DOCTYPE html> <meta charset="UTF-8"> <title>Tutorial Example</title> {% block content %} {% endblock %} </code>
format
通过替换所有占位符来格式化给定字符串。例如:
<code class="language-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 %}</code>
striptags
striptags
过滤器去除SGML/XML标签,并将相邻的空格替换为空格:
<code class="language-php"><?php echo "<p> Hello " . $name . "</p>"; ?></code>
escape
escape
是最重要的过滤器之一。它过滤字符串以安全地插入最终输出中。默认情况下,它使用HTML转义策略,因此
<code class="language-twig"><p>Hello {{ name }}</p></code>
等效于
<code class="language-bash">composer require twig/twig</code>
js
、css
、url
和html_attr
转义策略也可使用。它们分别为Javascript、CSS、URI和HTML属性上下文转义字符串。
调试
最后,让我们来看看调试。有时我们需要访问模板变量的所有信息。为此,Twig具有dump()
函数。此函数默认情况下不可用。在创建Twig环境时,我们必须添加Twig_Extension_Debug
扩展:
<code class="language-php"><?php // 加载我们的自动加载器 require_once __DIR__.'/vendor/autoload.php'; // 指定我们的Twig模板位置 $loader = new Twig_Loader_Filesystem(__DIR__.'/templates'); // 实例化我们的Twig $twig = new Twig_Environment($loader);</code>
此步骤是必要的,这样我们才不会意外地在生产服务器上泄露调试信息。配置完成后,我们只需使用dump()
函数即可转储有关模板变量的所有信息。
<code class="language-php"><?php require_once __DIR__.'/bootstrap.php'; // 创建产品列表 $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', ], ]; // 渲染我们的视图 echo $twig->render('index.html', ['products' => $products] );</code>
结论
希望本文能为您提供Twig基础知识的坚实基础,并立即启动您的项目!如果您想更深入地了解Twig,官方网站提供了您可以查阅的非常好的文档和参考。您使用模板引擎吗?您对Twig有什么看法?您会将它与Blade或Smarty等流行的替代方案进行比较吗?
(以下内容为FAQ,原文已包含,此处略去)
以上是树枝 - 最受欢迎的独立PHP模板引擎的详细内容。更多信息请关注PHP中文网其他相关文章!