acalvino4 / twig-embed-implicit-default
扩展twig嵌入标签,允许使用隐式默认块
Requires
- php: >=8.0.2
- twig/twig: ^3.3
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
- phpunit/phpunit: ^10
This package is auto-updated.
Last update: 2024-09-12 01:40:53 UTC
README
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引入了破坏性变更。然而,它可能不会影响太多你的文件,可能相当容易解决,而且绝对值得。见 详情。
内容
理由
在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
或者只需在插件商店中找到它并从中安装。