用PHP编写的简单模板语言

v1.0.21 2024-08-08 19:18 UTC

README

PHPUnit Latest Stable Version License

Brace

Brace 是一种用PHP编写的简单模板语言。Brace 使用类似 Handlebar 的语法。

  • 要求
  • 安装
    • 通过 composer
    • 或包含 brace 类
  • 使用
    • 以字符串形式返回模板过程
    • 编译到外部文件
    • 实例变量
  • 模板引用
    • 变量
      • 行内 "或" 操作符
      • 多个行内 "或" 操作符
      • 通过数组索引值返回变量值
    • 迭代器
      • 行内迭代器
    • Nth 子元素
    • 行键
    • 迭代数据变量
    • 循环
      • 递增
      • 递减
    • 循环数据变量
    • 条件语句
      • 条件块
    • Else If 语句
      • 行内条件
      • 条件
    • 包含模板
    • 简码
      • PHP 实现示例
      • 内容模板
    • 数组计数
      • 显示计数
      • 检查计数
    • 注释块
      • 行内注释块
      • 多行注释块
    • 清除缓存的处理字符串
    • 运行测试

要求

Brace 需要 PHP 版本 8.1 或更高。

安装

通过 composer

composer require alexoliverwd/brace

或包含 brace 类

/** Include brace */
include __DIR__.'/src/brace.php';

使用

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Set instance variables (Optional) */
$brace->remove_comment_blocks = false;
$brace->template_path = __DIR__.'/';
$brace->template_ext = 'tpl';

/** Process template and echo out */
$brace->Parse('example',[
    'name' => [
        'first' => 'John',
        'last' => 'Doe'
    ]
]);

以字符串形式返回模板过程

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and return string */
$template_string = $brace->Parse('example',[
    'name' => [
        'first' => 'John',
        'last' => 'Doe'
    ]
], false)->return();

编译到外部文件

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and compile to external file */
$brace->compile('example', 'example.html', [
    'name' => [
        'first' => 'John',
        'last' => 'Doe'
    ]
]);

实例变量

模板引用

变量

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'firstname' => 'John Doe'
]);
<p>{{firstname}}</p>

行内 "或" 操作符

<p>{{firstname || "No first name found"}}</p>

多个行内 "或" 操作符

<p>{{firstname || fname || "No first name found"}}</p>

通过数组索引值返回变量值

<p>Hi {{names->?first[Jane]->title}} {{names->?first[Jane]->last}}</p>
/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'names' => [
        0 => [
            'title' => 'Mr',
            'first' => 'John',
            'last' => 'Smith'
        ],
        1 => [
            'title' => 'Miss',
            'first' => 'Jane',
            'last' => 'Doe'
        ],
        2 => [
            'title' => 'Dr',
            'first' => 'David',
            'last' => 'Jones'
        ]
    ]
]);

结果

<p>Hi Miss Doe</p>

迭代器

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'products' => [
        0 => [
            'title' => 'Product 1',
            'price' => 22.99,
            'stock' => 15,
            'categories' => ['Textile','Cloths']
        ],
        1 => [
            'title' => 'Product 2',
            'price' => 10.00,
            'stock' => 62,
            'categories' => ['Electronics','PC','Hardware']
        ],
        2 => [
            'title' => 'Product 3',
            'price' => 89.98,
            'stock' => 120,
            'categories' => ['PC Game']
        ]
    ]
]);
<ul>
{{each products}}
    <li>{{title}}</li>
{{end}}
</ul>
<ul>
{{each products as product}}
    <li>
        {{product->title}}
        <ul>
        {{each product->categories as category}}
            <li>{{category}}</li>
        {{end}}
        </ul>
    </li>
{{end}}
</ul>
<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'names' => ['John','Steve','Bert']
]);
{{each names as name}}
    <p>{{name}}</p>
{{end}}

行内迭代器

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'names' => ['John','Steve','Bert']
]);
<ul>
    {{names as name "<li>__name__</li>"}}
</ul>

<ul>
    {{names as key value "<li data-key="__key__">__value__</li>"}}
</ul>
<ul>
    <li>John</li>
    <li>Steve</li>
    <li>Bert</li>
</ul>

Nth 子元素

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'names' => ['John','Steve','Bert','Fred','Cindy']
]);
<!-- Is first item -->
{{each names as name}}
    <span{{_ITERATION === "is_first_item" ? " class=\"is_first\""}}>{{name}}</span>
{{end}}

