twig 模板引擎

tech2022-08-23  138

twig 模板引擎

This article was peer reviewed by Wern Ancheta. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

本文由Wern Ancheta进行同行评审。 感谢所有SitePoint的同行评审人员使SitePoint内容达到最佳状态!



Twig is a template engine for PHP. But isn’t PHP itself a template engine?

Twig是PHP的模板引擎。 但是PHP本身不是模板引擎吗?

Yes and no!

是的,没有!

Even though PHP started as a template engine, it didn’t evolve like one, and while we can still use it as one please tell me which version of “Hello world” you prefer:

尽管PHP是从模板引擎开始的,但它并没有像现在那样发展,尽管我们仍然可以将其作为模板引擎使用,但请告诉我您喜欢哪种版本的“ Hello world”:

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

or

要么

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

PHP is a verbose language, and that verbosity is amplified when trying to output HTML content.

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

Modern template systems will take away some of that verbosity and still add a fair share of functionality on top. Things like security and debug features are mainstays in modern template engines.

现代模板系统将消除一些冗长的细节,并且仍然在其顶部添加相当一部分的功能。 安全性和调试功能是现代模板引擎中的主流。

Today, we’re focusing on Twig.

今天,我们专注于Twig。

Twig is a template engine created by Sensio labs, the company behind Blackfire and Symfony. Let’s take a look at its main strengths and how can we use it in our projects.

特威格是创建一个模板引擎Sensio公司的实验室 ,公司背后Blackfire和Symfony的。 让我们看一下它的主要优势以及如何在项目中使用它。

安装 (Installation)

There are two ways of installing Twig. We can use the tar ball available on their website, or we can use Composer, just like we always do and recommend.

有两种安装Twig的方法。 我们可以使用其网站上的tar球,也可以使用Composer ,就像我们一如既往并推荐这样做。

composer require twig/twig

We’re assuming you’re running an environment with PHP set up and Composer globally installed. Your best bet is using Homestead Improved – it’ll let you get started in 5 minutes on the exact same machine we’re using, so we’re all on the same page. If you’d like to learn more about PHP Environments, we have an excellent premium book about that available for purchase here.

我们假设您正在运行一个安装了PHP且已全局安装Composer的环境。 最好的选择是使用Homestead Enhanced –它可以让您在5分钟内开始使用与我们使用的完全相同的计算机,因此我们都在同一页面上。 如果您想了解有关PHP环境的更多信息,我们可以在此处购买有关这本优秀的高级书籍。

Before we go any further, there’s something we need to clarify first.

在继续进行之前,我们需要先进行澄清。

As a template engine, Twig operates both on the front and on the back end of a project. Because of that, we can look at Twig in two different ways: Twig for template designers and Twig for developers.

作为模板引擎,Twig在项目的前端和后端均运行。 因此,我们可以用两种不同的方式来看待Twig:用于模板设计师的Twig和用于开发人员的Twig。

On one side, we prepare all data we need. On the other side, we render all that data.

一方面,我们准备了所需的所有数据。 另一方面,我们渲染所有数据。

基本用法 (Basic Usage)

To exemplify the basic usage of Twig, let’s create a simple project. First of all, we need to bootstrap Twig. Let’s create a bootstrap.php file with the following content:

为了说明Twig的基本用法,我们创建一个简单的项目。 首先,我们需要引导Twig。 让我们创建一个具有以下内容的bootstrap.php文件:

<?php // Load our autoloader require_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 uses a central object called Environment. Instances of this class are used to store the configuration, extensions, and to load templates from the file system or other locations.

Twig使用了一个称为Environment的中心对象。 此类的实例用于存储配置,扩展和从文件系统或其他位置加载模板。

With our Twig instance bootstrapped, we can go on and create an index.php file where we will load some data and pass it to a Twig template.

自举启动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 view echo $twig->render('index.html', ['products' => $products] );

This is a simple example; we are creating an array of products that we can use in our template. Then, we use the render() method which accepts a template name (this is a file inside the template folder that we defined earlier) and the data that we want to pass to the template.

