php twig模板引擎详细使用教程

php twig模板引擎

1. 什么是Twig模板引擎

Twig是一个强大且灵活的PHP模板引擎,它提供了一种更简洁和可扩展的方法来创建PHP应用程序的视图层。Twig模板引擎旨在将设计与业务逻辑分离,并为开发人员提供一种更加清晰和易于维护的方式来构建网页。Twig由Symfony框架的开发团队开发,因此它与Symfony的组件非常兼容,并且被广泛用于Symfony应用程序中。

2. Twig的安装和配置

注意:PHP版本至少在 7.0.0以上

要使用Twig模板引擎,在你的PHP项目中需要先进行安装。可以使用Composer进行安装,执行以下命令:

composer require twig/twig

安装完成后,在你的PHP文件中引入Twig的自动加载文件:

require_once 'vendor/autoload.php';

2.1 phpstudy安装composer

注意:PHP版本至少在 7.0.0以上

笔者使用的是phpstudy安装twig,要先安装composer,phpstudy自带composer安装,可以自选一个版本安装
在这里插入图片描述

2.2 安装twig

在phpstudy中创建一个项目,就叫twig,然后右键项目,点击composer进入cmd界面

在这里插入图片描述

2.2.1 配置国内镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
2.2.2 更新composer
composer self-update
2.2.3 安装twig

输入安装twig命令
在这里插入图片描述

composer require twig/twig

看到项目中出现vendor,说明已经安装完成

在这里插入图片描述

3.hello world

在根目录twig下新建view文件夹,在view下新建cache和templates两个文件夹,在templates文件夹下新建一个hello.html文件,在根目录下新建入口文件index.php,文件内容如下:

hello.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>hello</title>
</head>
<body>
<h2>hello world! {{name}}</h2>
</body>
</html>

index.php

  • ./view/templates :为hello.html文件所在目录
  • ./view/cache : 为cache文件夹所在目录
<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, ['cache' => './view/cache','debug' => true,
]);echo $twig->render('hello.html',['name'=>'twig模板字符串']);

浏览器访问index.php,{{name}}能正常解析,说明成功运行!

4 变量

4.1 全局变量

以下变量总是在模板中可用:

  • _self:引用当前的模板名称;
  • _context:引用当前上下文;
  • _charset:引用当前的字符集。
<h2>hello world! {{name}}</h2>
<h2>全局变量:{{_self}}</h2>
<h2>全局变量:{{_context}}</h2>
<h2>全局变量:{{_charset}}</h2>

结果:

hello world! twig模板字符串
全局变量:hello.html
全局变量:Array
全局变量:UTF-8

4.2 修改变量

您可以为代码块中的变量赋值。使用set标签:

{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}

例如:

<h2>hello world! {{name}}</h2>
<p>{% set name = '修改后的name' %}</p>
<p>{{name}}</p>

浏览器输出:

hello world! twig模板字符串修改后的name

4.3 数组和对象变量

在根目录新建一个condition.php,内容如下:

<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, ['cache' => './view/cache','debug' => true,
]);$user = ['id' => 1,'name' => 'tom','age'=>18,'intro' => 'my name is tom','now' => date_format(new DateTime(),"Y/m/d H:i:s"),
];class tom {public  $is_login = true;public $sex = '男';public $name = 'tom';
}echo $twig->render('condition.twig',['user'=>$user,'tom'=>new tom()]);

在twig/view/templates下新建一个condition.twig模板文件,内容如下:

<p>{{ user['id'] }}</p>
<p>{{ user['name'] }}</p>
<p>{{ user['age'] }}</p>
<p>{{ user.intro }}</p>
<p>{{ user['now'] }}</p><h1>{{ tom.sex }}</h1>

访问condition.php,浏览器输出:

1tom18my name is tom2025/01/25 18:31:15
男

5 控制结构

Twig支持各种控制结构,如条件语句和循环语句。以下是一些示例:

5.1 条件语句

使用Twig的条件语句可以根据不同的条件选择性地渲染模板的一部分。
还是以condition.twig为例

