acalvino4/twig-embed-implicit-default

扩展twig嵌入标签,允许使用隐式默认块

1.0.1 2023-05-04 19:29 UTC

This package is auto-updated.

Last update: 2024-09-12 01:40:53 UTC


README

License Build Status

Test Coverage Phpstan Level Easy Coding Standard

TLDR

{% embed 'wrapper.twig' %}
  Default block content
{% endembed %}

{# wrapper.twig #}
<div class='bg-slate-300'>
  <div class='max-w-7xl py-16 '>
    <p>{% block default '' %}</p>{# --> renders "Default block content" #}
  </div>
</div>

警告 此扩展对twig引入了破坏性变更。然而,它可能不会影响太多你的文件,可能相当容易解决,而且绝对值得。见 详情

内容

  1. 理由
  2. 用法
  3. 入门

理由

在vanilla twig中,要通过嵌入覆盖父模板的插槽,我们需要声明一个块。

{% embed 'wrapper.twig' %}
  {% block content %}
    <p>This is default block content</p>
  {% endblock %}
{% endembed %}

{# example wrapper.twig #}
<div class='bg-slate-300'>
  <div class='max-w-7xl py-16 '>
    {% block content %}{% endblock %}
  </div>
</div>

遵循最佳实践以保持代码模块化和简洁,通常会为各种代码块创建组件,但这样会导致标记相当臃肿且难以阅读,尤其是在开始嵌套时(这里只有两层!)

{% embed 'wrapper.twig' %}
  {% block default %}
    <p>
      This is a CTA, so naturally it includes a
      {% embed 'button.twig' %}
        {% block default %}Button{% endblock %}
      {% endembed %}
    </p>
  {% endblock %}
{% endembed %}

显式块声明对于扩展布局很有用(例如,你可能需要'header'、'footer'和'sidebar'),但在大多数情况下,embed可能只是用来包含需要传递一些内容的组件,而对于这些情况,通常只需要一个内容插槽。

因此,我们牺牲了基本情况的简单性以获得更大的灵活性...但如果我们能够两者兼得呢?

用法

此twig扩展允许在嵌入中使用隐式默认块

{% embed 'wrapper.twig' %}
  <p>This is default block content</p>
{% endembed %}

{# same as this, which still will work #}
{% embed 'my_subtemplate.twig' %}
  {% block default %}
    <p>This is default block content</p>
  {% endblock %}
{% endembed %}

上面的更长的示例可以变成

{% embed 'wrapper.twig' %}
    <p>
      This is a CTA, so naturally it includes a
      {% embed 'button.twig' %}Button{% endembed %}
    </p>
{% endembed %}

要指定默认内容在组件模板中的位置,请遵循上面的wrapper.twig示例,或者,如果你的默认块没有/简单的默认内容,你可以使用twig的块快捷语法

{% block default %}{% endblock %}
{# same as #}
{% block default '' %}

这是因为此扩展所做的只是将嵌入内的初始内容解析为名为'默认'的块。

注意

隐式默认内容可以与(任意数量的)命名块组合

{% embed 'wrapper.twig' %}
  <p>This is default block content</p>
  {% block special_slot %}
    Special content
  {% endblock %}
{% endembed %}

{# example wrapper.twig #}
<div class='bg-slate-300'>
  <div class='max-w-7xl py-16 '>
    {% block default '' %}
    {% block special_slot '' %}
  </div>
</div>

隐式默认内容需要放置在所有显式块之前(见此问题

{# Will throw error: "A template that extends another one cannot include content outside Twig blocks." #}
{% embed 'wrapper.twig' %}
  {% block special_slot %}
    Special content
  {% endblock %}
  <p>This is default block content</p>
{% endembed %}

如果你既有隐式默认内容又有显式默认块,将会抛出错误(就像声明了两个同名块一样)

{# Will throw error: "The block 'default' has already been defined" #}
{% embed 'wrapper.twig' %}
  <p>This is default block content</p>
  {% block default %}
    Other default content???
  {% endblock %}
{% endembed %}

破坏性变更

默认情况下,twig不允许在embed标签内部输出内容,但在此扩展中,它不会改变任何已定义的行为;它只定义了以前是错误的内容。然而,twig允许在这种情况下使用非输出内容,例如

{% embed 'wrapper.twig' %}
  {% set a = 'foo bar' %}
  {% block content %}
    <p>{{ a }}</p>
  {% endblock %}
{% endembed %}

使用此扩展,那个set标签会被吸收为默认块的一部分,而下面的a将未定义。

在这种情况下,解决方案很简单:将set标签移出embed作用域。我怀疑大多数此类更改都将很容易适应此扩展。如果你遇到更复杂的情况,请提交问题,我将尝试处理或记录该情况。

入门

composer require acalvino4/twig-embed-implicit-default

然后根据你的框架适当注册扩展。

Craft CMS

由于我主要是一位Craft开发者,所以我创建了一个插件,它包装了这个包,因此将其包含到你的站点中就像其他插件一样简单。

composer require acalvino/craft-embed-implicit-default
./craft plugin/install embed-implicit-default

或者只需在插件商店中找到它并从中安装。