mauricesnip / twig-elementary-bundle
以最基本的方式构建 Twig 组件,无需占用大量空间。
Requires
- php: ^7.4 || ^8.0
- twig/twig: ^2.0 || ^3.0
README
Twig Elementary Bundle
以最基本的方式构建 Twig 组件,无需占用大量空间。
请注意!
⚠️ 此扩展包处于早期开发阶段,不应在生产环境中使用。
以下示例需要安装 Twig 的 HtmlExtension
。有关如何安装此扩展的说明,请参阅 html_classes
文档。
安装
运行以下命令使用 Composer 安装此包:
composer require mauricesnip/twig-elementary-bundle
基本用法
首先从 element-entry.html.twig
继承,该文件提供了在 正常元素 和 空元素 之间自动切换的功能。
{# common/molecules/cards/card.html.twig #} {% extends '@MausTwigElementary/core/element-entry.html.twig' %} {# Config #} {% set tag_name = 'article' %} {% set base_class = 'card' %} {# Attributes #} {% set attributes = { class: html_classes( base_class|default, { ("#{base_class}--#{size|default}"): size|default, ("#{base_class}--#{theme|default}"): theme|default, 'is-active': is_active|default, }, ), } %}
使用上述模板,以下 include
{% include 'common/molecules/cards/card.html.twig' with { theme: 'primary', is_active: true, } %}
将渲染
<article class="card card--primary is-active"></article>
模板
element.html.twig
渲染正常元素。
区块
参数
element-void.html.twig
渲染空元素。继承自 element.html.twig
。
区块
参数
element-entry.html.twig
自动渲染正常或空元素。
有关区块和参数,请参阅上面关于正常和空元素的文档。根据提供的 tag_name
继承自 element.html.twig
或 element-void.html.twig
。
高级用法
如果您想从新创建的组件继承,请确保允许变量从其子组件接收值。继续使用 基本用法 示例
{# common/molecules/cards/card.html.twig #} {% extends '@MausTwigElementary/core/element-entry.html.twig' %} {# Config #} {% set tag_name = tag_name|default('article') %} {% set base_class = base_class|default('card') %} {# Attributes #} {% set attributes = { class: html_classes( element_class|default, base_class|default, { ("#{base_class}--#{size|default}"): size|default, ("#{base_class}--#{theme|default}"): theme|default, 'is-active': is_active|default, }, classes|default, ), ...attributes|default({}), } %}
变量覆盖
请注意,这还启用了 include
或 embed
的变量覆盖,例如
{% include 'common/molecules/cards/card.html.twig' with { base_class: 'item', element_class: 'block__item', tag_name: 'div', theme: 'primary', attributes: { id: 'specific-item', 'data-group': 'featured', }, } %}
将渲染
<div class="block__item item item--primary" id="specific-item" data-group="featured"></div>
attributes
特性
请注意,覆盖 attributes.class
将替换整个 class
属性,因为 Twig 不支持深度合并。合并也不会以任何方式连接字符串值。因此,以下 include
{% include 'common/molecules/cards/card.html.twig' with { attributes: { class: 'is-active', }, } %}
将渲染
<article class="is-active"></article>
因此,在 高级用法 示例中使用了 classes|default
来向最终输出添加类。在这种情况下,以下
{% include 'common/molecules/cards/card.html.twig' with { classes: html_classes( 'is-featured', 'w-100', ), element_class: 'block__card', theme: 'primary', } %}
将渲染
<article class="block__card card card--primary is-featured w-100"></article>
添加内容
您可以通过提供 contents
变量来提供内容,这主要用于文本内容。通过将 is_raw_contents
设置为 true
来支持标记。请参阅 关于 element.html.twig
的文档。
{# common/molecules/cards/card.html.twig #} ... {# Contents #} {% set contents = 'Lorem ipsum' %}
或者,您可能更希望覆盖内容的 block
。
{# common/molecules/cards/card.html.twig #} ... {# Contents #} {% block contents %} {% block body %} <div class="{{ "#{base_class}__body" }}"> {% block body_inner %} {% block title %} {% if title|default %} <h2 class="{{ "#{base_class}__title" }}">{{ title }}</h2> {% endif %} {% endblock %} {% endblock %} </div> {% endblock %} {% endblock %}
具体示例
骨架为许多不同风味(或类型)的组件提供了一个基础。以高级用法为例,再进一步
{# skeletons/cards/card.html.twig #} {% extends '@MausTwigElementary/core/element-entry.html.twig' %} {# Config #} {% set tag_name = tag_name|default('article') %} {% set base_class = base_class|default('card') %} {# Attributes #} {% set attributes = { class: html_classes( element_class|default, base_class|default, { ("#{base_class}--#{size|default}"): size|default, ("#{base_class}--#{theme|default}"): theme|default, ("#{base_class}--#{type|default}"): type|default, 'is-active': is_active|default, }, classes|default, ), ...attributes|default({}), } %} {# Element classes #} {% set body_class = html_classes( "#{base_class}__body", body_classes|default, ) %} {% set title_class = html_classes( "#{base_class}__title", title_classes|default, ) %} {% set text_class = html_classes( "#{base_class}__text", text_classes|default, ) %} {# Contents #} {% block contents %} {% block header %}{% endblock %} {% block image %}{% endblock %} {% block body %} <div class="{{ body_class|trim }}"> {% block body_inner %} {% block title %} {% if title|default %} <h2 class="{{ title_class|trim }}">{{ title }}</h2> {% endif %} {% endblock %} {% block text %} {% if text|default %} <p class="{{ text_class|trim }}">{{ title }}</p> {% endif %} {% endblock %} {% endblock %} </div> {% endblock %} {% block footer %}{% endblock %} {% endblock %}
并从上述骨架扩展出的产品卡片
{# common/molecules/cards/card-product.html.twig #} {% extends 'skeletons/cards/card.html.twig' %} {# Config #} {% set type = 'product' %} {# Super (use parent variables here) #} {% block contents %} {% set sku_class = html_classes( "#{base_class}__sku", sku_classes|default, ) %} {{ parent() }} {% endblock %} {# Body inner #} {% block body_inner %} {% block sku %} {% if sku|default %} <p class="{{ sku_class|trim }}">{{ sku }}</p> {% endif %} {% endblock %} {{ parent() }} {% endblock %}
这继承了所有内容,直至element.html.twig
,在过程中添加了功能。考虑到这一点,以下include
{% set some_size_variable = 'lg' %} ... {% include 'common/molecules/cards/card-product.html.twig' with { title: 'Fancy product', text: 'Lorem ipsum dolor sit amet consectetur adipiscing elit.', sku: 12345678, sku_classes: html_classes( { 'font-size-small': some_size_variable|default == 'sm', 'font-size-large': some_size_variable|default == 'lg', }, ), } %}
将渲染
<article class="card card--product"> <div class="card__body"> <p class="card__sku font-size-large">12345678</p> <h2 class="card__title">Fancy product</h2> <p class="card__text">Lorem ipsum dolor sit amet consectetur adipiscing elit.</p> </div> </article>
可视化
┌───────────────────┐
│ │
│ element.html.twig │ Handles tag name, start and end tag, attributes and contents
│ │
└─────────▲─────────┘
│
┌────────────┴────────────┐
│ │
│ element-entry.html.twig │ Handles element type (normal vs. void)
│ │
└────────────▲────────────┘
│
┌───────┴────────┐
│ │
│ card.html.twig │ Handles classes, structure, title and text
│ │
└───────▲────────┘
│
┌───────────┴────────────┐
│ │
│ card-product.html.twig │ Handles SKU and sku_classes
│ │
└────────────────────────┘