<p>{{ user['id'] }}</p>
<p>{{ user['name'] }}</p>
<p>{{ user['age'] }}</p>
<p>{{ user.intro }}</p>
<p>{{ user['now'] }}</p><h1>{{ tom.sex }}</h1>{% if tom.is_login %}<p>Welcome, {{ tom.name }}!</p>
{% else %}<p>Please log in.</p>
{% endif %}

访问condition.php,浏览器输出:

1tom18my name is tom2025/01/25 18:39:40
男Welcome, tom!

Twig还支持使用elseif关键字来添加多个条件。

5.2 循环

<ul>{% for item in user %}<li>{{ item }} </li>{% endfor %}
</ul>

输出:

在这里插入图片描述

6 过滤器

变量可以通过过滤器来修改。通过管道符号(|)将过滤器与变量分隔开,在括号中可以有可选的参数。多个过滤器可以被链式。一个过滤器的输出应用于下一个过滤器。

本例新建./view/templates/filter.twig 和 ./filter.php

filter.php

<?phprequire_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, ['cache' => './view/cache','debug' => true,
]);$user = ['id' => 1,'name' => 'tom','age'=>18,'intro' => 'my name is tom','now' => date_format(new DateTime(),"Y/m/d H:i:s"),
];$filter = new \Twig\TwigFilter('ff', function ($number) {return $number . "我是过滤器";
});$twig->addFilter($filter);echo $twig->render('filter.twig',['user'=>$user]);

filter.twig

<p>{{ user.name }}</p>
<p>{{ user.name | ff }}</p>

其中的$number为传入的变量,即user.name

7 函数

函数的定义与过滤器完全相同,但您需要创建Twig_Function的一个实例:

可以调用函数来生成内容。函数由名称调用,后面是括号(()),可能有参数。
在filter.php中添加如下代码:

$function = new \Twig\TwigFunction('func', function ($number) {return $number."我是函数";
});
$twig->addFunction($function);

filter.twig

<p>{{ user.name }}</p>
<p>{{ user.name | ff }}</p>
<p>{{ func(user.name)}}</p>

输出结果:

tomtom我是过滤器tom我是函数

8 注解(Comments)

要在模板中引用一行,请使用注释语法{ #…# }。这对于调试或为其他模板设计人员或您自己添加信息非常有用:

{# note: disabled template because we no longer use this{% for user in users %}...{% endfor %}
#}

9 包括其他模板(Including other Templates)

include函数用于包含模板,并将该模板的呈现内容返回当前的模板

新建一个./view/templates/index.html,内容如下:

{{ include('hello.html') }}

输出:

hello world! twig模板字符串修改后的name

10 模板继承

Twig最强大的部分是模板继承。模板继承允许您构建包含站点所有常见元素的基本“骨架”模板,并定义子模板可以覆盖的块。

听起来很复杂,但是很基础。从一个例子开始就更容易理解。

我们来定义一个基模板,./view/templates/base.twig,它定义了一个简单的html框架文档:

<h1>{% block header%} 默认大标题 {% endblock %}</h1>
<h2 id="content" style="color:red;">{% block content %}默认正文{% endblock %}</h2>
<div id="footer"><p> {% block footer %}Copyright 2025 by  小彭爱学习{% endblock %}</p>
</div>

在本例中,block标记定义子模板可以填充的3个块。所有的块标记都是告诉模板引擎,子模板可以覆盖模板的那些部分。

block后面的header.content,footer为自定义的块名,后面引用时根据块名来覆盖。

新建./extend.php

<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, ['cache' => './view/cache','debug' => true,
]);echo $twig->render('base.twig');

访问extend.php,浏览器输出如下:

默认大标题
默认正文Copyright 2025 by 小彭爱学习

新建一个./view/templates/extend.twig,继承base.twig:

{% extends "base.twig" %}
{% block header %}修改后大标题{% endblock %}
{% block content %}修改后正文{% endblock %}

修改extend.php

<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, ['cache' => './view/cache','debug' => true,
]);echo $twig->render('extend.twig');

再次访问extend.php,浏览器输出如下:

修改后大标题
修改后正文Copyright 2025 by 小彭爱学习

我们可以发现对应的块名内的内容被继承后的模板修改了

11 HTML转义(HTML Escaping)

