redant/twig-components

在Twig中定义可重用的组件。

1.2.1 2024-09-10 12:50 UTC

This package is auto-updated.

Last update: 2024-09-10 12:50:54 UTC


README

Twig组件是强大、可重用且自动文档化的元素,您可以使用新的component标签在Twig模板中使用。Twig组件允许您快速构建和维护自己的UI工具包,其中每个按钮、表格或卡片只需设计一次,就可以在整个应用程序中使用。

这种方法在以下方面改善了开发人员的体验

  • 渲染(使用)组件的简单语法;
  • 当缺少必需参数时发出通知;
  • 当参数名拼写错误时提供有用的建议;
  • 当提供错误类型的数据时发出警告;
  • 参数排序的灵活性。

还有一个实用的Symfony包可用。

快速入门

安装

此扩展可以通过Composer安装

$ composer require redant/twig-components

或者在您的composer.json中直接安装

{
    "require": {
        "redant/twig-components": "~1.0"
    }
}

设置

您可以将扩展添加到Twig中,如下所示

use RedAnt\TwigComponents\Registry as ComponentsRegistry;
use RedAnt\TwigComponents\Extension as ComponentsExtension;

// Initialize Twig
$loader = new \Twig\Loader\FilesystemLoader($templateDir);
$loader->addPath($componentsDir, 'Ui'); // Creates a @Ui namespace for the specified dir
$twig = new \Twig\Environment($loader);

// Initialize Twig Components registry
$componentsRegistry = new ComponentsRegistry($twig);
$componentsRegistry->addComponent('ui.button', '@Ui/elements/button');
// ... add more components here

// Add the extension to your Twig environment
$componentsExtension = new ComponentsExtension($componentsRegistry);
$twig->addExtension($componentsExtension);

什么是组件?

组件在某种程度上受到了普通编程语言函数的启发。组件具有一组固定的参数,因此您不能使用在组件上未定义的参数。所有参数都会进行类型检查并自带文档。然后,完整的组件文档可以自动组装成一个Markdown文件文件夹。每个组件都必须提供包含配置选项的嵌套哈希,类似于我们之前使用的宏定义。

为什么要在模板中对类型检查如此严格?原因之一是我们希望能够将这些组件(以及它们的文档,正如您将看到的)作为技术涉及的组件设计师和前端导向的开发人员之间交流的手段。

Twig在设计上在很多方面都非常宽容,如果您拥有完整的知识,这很好,但它可能会阻碍不同技能或信息水平的人之间的沟通。我们不希望组件用户每次都必须深入研究特定组件的实现——我们希望他们能够从类似于我们常规代码的公共API中获取信息。这就是为什么我们强制执行更严格的使用:现在我们能够帮助用户纠正小错误或类型不匹配。

但说够了,让我们看看一个示例组件定义:按钮组件。

Twig组件定义了一系列具有严格类型、默认值和注释的属性,并指定了哪些属性是必需的。在实现您的组件时,每个属性都可以渲染为一个属性。只有当您将其标记为必需时,属性才是必需的。否则,您可以设置默认值。

{% component button {
    container:           { type: 'string', default: 'button', comment: 'HTML element, e.g. "button" (default) or "a"' },
    label:               { type: 'string', required: true, comment: 'Button text (rendered as raw HTML)' },
    classes:             { type: 'string[]', default: [ 'small' ], comment: 'Additional button classes'},
    some_object:         { type: 'Some\\Namespace\\SomeObject', comment: 'An implementation of a component' },
    absent_object:       { type: '?Some\\Namespace\\AbsentObject', comment: 'An implementation of a component which can be absent at any point' }
} with options %}

您会注意到这个文件开始有一个注释,这是可选的。如果存在,它将在渲染此组件的文档时使用。紧接着是实际的组件定义,在{% component %}标签中。为此按钮组件定义了三个参数,所有参数都是类型string,其中只有一个必需(按钮的label)。我们可以通过提供简短的描述(comment)和在preview参数中提供示例值来对每个属性进行文档化。

此外,Twig组件强制执行一些最佳实践以促进组件之间的一致性,例如

  1. 文件名必须与组件名相同(即,button.html.twig必须定义名为button的组件);
  2. 仅使用蛇形大小写(snake_case)变量名;
  3. 不要在注释结尾处使用句号。

好的,上一个可能感觉有点随意或严格,但相信我,如果你的参数描述有统一性,你的文档看起来会好很多。

这个按钮组件将生成一个包含所有属性的Twig变量button,其值来自options变量或指定的默认值。

options中的每个值都会被检查其名称、类型,以及对于必需属性,是否已定义。值可以是引用对象的类型。如果对象不一定总是可用,如absent_object,你可以在其前加一个?来标记类型为可空,在这种情况下,将避免错误。

用法

每个定义的组件都可以通过一个引用Twig组件服务的Twig全局变量访问,实际上将组件放在了component命名空间中。例如,可以在任何Twig模板中使用component.button()来访问button组件。

如果你不喜欢“component”这个名字,我们在下一节中会解决这个问题。

{{ component.button({
    container: 'a',
    label: 'Click me',
    classes: [ 'large' ]
}) }}

由于所有指定的属性都会被检查,一个像{{ component.button({ lable: 'Click me' })这样的拼写错误将被检测到。此外,{{ component.button({}) }}将抛出运行时错误,因为label属性是必需的。

给组件提供的哈希值首先会检查与组件定义的名称一致性。例如,如果你不小心把lable写成了label,Twig Components会给出一个友好的运行时错误消息:组件 "button" 不包含属性 "lable"。你是想指 "label" 吗?

它还进行类型检查:当你提供一个数组作为url时,它会失败。每个参数都会使用is_stringis_boolis_intis_floatis_array进行检查。参数还可以强制指定特定的PHP类,在这种情况下,会使用instanceof检查。这确保了你会在没有正确使用组件时立即注意到。

注意:在可重用的包中,始终使用render_component()函数,因为用户可能已经定义了一个不同的组件全局变量(见下文)。

{{ render_component('button', {
    container: 'a',
    label:     'Click me',
    classes:   [ 'large' ]
}) }}

一些示例包含在doc文件夹中。

全局变量

如果你不喜欢定义组件的全局变量的名称,请使用扩展的$globalVariable参数来更改它。

$componentsExtension = new ComponentsExtension($twig, 'ui');

这将注册按钮组件为ui.button()

注意:如果你将前缀设置为false,则不会为定义的组件注册任何Twig全局变量。然后,你只能使用render_component函数来渲染组件。

许可证

此库受MIT许可证许可 - 有关详细信息,请参阅LICENSE文件。

Twig组件由Gert Wijnalda gert@redant.nl构思,并受到Pierre Stoffe的这篇文章的启发

本文档的部分内容首先出现在文章'Taming Twig'中,最初发表在2019年4月php[architect]杂志的第四期。

Twig组件的代码和本文档都得到了RedAnt同事宝贵的反馈,尤其是Vincent Vermeulen、Rico Humme、Florian Käding和Martijn van Beek。感谢你们,伙计们!