<!-- Is last item -->
{{each names as name}}
    <span{{_ITERATION === "is_last_item" ? " class=\"is_last\""}}>{{name}}</span>
{{end}}

<!-- Is second item -->
{{each names as name}}
    <span{{_ITERATION == 2 ? " class=\"is_second_item\""}}>{{name}}</span>
{{end}}

行键

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'names' => [
        'name_1' => 'Dave',
        'name_2' => 'John',
        'name_3' => 'Barry'
    ]
]);
{{each names as name}}
    <span data-key="{{_KEY}}">{{name}}</span>
{{end}}

{{each names as key value}}
    <span data-key="{{key}}">{{value}}</span>
{{end}}

迭代数据变量

添加到每次迭代的变量。

循环

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[]);
{{loop 3}}
<li>{{_KEY}}</li>
{{end}}

递增

{{loop 1 to 3}}
<li>{{_KEY}}</li>
{{end}}

递减

{{loop 3 to 1}}
<li>{{_KEY}}</li>
{{end}}

循环数据变量

添加到每次迭代的变量。

条件语句

条件块

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'first_name' => 'John',
    'last_name' => 'Doe'
]);
{{if first_name EXISTS}}
    <p>Hello {{first_name}}</p>
{{end}}
{{if first_name EXISTS && first_name == "John"}}
    <p>My first name is {{first_name}}</p>
{{else}}
    <p>Please enter your first name</p>
{{end}}

Else If 语句

<?php

/** New brace instance */
$brace = new Brace\Parser();

/** Process template and echo out */
$brace->Parse('example',[
    'names' => ['John','Steve','Bert','Fred','Cindy']
]);
{{each names as name}}
    {{if _ITERATION === "is_first_item"}}
        <span class="first_item" data-rowid="{{_ROW_ID}}">{{name}}</span>
    {{elseif _ITERATION === "is_last_item"}}
        <span class="last_item" data-rowid="{{_ROW_ID}}">{{name}}</span>
    {{elseif _ITERATION == 2}}
        <span class="second_item" data-rowid="{{_ROW_ID}}">{{name}}</span>
    {{else}}
        <span data-rowid="{{_ROW_ID}}">{{name}}</span>
    {{end}}
{{end}}

行内条件

<p>{{first_name !== "test" ? "__first_name__" : "is test"}}</p>
<p>{{first_name EXISTS ? "__first_name__" : "is test"}}</p>
<p>{{first_name EXISTS ? "my first name is __first_name__"}}</p>

转义引号

<p>{{first_name !== "test" ? "Name is \"__first_name__\"" : "is test"}}</p>
Name is "John"

条件

包含模板

[@include sections/footer]
[@include header footer]
[@include {{section}}]

简码

PHP 实现示例

<?php

/** New brace parser */
$brace = new Brace\Parser();

/** Return HTML link */
$button_function = function ($attributes){
    return '<a href="'.$attributes['url'].'" alt="'.$attributes['alt'].'" target="'.$attributes['target'].'" rel="noreferrer noopener">'.$attributes['title'].'</a>';
};

/** Register shortcode */
$brace->regShortcode('button', 'button_function');

/** Process content template */
$brace->Parse('content', []);

内容模板

<!-- Button shortcode -->
[button title="Hello world" url="https://hello.world" alt="Hello world button" target="_blank"]

数组计数

检查并显示数组项目计数的功能

显示计数

<p>Total items is: {{COUNT(items)}}</p>
Total items is: 3

检查计数

{{if COUNT(items) == 3}}
<p>There are three items</p>
{{end}}
There are three items

注释块

行内注释块

<!-- Inline comment block -->

多行注释块

<!--
    Comment block over multiple lines
-->

清除缓存的处理字符串

当需要使用相同的 brace 实例处理多个具有不同数据的模板时,--clear-- 方法很有用。

默认情况下,Brace 在执行模板/字符串解析后不会清除处理过的字符串。

<?php

// Init brace
$brace = new Brace\Parser();
$brace->template_path = __DIR__.'/';

// Process first template
$brace->Parse('example',[
    'name' => [
      'first' => 'John',
      'last' => 'Doe'
    ]
]);

// Process second template using the same brace instance
$brace->clear()->parse('example_two',[
    'name' => [
      'first' => 'Dave',
      'last' => 'Smith'
    ]
]);

运行测试

可以使用以下命令运行 PHPStan 和 PHPUnit 测试

./vendor/bin/phpstan analyse -c phpstan.neon
./vendor/bin/phpunit -c ./tests/phpunit.xml

或者通过 composer 运行 composer test