这是一个简单的例子。 我们正在创建可以在模板中使用的一系列产品。 然后,我们使用render()方法,该方法接受模板名称(这是我们之前定义的模板文件夹中的文件)以及要传递给模板的数据。

To complete our example, let’s go inside our /templates folder and create an index.html file. First, let’s take a look at the template itself.

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

<!DOCTYPE html> <html lang="pt-BR"> <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>

Opening index.php in the browser (by visiting localhost or homestead.app, depending on how you’ve set up your hosts and server) should produce the following screen now:

在浏览器中打开index.php (通过访问localhost或homestead.app ,具体取决于您如何设置主机和服务器)现在应该显示以下屏幕:

But let’s go back and take a closer look at our template code.

但是,让我们回头仔细看看我们的模板代码。

There are two types of delimiters: {{ ... }} is used to print the result of an expression or an operation and {% ... %} is used to execute statements like conditionals and loops. These delimiters are Twig’s main language constructs, and are what Twig uses to “inform” the template that it has to render a Twig element.

分隔符有两种类型: {{ ... }}用于打印表达式或操作的结果, {% ... %}用于执行条件语句和循环之类的语句。 这些定界符是Twig的主要语言构造,也是Twig用来“通知”模板它必须呈现Twig元素的工具。

版面 (Layouts)

In order to avoid the repetition of elements (like headers and footers) in our templates, Twig offers us the ability to nest templates inside of templates. These are called blocks.

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

To exemplify this, let’s separate actual content from the HTML definition in our example. Let’s create a new HTML file and call it layout.html:

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

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

We created a block called content. What we are saying is that every template that extends from layout.html may implement a content block that will be displayed in that position. This way we can reuse the layout multiple times without having to rewrite it. In our case, the index.html file will now look like this:

我们创建了一个名为content的块。 我们的意思是,每个从layout.html扩展的模板都可以实现一个content块,该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 also allows us to render just a single block. To do that we need to first load a template and then render the block.

Twig还​​允许我们仅渲染一个块。 为此,我们需要先加载模板,然后渲染块。

$template = $twig->load('index.html'); echo $template->renderBlock('content', array('products' => $products));

At this point, we still have the same page, but we reduced the complexity of it by separating contextual blocks.

此时,我们仍然拥有相同的页面,但是通过分离上下文块降低了页面的复杂性。

快取 (Cache)

The Environment object can be used for more than just loading templates.

Environment对象不仅可以用于加载模板,还可以用于其他用途。

If we pass the cache option with a directory associated, Twig will cache the compiled templates so it avoids the template parsing in subsequent requests. The compiled templates will be stored in the directory we provided. Be aware that this is a cache for compiled templates, not evaluated ones. What this mean is that Twig will parse, compile and save the template file. All subsequent requests will still need to evaluate the template, but the first step is already done for you.

如果我们通过带有关联目录的cache选项,Twig将缓存已编译的模板,从而避免了后续请求中的模板解析。 编译后的模板将存储在我们提供的目录中。 请注意,这是编译模板的缓存,而不是评估模板的缓存。 这意味着Twig将解析,编译和保存模板文件。 所有后续请求仍将需要评估模板,但是第一步已经为您完成。

Let’s cache the templates in our example by editing our bootstrap.php file:

通过编辑bootstrap.php文件,让我们在示例中缓存模板:

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

循环 (Loops)

In our example we’ve already seen how a loop is done using Twig. Basically, we use the for tag and assign an alias for each element in the specified array. In our case, we assigned the alias product for our products array. After that, we can access all the attributes in each array element by using the . operator. We use the endfor tag to indicate the end of our loop.

在我们的示例中,我们已经看到了如何使用Twig完成循环。 基本上,我们使用for标签,并为指定数组中的每个元素分配一个别名。 在本例中,我们为products数组分配了别名product 。 之后,我们可以使用来访问每个数组元素中的所有属性. 操作员。 我们使用endfor标记来指示循环的结束。

We can also loop through numbers or letters using the .. operator. Just like the following:

我们也可以使用..运算符循环显示数字或字母。 就像下面这样:

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

or for letters:

或字母:

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

