leongrdic / dataplater
使用 data-* 属性的模板引擎,在渲染前确保 HTML 模板看起来很棒
Requires
- php: >=8.0
- ext-dom: *
- ext-libxml: *
- leongrdic/smplang: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^v3.8
- pestphp/pest: ^1.21
README
Dataplater 是一个用 PHP 编写的模板引擎,它使用 HTML data-attributes 以保持模板有效和整洁。这使得 Dataplater 成为创建文档模板(如发票、合同、电子邮件等)的理想选择,这些模板可以在渲染前在浏览器中预览。
特性
- 💻 制作渲染前看起来很棒的 HTML 模板
- 💾 使用 data-attributes 将数据传递到模板中
- ⚡ 强大的表达式语言 (SMPLang)
- 📩 自动转义
- 👍 UTF-8 支持
- 🧮 在表达式中访问 PHP 函数
- 🔗 包含 HTML 文件
- ➿ 嵌套的 foreach 循环
- 🔤 设置元素的内部 HTML 或自定义属性
- 🗑️ 根据条件删除元素
示例
This is <var data-dp=php.strrev(`emosewa`)></var> <!-- line above becomes: --> This is <var>awesome</var>
我实际上创建了一个用于 Dataplater 的 发票模板,该模板在生产中使用。模板的源代码在这里:链接。
安装
composer require leongrdic/dataplater
要求
- PHP 8.0+
- DOM & XML 扩展
用法
$dp = new \Le\Dataplater\Dataplater( filename: 'template.html', // path relative to baseDir or an absolute path // OR template: '<html>...</html>', // doesn't have to be a full HTML document // optional: vars: [ 'var' => 'value', ], // global vars baseDir: 'app/templates/', // base directory for templates attr: 'data-custom' // custom base attribute );
创建 Dataplater 对象时,您可以提供模板文件的 路径 或传递 模板字符串。推荐使用 PHP8 的命名参数初始化对象。
可选参数
vars
:要传递到模板中的全局变量数组,键为变量的名称baseDir
:用于包含的基目录(默认为.
)attr
:用于所有属性的基属性名称(默认为data-dp
)
render()
方法
$html = $dp->render([ 'var' => 'local value', 'function' => fn () => 'some value', ]);
render()
方法渲染模板,并返回作为字符串的渲染后的 HTML。
可选参数是本地变量数组,将覆盖具有相同名称的全局变量。
您可以在同一个对象上多次调用此方法,使用不同的变量以渲染同一文档的多个变体。
属性参考
如果您将基属性更改为例如 data-custom
(在创建 Dataplater 对象时),请使用 data-custom-foreach
而不是 data-dp-foreach
。
渲染后,所有 Dataplater 属性都将自动从模板中删除。
data-dp-include
值:要包含的 HTML 模板文件名。
包含文件的正文将插入到文档中,替换具有 data-dp-include
属性的元素。
<template data-dp-include="include.html"></template>
data-dp-if
值:SMPL 表达式
如果表达式评估为 true
,则将渲染元素,否则将删除它。
<div data-dp-if=false>this element will always be removed</div> <div data-dp-if="id > 1">this will be rendered if the condition is met</div>
data-dp-foreach
值:SMPL 表达式
其他属性:
data-dp-key
:当前元素键的变量名称(可选)data-dp-value
:当前元素值的变量名称(必需)
表达式必须评估为数组或可迭代对象。具有 data-dp-foreach
属性的元素的子元素将复制每个迭代,并将 data-dp-key
和 data-dp-value
变量设置为当前元素键和值,以用于这些子元素。
包含 data-dp-foreach
属性的元素将在循环之后被移除。
<ul> <template data-dp-foreach=['google','youtube'] data-dp-var=name data-dp-key=id> <li data-dp="id+1 ~ '. ' ~ name"></li> </template> </ul> <template data-dp-foreach=users data-dp-var=user> <a data-dp-href=user.url data-dp=user.name></a> </template>
data-dp-html
值:SMPL 表达式
如果表达式计算结果为 null
,则不会采取任何操作(元素将以原始内容渲染,不进行任何修改)。
否则,表达式必须计算为字符串。该字符串将作为 HTML 插入到元素中,替换元素的内容。
插入的 HTML 将仅渲染 data-dp
、data-dp-attr
和属性快捷键,这意味着其他属性如 data-dp-if
或 data-dp-foreach
将被忽略。
<div data-dp-html="'<b>' ~ name ~ '</b>'"></div> <div data-dp-html="'<b data-dp=name></b>'"></div>
注意第二个示例中表达式的引号 - 外部引号定义了 HTML 属性的内容,而内部引号定义了 SMPL 表达式中的字符串。
data-dp
值:SMPL 表达式
如果表达式计算结果为 null
,则不会采取任何操作(元素将以原始内容渲染,不进行任何修改)。
否则,表达式必须计算为字符串。该字符串将作为转义文本插入到元素中,替换元素的内容。
<span data-dp=message></span> <var data-dp="balance > 0 ? balance : 'empty balance'"></var> <label data-dp=`cool`></label>
注意:HTML 将最后一个示例中的属性解释为:data-dp="`cool`"
,而 SMPLang 将 `cool`
解释为字符串字面量。如果您将 data-dp="cool"
替换,SMPLang 将寻找一个名为 cool
的变量并返回其值。
data-dp-attr
值: attribute name ; SMPL 表达式
如果表达式计算结果为 null
,则不会设置属性,其值保持不变(如果有的话)。
否则,表达式必须计算为字符串。该字符串将被转义并作为所需属性的属性值插入。
Dataplater 还为以下属性提供了一些快捷方式:id
、class
、title
、alt
、value
、href
、src
、style
,使用以下语法:data-dp-attribute
。
<span data-dp-attr="title ; message"></span> <!-- or --> <var data-dp-title=message></var> <div data-dp-class="!hidden ? 'show'"></div>
表达式参考
Dataplater 使用 SMPLang 表达式语言。有关语法和支持运算符的更多信息,请参阅 SMPLang 的说明。
可以从 SMPL 表达式中访问 Dataplater 的变量。
此外,Dataplater 还提供了一个全局对象 php
,它基本上是一个所有 PHP 函数的代理。使用它可以在您的表达式中访问任何 PHP 函数。
php.count(users) > 0
php.array_reverse(links)
php.implode('-', php.explode(' ', someText))
请注意,您仍然可以传递自己的闭包/函数变量并在模板中使用它们。
当表达式返回一个闭包时,Dataplater 将尝试调用它(不带任何参数)并使用结果而不是闭包。
Dataplater 将所有 SMPL 异常包装在 \Le\Dataplater\ParseException
中,这为您提供了访问行号和导致 HTML 元素的功能。
渲染顺序
- 插入包含(仅限单级)
- 执行
if
检查(除循环中的那些之外) - 执行循环(递归)并完全渲染其内容(这允许嵌套循环,包括
if
检查) - 执行 HTML 插入
- 执行文本和属性插入
注意事项
Dataplater 严重依赖 PHP DOM 扩展,所有转义都是由 DOM 扩展原生完成的,因此将用户生成数据传递到 Dataplater 变量应该是安全的,尽管如果您确实使用来自不受信任来源的数据,请确保进行适当的验证。
另外,请注意 DOM 扩展有时会重新格式化 HTML(如添加属性括号、删除不必要的结束标签等),并且 Dataplater 输出的代码将无法很好地缩进。
欢迎对该项目做出贡献!