承接 asko/toretto 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

asko/toretto

Composer 安装命令:

composer require asko/toretto

包简介

A simple and extendable templating library.

README 文档

README

builds.sr.ht status coverage

A simple and extendable templating library built on top of the new \DOM\HTMLDocument of PHP 8.4.

Features

  • Simple syntax: Toretto is a superset of HTML, meaning that any valid HTML is also valid Toretto.
  • Good editor support: Because Toretto is a superset of HTML, it works in all editors without additional plugins.
  • Interpolation: You can interpolate values from a data array into your templates.
  • Modifiers: You can modify the interpolated values using modifiers.
  • Conditionals: You can show or hide blocks using simple (soon: complex) expressions.
  • Partials: You can include other templates inside your templates.
  • Loops: You can loop over iterable data.
  • Extendable: You can implement custom attribute parsers and expression modifiers.

Example syntax

<!DOCTYPE html>
<html>
<head>
    <title inner-text="{title}"></title>
</head>
<body>
    <h1 inner-text="{title}"></h1>
    
    <div class="posts" if="posts">
        <div foreach="posts as post">
            <h2 class="post-title">
                <a :href="/blog/{post.url}" inner-text="{post.title | capitalize}"></a>
            </h2>
            <div class="post-date" inner-text="{post.date | date:yyyy-MM-dd}"></div>
            <div class="post-content" inner-html="{post.body}"></div>
        </div>
    </div>
</body>
</html>

Installation

composer require asko/toretto

Usage

A simple example of how to use Toretto with default configuration looks like this:

use Asko\Toretto;

$toretto = new Toretto('<p inner-text="Hello {who}"></p>', ['who' => 'World']);
$html = $toretto->toHtml(); // <p>Hello World</p>

Attributes

Toretto works by parsing attributes in the template.

inner-text

Sets the inner text of the element to the value of the attribute.

Toretto template where title key is Hello, World!:

<h1 inner-text="{title}"></h1>

Results in:

<h1>Hello, World!</h1>

inner-html

Sets the inner HTML of the element to the value of the attribute.

Toretto template where content key is <p>Hello, World!</p>:

<div inner-html="{content}"></div>

Results in:

<div>
    <p>Hello, World!</p>
</div>

inner-partial

Sets the inner HTML of the element to the value of the parsed Toretto template. Inherits all the same data as the parent template.

Toretto template with data such as:

$data = [
    'title' => 'My Web Portal Thing',
    'header' => '<div class="header"><h1 inner-text="title"></h1></div>'
];

And the template is:

<div inner-partial="header"></div>

Results in:

<div>
    <div class="header">
        <h1>My Web Portal Thing</h1>
    </div>
</div>

outer-text

Sets the outer text of the element to the value of the attribute.

Toretto template where title key is Hello, World!:

<h1 outer-text="{title}"></h1>

Results in:

Hello, World!

outer-html

Sets the outer HTML of the element to the value of the attribute.

Toretto template where content key is <p>Hello, World!</p>:

<div outer-html="{content}"></div>

Results in:

<p>Hello, World!</p>

outer-partial

Sets the outer HTML of the element to the value of the parsed Toretto template. Inherits all the same data as the parent template.

Toretto template with data such as:

$data = [
    'title' => 'My Web Portal Thing',
    'header' => '<div class="header"><h1 inner-text="title"></h1></div>'
];

And the template is:

<div outer-partial="header"></div>

Results in:

<div class="header">
    <h1>My Web Portal Thing</h1>
</div>

if

Removes the element if the attribute is false-y.

Toretto template where show key is false:

<div if="show">Hello, World!</div>

Results in:

<!-- Empty -->

unless

Removes the element if the attribute is truthy.

Htmt template where hide key is true:

<div unless="hide">Hello, World!</div>

Results in:

<!-- Empty -->

foreach

Loops anything iterable.

For example, to loop over a collection of posts and then use post as the variable of each iteration, you can do something like this:

<div foreach="posts as post">
    <h2 inner-text="post.title"></h2>
</div>

If you do not care about using any of the iteration data, you can also entirely omit as ... from the iterative expression, like so:

<div foreach="posts">
    ...
</div>

And, you can also assign the key of the iteration to a variable, like so:

<div foreach="posts as index:post">
    <h2 :class="post-{post.index}" inner-text="post.title"></h2>
</div>

:* (Generic Value Attributes)

You can use the :* attribute to set any attribute on an element to the interpolated value of the generic value attribute.

For example, to set the href attribute of an element, you can use the :href attribute:

<a :href="/blog/{slug}">Hello, World!</a>

Results in:

<a href="/blog/hello-world">Hello, World!</a>

If the slug key is hello-world.

Modifiers

