wol-soft/php-micro-template 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

wol-soft/php-micro-template

Composer 安装命令:

composer require wol-soft/php-micro-template

包简介

A minimalistic templating engine for PHP

README 文档

README

Latest Version Maintainability Build Status Coverage Status MIT License

php-micro-template

A minimalistic, lightweight templating engine for PHP with zero dependencies based on regular expressions.

Features

  • Replace variables inside a template
  • Iterate over an array or iterable object
  • Conditional sections
  • Pass objects
  • call functions

Requirements

  • Requires at least PHP 7.1

Installation

The recommended way to install php-micro-template is through Composer:

$ composer require wol-soft/php-micro-template

Examples

First create your template file:

<html>
    <h1>{{ pageTitle }}</h1>

    <ul class="row">
        {% foreach products as product %}
            {% if product.isVisible() %}
                <li class="product">
                    <span>{{ productHead }}</span>
                    <span>{{ product.getTitle() }}</span>
                </li>
            {% endif %}
        {% endforeach %}
    </ul>

    {% if showVersion %}
        <div class="version">1.0.1</div>
    {% endif %}
</html>

Afterwards create a new instance of the Render class and render your template:

<?php

use PHPMicroTemplate\Render;

/* ... */

$render = new Render(__DIR__ . '/Templates/');

$result = $render->renderTemplate(
    'productList.template',
    [
        'pageTitle' => $translator->translate('availableProducts'),
        'productHead' => $translator->translate('product'),
        'products' => $products,
        'showVersion' => true
    ]
);

/* ... */

Instead of saving your templates into files you can also prepare a string which contains the template:

<?php

use PHPMicroTemplate\Render;

/* ... */

$myPartialTemplate = '
    {% foreach products as product %}
        {% if product.isVisible() %}
            <li class="product">
                <span>{{ productHead }}</span>
                <span>{{ product.getTitle() }}</span>
            </li>
        {% endif %}
    {% endforeach %}
';

$render = new Render();

$result = $render->renderTemplateString(
    $myPartialTemplate,
    [
        'productHead' => $translator->translate('product'),
        'products' => $products
    ]
);

/* ... */

Replacement of variables

Values which are assigned to the template and used directly will be casted to string. For assigned objects you can call methods which return a value. Afterwards the returned value will be casted to string. As constant values integer numbers, strings in single quotes and booleans (true, false) are supported.

{{ simpleValue }}
{{ myObject.getProperty() }}
{{ 'Hello World' }}
{{ 12345 }}

Your provided data may be a nested array which can be resolved in the template:

$render->renderTemplateString(
    '{{ render.productRender.renderProductName(product.details.name) }}',
    [
        'product' => [
            'details' => [
                'name' => 'MyProduct',
            ],
        ],
        'render' => [
            'productRender' => new ProductRender(),
        ]
    ]
);

Also, public properties of objects may be accessed from the template:

$person = new stdClass();
$person->name = 'Hans';

$render->renderTemplateString(
    '{{ person.name }}',
    [
        'person' => $person,
    ]
);

By default, a used variable which is not provided will result in an UndefinedSymbolException. You can register a callback function via onResolveError to handle unresolved variable errors. The callback function must implement the signature function (string $unresolvedVariable): string. The provided $unresolvedVariable will contain the whole expression which failed to resolve (eg. myUnresolvedVariable, myUnresolvedObject.render(var1, var2)).

$render->onResolveError(function (string $var): string {
    return 'Undefined';
});

// will result in "Person name: Undefined"
$result = $render->renderTemplateString('Person name: {{ name }}');

Loops

If you assign an array or an iterable object you can use the foreach loop to iterate.

{% foreach products as product %}
    <span>{{ product.getTitle() }}</span>
{% endforeach %}

All variables of the parent scope are available inside the loop as well as the current item of the loop. Multiple foreach loops can be nested (compare tests). You can also provide a function which returns an array or an iterable object:

{% foreach product.getIngredients() as ingredient %}
    <span>{{ ingredient.getTitle() }}</span>
{% endforeach %}

Loops support the usage of key value pairs:

{% foreach products as bestSellerNumber, product %}
    <b>Bestseller Nr. {{ bestSellerNumber }}:</b>{{ product.getTitle() }}<br/>
{% endforeach %}

