# Latte:PHP的令人惊叹的模板引擎
Latte是PHP的模板引擎,它简化了您的工作,并确保输出被保护免受漏洞,例如XSS。
Latte是快速的:它将模板编译成平凡的优化PHP代码。
Latte是安全的:它是第一个引入内容感知转义的PHP引擎。
Latte语法:它有直观的语法,并帮助您轻松地构建更好的网站。
虽然PHP最初是一种模板语言,但它不是特别适合编写模板。 让我们来看一个PHP模板的例子,它将一个数组$ items打印成一个列表:
~~~
<?php if ($items): ?>
<?php $counter = 1 ?>
<ul>
<?php foreach ($items as $item): ?>
<li id="item-<?php echo $counter++ ?>"><?php
echo htmlSpecialChars(mb_convert_case($item, MB_CASE_TITLE)) ?>
</li>
<?php endforeach ?>
</ul>
<?php endif?>
~~~
代码相当混乱。 此外,我们不能忘记调用htmlSpecialChars函数。 这就是为什么有这么多不同的模板引擎PHP。 最好的模板引擎之一是Nette Framework的一部分,它被称为Latte。 你会爱上它!
与上面相同的模板可以很容易地写在Latte:
~~~
<ul n:if="$items">
{foreach $items as $item}
<li id="item-{$iterator->counter}">{$item|capitalize}</li>
{/foreach}
</ul>
~~~
正如你可以看到有两种类型的宏:
大括号中的宏,例如{foreach ...}
n:宏,例如n:if =“...”
# 安装和使用
如何安装Latte的最好方法是下载最新的[软件包](https://github.com/nette/latte/releases)或使用Composer:
~~~
php composer.phar require latte/latte
~~~
Latte需要PHP 5.3.1或更高版本。
如何渲染模板? 只需运行这段代码:
~~~
$latte = new Latte\Engine;
$latte->setTempDirectory('/path/to/tempdir');
$parameters['items'] = ['one', 'two', 'three'];
//渲染输出
$latte->render('template.latte', $parameters);
// 或呈现为字符串
$html = $latte->renderToString('template.latte', $parameters);
~~~
# 宏命令
您可以在额外页面上找到所有默认宏命令的详细说明。 此外,您可以制作自己的宏命令。
每对宏命令,例如{if} ... {/ if},对单个HTML元素操作可以写成n:宏命令符号。 因此,可以以相同的方式写入{foreach}宏命令:
~~~
<ul n:if="$items">
<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>
~~~
使用n:宏命令你可以做更多的有趣的技巧,你会看到一会儿。
{$ item | capitalize}宏命令打印$ item变量包含所谓的过滤器,在这种情况下大写字母过滤器使每个单词的第一个字母大写。
Latte的非常重要的特性是它默认转义变量。 打印变量时需要转义,因为我们必须将HTML中有特殊含义的所有字符转换为其他序列。 如果我们忘记它可能导致一个严重的安全漏洞称为跨站脚本(XSS)。
由于在不同文档和页面的不同部分需要不同的转义功能,Latte提供了一种独特的上下文感知转义技术,它识别宏命令被放置的上下文,并选择正确的转义模式。 你不必担心你的编码器忘了它导致你出现一个安全漏洞。 这是伟大的!
你仍然可以使用PHP里面的宏命令,包括注释。 但Latte还扩展了PHP语法有三个令人愉快的功能:
1、数组可以写成[1,2,3],这与PHP中的[1,2,3]相同
2、我们可以省略由字母,数字和破折号组成的字符串周围的引号
3、短条件符号$ a? 'b'与$ a相同? 'b':在PHP中为null
例如:
~~~
{foreach [a, b, c] as $id} ... {/foreach}
{$cond ? hello} // 如果$ cond等于true,则打印'hello'
~~~
# n:宏命令
我们显示n:宏命令应该直接写入HTML标签,作为他们的特殊属性。 我们还说每对宏命令(例如{if} ... {/ if})可以用n:宏命令表示。 然后,宏对应于写入它的HTML元素:
~~~
{var $items = ['I', '♥', 'Nette Framework']}
<p n:foreach="$items as $item">{$item}</p>
~~~
打印:
~~~
<p>I</p>
<p>♥</p>
<p>Nette Framework</p>
~~~
通过使用内部前缀,我们可以改变行为,使宏命令只适用于元素的主体:
~~~
<div n:inner-foreach="$items as $item">
<p>{$item}</p>
<hr>
</div>
~~~
打印:
~~~
<div>
<p>I</p>
<hr>
<p>♥</p>
<hr>
<p>Nette Framework</p>
<hr>
</div>
~~~
或者通过使用标记前缀,宏命令仅应用于HTML标记:
~~~
<p><a href="{$url}" n:tag-if="$url">Title</a></p>
~~~
根据$ url变量的值,这将打印:
~~~
// 当$ url是空的
<p>Title</p>
// 当$ url等于'https://nette.org'
<p><a href="https://nette.org">Title</a></p>
~~~
然而,n:宏命令不仅是对宏的快捷方式,还有一些纯n:宏,例如编码器的最好的朋友n:类宏。
# 过滤器
Latte通过使用特殊符号调用过滤器(允许前面的有空格):
~~~
<h1>{$heading|upper}</h1>
~~~
过滤器(或修饰符)可以一起使用,在这种情况下,它们从左到右依次应用:
~~~
<h1>{$heading|lower|capitalize}</h1>
~~~
参数放在过滤器名称后面,用冒号或逗号分隔:
~~~
<h1>{$heading|truncate:20,''}</h1>
~~~
过滤器可以通过任何回调或lambda函数注册:
~~~
$latte = new Latte\Engine;
$latte->addFilter('shortify', function ($s) {
return mb_substr($s, 0, 10); //将文本缩短为10个字符
});
~~~
在这种情况下,过滤器会得到一个额外的参数:
~~~
$latte->addFilter('shortify', function ($s, $len = 10) {
return mb_substr($s, 0, $len);
});
~~~
我们这样的模板中调用它:
~~~
<p><?php echo $template->shortify($text, 100); ?></p>
~~~
Latte简化了符号 - 过滤器由特殊符号表示,它们可以组合(它们从左到右依次应用)。 参数用冒号或逗号分隔:
~~~
<p>{$text|shortify:100}</p>
~~~
# 通用过滤器
手动注册多个过滤器可以替换为单个通用注册:
~~~
$template->addFilter(NULL, 'Filters::common');
~~~
过滤器:common将过滤器的名称作为第一个参数。
~~~
class Filters
{
public static function common($filter, $value)
{
if (method_exists(__CLASS__, $filter)) {
$args = func_get_args();
array_shift($args);
return call_user_func_array([__CLASS__, $filter], $args);
}
}
public static function shortify($s, $len = 10)
{
return mb_substr($s, 0, $len);
}
}
~~~
# 性能
Latte运行很快。 它将模板编译为本机PHP代码,并将它们存储在磁盘的缓存中。 因此,它们就像用纯PHP编写的一样快。
每次我们更改源文件时,模板都会自动重新编译。 在开发时,您只需要编辑Latte中的模板,并且更改会立即显示在浏览器中。
# 调试
每一个错误或打字错误,你将被告知Tracy所有的奢侈。 显示模板源代码,红线标记显示错误消息的错误。 只需单击一下,您可以在您喜欢的编辑器中打开模板,并立即修复错误。 十分简单!
如果您使用带有代码步进的IDE,您可以通过模板生成的PHP代码。
# 可用性
Latte语法不是由工程师发明的,而是来自webdesigner的实际需求。 我们正在寻找最友好的语法,你甚至可以写出最有问题的结构足够舒服。 你会惊讶的是,Latte可以多少有一些帮助。
您可以找到用于高级布局管理,模板继承,嵌套块等的宏。 语法来自PHP本身,所以你不必学习任何新的,你可以利用你的专有技术。
# 上下文感知转义
虽然跨站脚本(XSS)是利用网页的一种简单的方法,它是最常见的漏洞,但非常严重。 它可能导致身份盗窃等。 最好的防御是一致的逃脱打印数据,即。 转换在给定上下文中具有特殊含义的字符。
如果编码器省略了逃逸,则产生安全漏洞。 这就是为什么模板引擎实现自动转义。 问题是网页具有不同的上下文,并且每个具有用于转义打印数据的不同规则。 如果使用错误的转义函数,则会显示安全漏洞。
但Latte是复杂的。 它具有上下文感知转义的独特技术,它识别宏命令被放置的上下文,并选择正确的转义模式。 这意味着什么?
Latte不需要任何手动工作。 一切都是自动,一致和正确。 你不必担心安全漏洞。
让我们看看它是如何工作的:
~~~
<p onclick="alert({$movie})">{$movie}</p>
<script>var movie = {$movie};</script>
~~~
如果$ movie变量存储'Amarcord&8 1/2'字符串,它将生成以下输出。 注意在HTML和JavaScript以及onclick属性中使用的不同转义:
~~~
<p onclick="alert("Amarcord & 8 1\/2")">Amarcord & 8 1/2</p>
<script>var movie = "Amarcord & 8 1\/2";</script>
~~~
感谢上下文感知转义模板很简单,你的应用程序完全防止跨站点脚本。 你可以在JavaScript中使用PHP变量!
# 一个漂亮的输出
Stickers将享受Latte生成的HTML输出的外观。 所有标签缩进为他们应该。 代码看起来像它已经处理与某种类型的HTML代码美化:-)
# 用户定义的宏命令
Latte提供API来创建自己的宏命令。 这根本不难。 宏命令是以集合的形式添加的(一个集合可以包含一个宏命令)。
~~~
$latte = new Latte\Engine;
//让我们创建一个集合
$set = new Latte\Macros\MacroSet($latte->getCompiler());
// 添加一对对宏命令 {try}... {/try}
$set->addMacro(
'try', // 宏命令名称
'try {', // PHP代码替换开始大括号
'} catch (\Exception $e) {}' // 代码替代闭包
);
~~~
如果我们省略addMacro()方法的最后一个参数,我们表示宏命令未配对。
PHP代码中的第二和第三个参数可以包含标签:
~~~
%node.word – 插入第一个宏参数
%node.array – 插入格式化为PHP数组的宏参数
%node.args – 插入格式化为PHP代码的宏参数
%escape(...) –替换为当前的逃逸函数
%modify(...) – 替换为一系列修饰符
~~~
例如:
~~~
$set->addMacro('if', 'if (%node.args):', 'endif');
~~~
如果宏逻辑更复杂,我们可以使用回调或lambda函数,而不是字符串。 在第一个参数中,它们将获得代表当前宏的MacroNode对象,第二个参数是帮助生成输出代码的PhpWriter对象。
~~~
$set->addMacro('if', function($node, $writer) {
return $writer->write('if (%node.args):');
}, 'endif');
~~~
# 从字符串加载到模板
您可以使用loader从字符串加载模板:
~~~
$latte->setLoader(new Latte\Loaders\StringLoader);
$template = '
{if true} {$var} {/if}
';
$latte->render($template, $parameters);
~~~
- Nette简介
- 快速开始
- 入门
- 主页
- 显示文章详细页
- 文章评论
- 创建和编辑帖子
- 权限验证
- 程序员指南
- MVC应用程序和控制器
- URL路由
- Tracy - PHP调试器
- 调试器扩展
- 增强PHP语言
- HTTP请求和响应
- 数据库
- 数据库:ActiveRow
- 数据库和表
- Sessions
- 用户授权和权限
- 配置
- 依赖注入
- 获取依赖关系
- DI容器扩展
- 组件
- 字符串处理
- 数组处理
- HTML元素
- 使用URL
- 表单
- 验证器
- 模板
- AJAX & Snippets
- 发送电子邮件
- 图像操作
- 缓存
- 本土化
- Nette Tester - 单元测试
- 与Travis CI的持续集成
- 分页
- 自动加载
- 文件搜索:Finder
- 原子操作