All interpolated values in expressions can be modified using modifiers. Modifiers are applied to the value of the attribute, and they can be chained, like so:

<h1 inner-text="{title | uppercase | reverse}"></h1>

Note that if you have nothing other than the interpolated variable in the attribute, then you can omit the curly brackets, and so this would also work:

<h1 inner-text="title | uppercase | reverse"></h1>

date

Parses the value into a formatted date string.

<p inner-text="published_at | date:YYYY-mm-dd"></p>

truncate

Truncates the value to the specified length.

<p inner-text="{title | truncate:10}"></p>

This also works on collections, so you can use truncate to limit items in an array as well.

Extending

Attribute Parsers

You can add (or replace) attribute parsers in Toretto by adding them to the $attributeParsers array, when creating a new instance of the Toretto class, like so:

use Asko\Toretto;
use Asko\Toretto\AttributeParsers;

$toretto = new Toretto('<p inner-text="Hello {who}"></p>', ['who' => 'World']);
$toretto->attributeParsers = [
    new InnerTextAttributeParser(),
    ...
];

$html = $toretto->toHtml(); // <p>Hello World</p>

A custom attribute parser must extend the BaseAttributeParser class, like so:

use Asko\Toretto\Core\Attributes\Query;
use Dom\Node;
use Dom\NodeList;

#[Query('//*[@inner-text]')]
class InnerTextAttributeParser extends BaseAttributeParser
{
    /**
     * @param NodeList<Node> $nodeList
     * @return void
     */
    #[\Override]
    public function parse(NodeList &$nodeList): void
    {
        foreach($nodeList as $node) {
            $parsedExpression = $this->parseExpression($node->getAttribute('inner-text'), serialize: true);
            $node->textContent = $parsedExpression;
            $node->removeAttribute('inner-text');
        }
    }
}

All attributes are matched via XTag queries, and you can match your attribute parser class with a XTag query by using the Query attribute.

List of built-in attribute parsers

  • Asko\Toretto\AttributeParsers\GenericValueAttributeParser - Parser the :* attributes.
  • Asko\Toretto\AttributeParsers\IfAttributeParser - Parser the if attributes.
  • Asko\Toretto\AttributeParsers\UnlessAttributeParser - Parser the unless attributes.
  • Asko\Toretto\AttributeParsers\InnerPartialAttributeParser - Parser the inner-partial attributes.
  • Asko\Toretto\AttributeParsers\InnerHtmlAttributeParser - Parser the inner-html attributes.
  • Asko\Toretto\AttributeParsers\InnerTextAttributeParser - Parser the inner-text attributes.
  • Asko\Toretto\AttributeParsers\OuterPartialAttributeParser - Parser the outer-partial attributes.
  • Asko\Toretto\AttributeParsers\OuterHtmlAttributeParser - Parser the outer-html attributes.
  • Asko\Toretto\AttributeParsers\OuterTextAttributeParser - Parser the outer-text attributes.
  • Asko\Toretto\AttributeParsers\ForeachAttributeParser - Parses the foreach attributes.

Expression Modifiers

You can add (or replace) expression modifiers in Toretto by adding them to the $expressionModiifers array, when creating a new instance of the Toretto class, like so:

use Asko\Toretto;
use Asko\Toretto\ExpressionModifiers;

$toretto = new Toretto('<p inner-text="Hello {who}"></p>', ['who' => 'World']);
$toretto->expressionModifiers = [
    new TruncateExpressionModifier(),
    ...
];

$html = $toretto->toHtml(); // <p>Hello World</p>

A custom expression attribute must implement the ExpressionModifier interface, like so:

<?php

use Asko\Toretto\Core\Attributes\Name;
use Asko\Toretto\ExpressionModifier;

#[Name('my-custom-modifier')]
class MyCustomExpressionModifier implements ExpressionModifier
{
    /**
     * @param mixed $value The value to be modified.
     * @param List<string>|null $opts Optional parameter.
     * @return mixed The modified expression.
     */
    public static function modify(mixed $value, ?array $opts = null): mixed
    {
        // Do something here.
    }
}

All expression modifiers need to have a name, and you can name your modifier with the Name attribute.

List of built-in expression modifiers

  • Asko\Toretto\ExpressionModifiers\TruncateExpressionModiifer - Truncates the value (both strings and collections).
  • Asko\Toretto\ExpressionModifiers\DateExpressionModiifer - Parses the value into a formatted date string.

asko/toretto 适用场景与选型建议

asko/toretto 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2 次下载、GitHub Stars 达 0, 最近一次更新时间为 2024 年 11 月 29 日, 在 PHP 生态内属于活跃度较高的组件。

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

围绕 asko/toretto 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 2
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 5
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-11-29