affinity4/template

简单的模板引擎,具有易于学习的可选语法。也可以使用纯PHP。

1.3.1 2022-05-25 17:15 UTC

This package is auto-updated.

Last update: 2024-09-18 15:36:19 UTC


README

功能齐全的模板引擎,具有易于学习的可选语法。也可以使用纯PHP。

特性

  • HTML注释语法
  • 在模板中需要时可以使用纯PHP
  • 如需要,可以添加新语法。

安装

Affinity4/Template 通过 composer 提供

composer require affinity4/template

{
    "require": {
        "affinity4/template": "^1.1"
    }
}

语法

输出变量

<h1><!-- :title --></h1>

设置变量

<!-- :showTitle = true -->

通过键获取数组项,例如 $post['title']

<!-- :post.title -->

如果语句

<!-- @if :showTitle is true and :something is false or :somethingElse -->
    <h1><!-- :title --></h1>
<!-- @/if -->

<!-- @if :showTitle -->
    <h1><!-- :title --></h1>
<!-- @elseif :something and :showTitle -->
    <h1><!-- :title --></h1>
    <h2>Something</h1>
<!-- @else -->
    <h1>Default Title</h1>
<!-- @/if -->

foreach 循环

<ul>
<!-- @each :item in :items -->
    <li><!-- :item --></li>
<!-- @/each -->
</ul>

<!-- @each :id, :post in :posts -->
<article>
<h1><!-- :post.title --></h1>
<div><!-- :post.content --></div>
</article>
<!-- @/each -->

注意: 也可以是 @foreach

while 循环

<!-- :i = 1 -->
<!-- @while :i <= count(:items) -->
    Number: <!-- :i --><br />
<!-- :i++ -->
<!-- @/while -->

for 循环

<!-- @for :i = 1; :i <= 3; :i++ -->
    Number: <!-- :i --><br />
<!-- @/for -->

布局和块

你可以像在 Twig 或 Blade 等其他模板引擎中一样扩展主布局。

创建一个主布局,其中包含每个视图文件中要覆盖的部分

文件: views/layout/master.php

<!DOCKTYPE html>
<html>
<head>
    <title><!-- @block title -->This can be overridden<!-- @/block -->: Site description</title>
    
    <link href="/assets/css/main.css" rel="stylesheet">
    <!-- @block css -->
    <!-- Each view can add custom CSS here -->
    <!-- @/block -->
    
    <script src="/assets/js/jquery.js"></script>
    <!-- @block js-head -->
    <!-- Each view can add custom JS here -->
    <!-- @/block -->
</head>
<body>
    <main>    
        <h1><!-- @block page-title -->Default Page<!-- @/block --></h1>
        
        <!-- @block content -->
        <p>Page content goes here...</p>
        <!-- @/block -->
    </main>

    <!-- @block js-footer -->
    <!-- Each view can add custom JS here -->
    <!-- @/block -->
</body>
</html>

然后在你的视图中

文件: views/home.php

<!-- @extends layout/master.php -->

<!-- @block title --><!-- :page_title --><!-- @/block -->

<!-- @block css -->
<link href="/assets/css/home.css" rel="stylesheet">
<!-- @/block -->

<!-- @block page-title --><!-- :page_title --><!-- @/block -->

<!-- @block content -->
<p>This is the homepage</p>
<!-- @/block -->

然后简单地渲染视图

文件: index.php

use Affinity4\Template;

$template = new Template\Engine(new Template\Syntax);

$tempalte->render('views/home.php', ['page_title' => 'Home']);

用法

要渲染模板

use Affinity4\Template;

$template = new Template\Engine(new Template\Syntax);

$template->render('views/home.php', ['title' => 'Home Page']);

如果你想要添加新的语法,可以在初始化模板引擎后使用 addToken 方法。

use Affinity4\Template;

$template = new Template\Engine(new Template\Syntax);

$template->addRule('/\{\{ ([\w\d+]) \}\}/', '<?= $$1 ?>');

$template->render('views/home.php', ['title' => 'Home Page']);

你也可以将可调用的函数作为 addToken 方法的第二个参数传递,以使用 preg_replace_callback 进行替换。

use Affinity4\Template;

$template = new Template\Engine(new Template\Syntax);

$template->addRule('/\{\{ ([\w\d]+) \}\}/', function ($statement) {
    return '<?php echo $' . $statement[1] . ' ?>'; 
});

$template->render('views/home.php', ['title' => 'Home Page']);

覆盖语法

Affinity4 模板的一个相当独特之处在于它允许你用你自己的简单类替换语法类,以创建你自己的模板语言。

通过扩展 Affinity4\Template\Tokenizer 类并实现 Affinity4\Template\SyntaxInterface,你可以轻松添加 Affinity4 模板中目前的所有功能。从那里开始,你只需添加变量、循环等规则,并扩展块语法。如果你不添加扩展或块规则,该功能将简单地不可用。

以下是一个创建自定义 Blade 风格语法的示例

<?php
namespace Your\Template\Syntax\Blade2;

use Affinity4\Template;

class Blade2 extends Affinity4\Template\Tokenizer implements Affinity4\Template\SyntaxInterface
{
    public function __construct()
    {
        $this->addRule('/\{\{ ?(\$.*) ?\}\}/', '<?php echo htmlspecialchars($1, ENT_QUOTES, 'UTF-8'); ?>');
        
        $this->addRule('/@if ?\(\(.*))/', '<?php if ($1) : ?>');
        $this->addRule('/@elseif ?\(\(.*))/', '<?php elseif ($1) : ?>');
        $this->addRule('/@else/', '<?php else : ?>');
        $this->addRule('/@endif/', '<?php endif; ?>');
        
        $this->addRule('/@foreach ?\(\(.*))/', '<?php foreach ($1) : ?>');
        $this->addRule('/@endforeach/', '<?php foreach ($1) : ?>');
        
        // For, while etc...
        
        $this->addExtendsRule('/@extends\((.*)\)/');
        $this->addSectionRule('/@section\('(.*)'\)/', '/@endsection/');
    }
}

然后你只需在调用 Template Engine 类时使用依赖注入即可

require_once __DIR__ . '/vendor/autoload.php';
 
use Affinity4\Template\Engine;
use Your\Template\Syntax\Blade2;

$blade2 = new Engine(new Blade2);
$blade2->render('views/home.blade', ['title' => 'Blade 2']);

你的布局模板(views/layout/master.blade)可以是

<!doctype html>
<html>
<head>
    <title>@section('title') Default to be overriden @endsection</title>
</head>
<body>
    <h1>
    @section('title')
        Title here...
    @endsection
    </h1>
</body>
</html>

在 views/home.blade...

@extends('layouts/master.blade')

@section('title')
  {{ $title }}
@endsection

测试

运行测试

vendor/bin/phpunit

许可证

(c) 2017 Luke Watts (Affinity4.ie)

本软件受 MIT 许可证许可。有关完整的版权和许可信息,请查看与源代码一起分发的 LICENSE 文件。