Conditional sections

With the if statement you can create conditional sections. As a condition you can pass either a value which will be casted to bool or call a method on an object. In this case the return value of the function will be casted to bool. Neither multiple values in a single condition combined by operators nor calculations or similar additional functions are provided. For advanced conditions compare the section function calls with a ViewHelper-Object.

{% if showProducts %}
    {% if product.isVisible() %}
        <span>{{ product.getTitle() }}</span>
    {% else %}
        <span>Product {{ product.getTitle() }} currently not available</span>
    {% endif %}
{% endif %}

Multiple if statements can be nested. To invert an if condition the keyword not can be used:

{% if not product.isVisible() %}
    <span>Product {{ product.getTitle() }} currently not available</span>
{% endif %}

To compose multiple conditions in a single if, the keywords and and or can be used (and has the higher precedence). Brackets in if statements are not supported.

{% if not product.isVisible() or not product.isAvailable() %}
    <span>Product {{ product.getTitle() }} currently not available</span>
{% endif %}

function calls

The methods which are called can take parameters. Allowed parameters are variables taken out of the current scope or another function call on an object available in the current scope as well as the supported constant values integer numbers, strings in single quotes and booleans (true, false). As an example a ViewHelper-Object can be assigned to the render process and methods of the ViewHelper can be used in the template for advanced logic inside the template.

<?php

use PHPMicroTemplate\Render;

/* ... */

class ViewHelper
{
    public function count(iterable $list): int
    {
        return count($list);
    }

    public function sum(float ...$values): float
    {
        return array_sum($values);
    }

    public function weight(string $label, int $weight = 400): string
    {
        return sprintf('<span style="font-weight: %d;">%s</span>', $weight, $label);
    }
}

/* ... */

$render = new Render(__DIR__ . '/Templates/');

$result = $render->renderTemplate(
    'functionExample.template',
    [
        'viewHelper' => new ViewHelper(),
        'currencyFormatter' => new CurrencyFormatter(),
        'basePrice' => 3.00,
        'products' => $products
    ]
);

/* ... */
<html>
    <p>Products: {{ viewHelper.count(products) }}
    <ul class="row">
        {% foreach products as product %}
            <li class="product">
                <span>{{ viewHelper.weightFont(product.getTitle(), 600) }}</span>
                <span>Price: {{
                    currencyFormatter.format(
                        viewHelper.sum(
                            product.getPrice(),
                            basePrice
                        )
                    )
                }}</span>
            </li>
        {% endforeach %}
    </ul>
</html>

Additionally, PHP global functions can be used directly in the template as well as assigned callback methods:

<?php

use PHPMicroTemplate\Render;

/* ... */

$render = new Render(__DIR__ . '/Templates/');

$result = $render->renderTemplate(
    'functionExample.template',
    [
        'customCallback' => function(string $in): string {
            return trim(strtoupper($in));
        },
    ]
);

/* ... */
<html>
    <p>{{ customCallback('products') }}</p>
    <span>{{ strtolower('UNDER CONSTRUCTION') }}</span>
</html>

Comments

With the {# ... #} syntax, the template can contain comments which are stripped from the output:

<html>
    {# customCallback delivers a summary, just like we need it here #}
    <p>{{ customCallback('products') }}</p>
</html>

Whitespace tolerance

The templating syntax is whitespace tolerant so a template like the one below would be perfectly fine:

{%if
    product.getCategories()
%}
    <p>Categories:</p>
    <ul>
    {%foreach
         product.getCategories()
            as
         category
    %}
        <li>{{product.getTitle()} [{{   category   }}]</li>
    {%endforeach%}
    </ul>
{%endif%}

wol-soft/php-micro-template 适用场景与选型建议

wol-soft/php-micro-template 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 140.1k 次下载、GitHub Stars 达 16, 最近一次更新时间为 2018 年 04 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 wol-soft/php-micro-template 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 wol-soft/php-micro-template 我们能提供哪些服务?
定制开发 / 二次开发

基于 wol-soft/php-micro-template 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 140.1k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 16
  • 点击次数: 40
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 16
  • Watchers: 3
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2018-04-26