当从模板生成HTML时,总是有一个风险,变量将包括影响生成HTML的字符。有两种方法:手动转义每个变量,或者默认情况下自动转义。

Twig支持这两种,自动转义是默认启用的。

自动转义策略可以通过autoescape选项和默认的html来配置。

11.1 使用手动转义

如果手动转移已启用,如果需要转义变量这是您的责任。转义什么?任何你不信任的变量。

通过escape或e过滤器将变量通过管道进行转义:

{{ user.username|e }}

默认情况下,escape过滤器使用html策略,但是根据转义上下文,您可能想要显式地使用其他可用策略:

{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}

11.2 使用自动转义

无论是否启用了自动转义,您都可以通过使用自动转义标记来标记一个模板的一个片段:

{% autoescape %}Everything will be automatically escaped in this block (using the HTML strategy)
{% endautoescape %}

默认情况下,自动转义使用html转义策略。如果在其他上下文中输出变量,则需要使用适当的转义策略显式地转义它们:

{% autoescape 'js' %}Everything will be automatically escaped in this block (using the JS strategy)
{% endautoescape %}

11.3 转义(Escaping)

有时需要或甚至有必要让Twig忽略它可能作为变量或块来处理的部分。例如,如果使用默认的语法,并且希望在模板中使用{ {作为原始字符串,而不是启动变量,则必须使用技巧。

最简单的方法是使用一个变量表达式输出变量分隔符({ {):

{{ '{{' }}

12 宏(Macros)

宏可以与常规编程语言中的函数相比较。它们是有用的,可以重用经常使用的HTML片段不重复自己。

{% macro 宏名(参数1,参数2,....) %}内容
{% endmacro %}

宏可以在任何模板中定义,在使用之前需要通过import标签“导入”:

{% import 模板名 as 别名 %}{{ 别名.宏名 }}

一个用户注册表单例子如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><style>div#id{width: 100%;}span{width:800px;height:30px;display: block;text-align: center;margin: auto 2px;}input{width:800px;}div.bottom{margin-top:10px;}</style>
</head>
<body><div><div id="register">{% macro inputSpan(spanname,name, value, type,placeholder) %}<span class="con">{{spanname}}:</span><input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" placeholder="{{ placeholder }}" />{% endmacro %}{% import "macro.twig" as macro1 %}{{ macro1.inputSpan('用户帐号','uName', '',"text","设置用户名") }}{{ macro1.inputSpan('设置密码','uPwd', '',"password","设置密码") }}{{ macro1.inputSpan('密码确认','uPwdCom', '',"password","设置确认密码") }}{{ macro1.inputSpan('手机号','phone', '',"text","设置手机号码") }}{{ macro1.inputSpan('电子邮箱','email', '',"email","设置电子邮箱") }}</div><div class="bottom"><input type="submit" name="submit" value="注册并提交"/></div></div></body>
</html>

相当于:

<div><div id="register"><span class="con">用户帐号:</span><input type="text" name="uName" value="" placeholder="设置用户名" /><span class="con">设置密码:</span><input type="password" name="uPwd" value="" placeholder="设置密码" /><span class="con">密码确认:</span><input type="password" name="uPwdCom" value="" placeholder="设置确认密码" /><span class="con">手机号:</span><input type="text" name="phone" value="" placeholder="设置手机号码" /><span class="con">电子邮箱:</span><input type="email" name="email" value="" placeholder="设置电子邮箱" /></div><div class="bottom"><input type="submit" name="submit" value="注册并提交"/></div></div>

确实可以简化很多重复的代码!

或者,您可以从模板从模板导入单个宏名称,通过from标签到当前名称空间,并可选地将它们别名为:

{% from 'forms.html' import input as input_field %}
<dl><dt>Username</dt><dd>{{ input_field('username') }}</dd><dt>Password</dt><dd>{{ input_field('password', '', 'password') }}</dd>
</dl>

如果在宏调用中没有提供,还可以为宏参数定义一个默认值:

{% macro input(name, value = "", type = "text", size = 20) %}<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
{% endmacro %}

如果将额外的位置参数传递给宏调用,它们将以特殊的varargs变量作为值列表结束。

13 小结

以上就是twig的基础功能,twig 还有其他的功能,例如表达式、文字、数学运算、逻辑运算等,详细请参考官方文档。这里不再一一赘述。上述案例文档已经打包供大家下载学习。

下载地址:https://download.csdn.net/download/m0_53073183/90313992

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/69633.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯之c++入门(一)【C++入门】

目录 前言5. 算术操作符5.1 算术操作符5.2 浮点数的除法5.3 负数取模5.4 数值溢出5.5 练习练习1&#xff1a;计算 ( a b ) ⋆ c (ab)^{\star}c (ab)⋆c练习2&#xff1a;带余除法练习3&#xff1a;整数个位练习4&#xff1a;整数十位练习5&#xff1a;时间转换练习6&#xff…

设想中的计算机语言:可执行对象的构造函数和析构函数

经典 C语言的内存管理&#xff0c;是一块一块的&#xff0c;用malloc分配内存&#xff0c;用free释放内存。 C有对象&#xff0c;一个对象是好几片内存&#xff0c;用指针连接起来&#xff0c;用构造函数和析构函数管理对象。 创意 如图&#xff0c;是一个“可执行对象”&am…

SAP系统中的主要采购类型/采购模式总结

在 SAP 系统中,采购类型主要有以下几种: 一、标准采购订单(Standard Purchase Order) 描述:这是最常用的采购类型,用于一次性采购货物或服务。采购部门根据需求部门提出的采购申请,向供应商发出采购订单,明确规定了采购的物料、数量、价格、交货日期等详细信息。 应…

SpringCloud系列教程:微服务的未来(十七)监听Nacos配置变更、更新路由、实现动态路由

前言 在微服务架构中&#xff0c;API 网关是各个服务之间的入口点&#xff0c;承担着路由、负载均衡、安全认证等重要功能。为了实现动态的路由配置管理&#xff0c;通常需要通过中心化的配置管理系统来实现灵活的路由更新&#xff0c;而无需重启网关服务。Nacos 作为一个开源…

pycharm(2)

conda 我下载安装conda的时候产生了各种问题&#xff0c;最终我发现&#xff0c;打开杀毒软件会有阻碍 cuda的版本问题很大&#xff0c;我尝试多个版本之后&#xff0c;发现anaconda3-2024.06.1-windows-x86_64安装了之后不会报错&#xff0c;另外pycharm的版本也一直有问题&a…

DeepSeek-R1:通过强化学习激励大型语言模型(LLMs)的推理能力

摘要 我们推出了第一代推理模型&#xff1a;DeepSeek-R1-Zero和DeepSeek-R1。DeepSeek-R1-Zero是一个未经监督微调&#xff08;SFT&#xff09;作为初步步骤&#xff0c;而是通过大规模强化学习&#xff08;RL&#xff09;训练的模型&#xff0c;展现出卓越的推理能力。通过强…

Maven的下载安装配置

maven的下载安装配置 maven是什么 Maven 是一个用于 Java 平台的 自动化构建工具&#xff0c;由 Apache 组织提供。它不仅可以用作包管理&#xff0c;还支持项目的开发、打包、测试及部署等一系列行为 Maven的核心功能 项目构建生命周期管理&#xff1a;Maven定义了项目构建…

< OS 有关 > 阿里云 几个小时前 使用密钥替换 SSH 密码认证后, 发现主机正在被“攻击” 分析与应对

信息来源&#xff1a; 文件&#xff1a;/var/log/auth.log 因为在 sshd_config 配置文件中&#xff0c;已经定义 LogLevel INFO 部分内容&#xff1a; 2025-01-27T18:18:55.68272708:00 jpn sshd[15891]: Received disconnect from 45.194.37.171 port 58954:11: Bye Bye […

解决幂等问题的4种方案

幂等问题引入与准备工作 幂等概念&#xff1a;幂等指多次操作影响仅与首次执行结果相同&#xff0c;重复执行不会对系统造成额外变化。业务场景问题&#xff1a;以网站金币充值为例&#xff0c;因网络不稳定&#xff0c;支付宝支付成功的异步通知可能多次发送&#xff0c;若商家…

LitServe - 闪电般快速服务AI模型⚡

文章目录 一、关于 LitServe二、快速启动定义服务器测试服务器LLM 服务小结 三、特色示例功能特点 四、性能表现五、托管选项 一、关于 LitServe LitServe是一个易于使用、灵活的服务引擎&#xff0c;适用于基于FastAPI构建的AI模型。批处理、流式传输和GPU自动缩放等功能消除…

小程序电商运营内容真实性增强策略及开源链动2+1模式AI智能名片S2B2C商城系统源码的应用探索

摘要&#xff1a;随着互联网技术的不断发展&#xff0c;小程序电商已成为现代商业的重要组成部分。然而&#xff0c;如何在竞争激烈的市场中增强小程序内容的真实性&#xff0c;提高用户信任度&#xff0c;成为电商运营者面临的一大挑战。本文首先探讨了通过图片、视频等方式增…

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)

目录 1 -> 生命周期 1.1 -> 应用生命周期 1.2 -> 页面生命周期 2 -> 资源限定与访问 2.1 -> 资源限定词 2.2 -> 资源限定词的命名要求 2.3 -> 限定词与设备状态的匹配规则 2.4 -> 引用JS模块内resources资源 3 -> 多语言支持 3.1 -> 定…

Linux网络 | 理解TCP面向字节流、打通socket与文件的关系

前言&#xff1a;我们经常说TCP是面向字节流的&#xff0c; TCP是面向字节流的。 但是&#xff0c; 到底是什么事面向字节流呢&#xff1f; 另外&#xff0c; 我们知道sockfd其实就是文件fd。 但是&#xff0c;为什么sockfd是文件fd呢&#xff1f; 这些问题都在本节内容中的到回…

FireFox | Google Chrome | Microsoft Edge 禁用更新 final版

之前的方式要么失效&#xff0c;要么对设备有要求&#xff0c;这次梳理一下对设备、环境几乎没有要求的通用方式&#xff0c;universal & final 版。 1.Firefox 方式 FireFox火狐浏览器企业策略禁止更新_火狐浏览器禁止更新-CSDN博客 这应该是目前最好用的方式。火狐也…

大数据学习之Kafka消息队列、Spark分布式计算框架一

Kafka消息队列 章节一.kafka入门 4.kafka入门_消息队列两种模式 5.kafka入门_架构相关名词 Kafka 入门 _ 架构相关名词 事件 记录了世界或您的业务中 “ 发生了某事 ” 的事实。在文档中 也称为记录或消息。当您向 Kafka 读取或写入数据时&#xff0c;您以事件的 形式执行…

深度学习指标可视化案例

TensorBoard 代码案例&#xff1a;from torch.utils.tensorboard import SummaryWriter import torch import torchvision from torchvision import datasets, transforms# 设置TensorBoard日志路径 writer SummaryWriter(runs/mnist)# 加载数据集 transform transforms.Comp…

Linux文件原生操作

Linux 中一切皆文件&#xff0c;那么 Linux 文件是什么&#xff1f; 在 Linux 中的文件 可以是&#xff1a;传统意义上的有序数据集合&#xff0c;即&#xff1a;文件系统中的物理文件 也可以是&#xff1a;设备&#xff0c;管道&#xff0c;内存。。。(Linux 管理的一切对象…

基于springboot+vue的流浪动物救助系统的设计与实现

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

提供一种刷新X410内部EMMC存储器的方法

USRP X410内部采用了16G的EMMC存储器&#xff0c;内有内核和文件系统。官方站[注1]提供了多个版本的EMMC映像文件&#xff0c;并提供了多种刷新方法[注2]。 1&#xff0c;如果内核还能运行只是文件系统破坏&#xff0c;可以从外接USB盘&#xff0c;之后使用mount挂载U盘&#…

CTFSHOW-WEB入门-命令执行29-32

题目&#xff1a;web 29 题目&#xff1a;解题思路&#xff1a;分析代码&#xff1a; error_reporting(0); if(isset($_GET[c])){//get一个c的参数$c $_GET[c];//赋值给Cif(!preg_match("/flag/i", $c)){eval($c);//if C变量里面没有flag&#xff0c;那么就执行C…