This operator is just syntactic sugar for the range function which works just like the native PHP range function.

该运算符只是range函数的语法糖,其作用与本机PHP range函数类似。

Also useful is the option to add a condition to a loop. With a condition, we’re able to filter which elements we want to iterate through. Imagine we want to iterate through all products whose value is less than 250:

将条件添加到循环中的选项也很有用。 在有条件的情况下,我们能够过滤要迭代的元素。 假设我们要遍历所有价值小于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>

有条件的 (Conditionals)

Twig also offers us conditionals in the form of the tags if, elseif, if not, and else. Just like in any programming language, we can use these tags to filter for conditions in our template.

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

Imagine that, in our example, we only want to show products with a value above 500.

想象一下,在我们的示例中,我们只想显示价值大于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>

筛选器 (Filters)

Filters allow us to filter what information is passed to our template and in which format it is shown. Let’s look at some of the most used and important ones. The full list of Twig filters can be found here.

过滤器使我们能够过滤传递到模板的信息以及显示的格式。 让我们看一些最常用和最重要的。 Twig过滤器的完整列表可以在这里找到 。

日期和date_modify (Date and date_modify)

The date filter formats a date to a given format. As we can see in our example:

date过滤器将date格式化为给定格式。 正如我们在示例中看到的:

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

We are showing our date in a month/day/year format. On top of the date filter, we can change the date with a modifier string using the date_modify filter. For example, if we wanted to add a day to our date we could use the following:

我们以month/day/year格式显示日期。 在date过滤器的顶部,我们可以使用date_modify过滤器使用修饰符字符串更改日期。 例如,如果我们想为日期添加一天,则可以使用以下内容:

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

格式 (Format)

Formats a given string by replacing all the placeholders. For example:

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

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

剥离标签 (Striptags)

The striptags filter strips SGML/XML tags and replaces adjacent white space with one space:

striptags过滤器剥离SGML / XML标签,并用一个空格替换相邻的空白:

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

逃逸 (Escape)

Escape is one of the most important filters. It filters a string for safe insertion in the final output. By default, it uses the HTML escaping strategy, so

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

{{ products.description|escape }}

is equivalent to

相当于

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

The js, CSS, URL and html_attr escaping strategies are also available. They escape the string for the Javascript, CSS, URI and HTML attribute contexts respectively.

还提供了js , CSS , URL和html_attr转义策略。 它们分别对Javascript,CSS,URI和HTML属性上下文的字符串进行转义。

除错 (Debug)

Lastly, let’s take a look at debugging. Sometimes we need to access all the information on a template variable. For that effect Twig has the dump() function. This function is not available by default. We must add the Twig_Extension_Debug extension when creating our Twig environment:

最后,让我们看一下调试。 有时我们需要访问模板变量上的所有信息。 为此,Twig具有dump()函数。 默认情况下此功能不可用。 创建Twig环境时,必须添加Twig_Extension_Debug扩展:

$twig = new Twig_Environment($loader, array('debug' => true)); $twig->addExtension(new Twig_Extension_Debug());

This step is needed so we don’t accidentally leak debug information on a production server. After configuring it, we can just use the dump() function to dump all the information about a template variable.

此步骤是必需的,因此我们不会在生产服务器上意外泄漏调试信息。 配置它之后,我们可以只使用dump()函数来转储有关模板变量的所有信息。

{{ dump(products) }}

结论 (Conclusion)

Hopefully, this article can give you a solid base on the fundamentals of Twig, and get your projects started right away! If you want to go deeper into Twig, the official website offers a very good documentation and reference that you can consult.

希望本文能为您提供有关Twig基础知识的坚实基础,并立即开始您的项目! 如果您想更深入地了解Twig,可以在官方网站上找到很好的文档和参考资料 。

Do you use a template engine? What do you think of Twig? Would you compare it with popular alternatives like Blade, or even Smarty?

您是否使用模板引擎? 您如何看待Twig? 您可以将其与诸如Blade甚至Smarty的流行替代品进行比较吗?

翻译自: https://www.sitepoint.com/twig-popular-stand-alone-php-template-engine/

twig 模板引擎

最新回复(0)