You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR was squashed before being merged into the 2.x branch.
Discussion
----------
[Twig] Embedded components
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| Tickets | Fix#300
| License | MIT
This adds a `{% component name %}` tag to allow rendering components and overriding their _slots_ (by using twig's native block system).
Example:
```twig
{# templates/components/alert.html.twig #}
<div{{ attributes.defaults({class: 'alert alert-'~type}) }}>
{% block default %}<strong>{{ type }}</strong> {{ message }}{% endblock %}
</div>
{# "embed" in another template: #}
{% component 'alert' with {message: 'embedded message', class: 'extra-class', role: 'alert'} %}
{% block default %} {# override "default slot (block)" #}
{{ parent() }} {# call parent "slot" #}
Custom stuff...
{{ this.message }} {# access component properties/methods as normal #}
{{ computed.someMethod }} {# all component features available #}
{% endblock %}
{% endcomponent %}
{# can still use the function as normal #}
{{ component('alert', {message: 'some message'}) }}
```
More Advanced Example:
```twig
{# templates/components/dialog.html.twig #}
<div{{ attributes }}>
<h1>{% block title %}Default Title{% endblock %}</h1>
<p>{% block body %}Default Body{% endblock %}</p>
<div>{% block footer %}Default Footer{% endblock %}</div>
</div>
{# "embed" in another template: #}
{% component dialog %} {# quotes can optionally be left off the component name #}
{% block title %}Custom Title{% endblock %}
{% block body %}Custom Body{% endblock %}
{% block footer %}Custom Footer{% endblock %}
{% endcomponent %}
```
Some notes:
1. Most code is copied and modified from twig's native `embed` tag
2. I really wanted to have a default slot to avoid the need for overriding the default block (see first example above) but couldn't figure out how to do this or if it's even possible. Maybe someone with a deeper knowledge of twig internals could help?
3. The `PreRender` event is still dispatched like normal but because of the nature of how this feature works, modifying the template via a listener is not supported.
4. Using with LiveComponent's is not supported and throws an exception if attempted. Perhaps some trickery could be added in the future to achieve but I think this feature adds enough value to stand on its own.
5. This with #283 could add more value I think - it would remove the need for simple components to be _backed by_ a component service.
**TODO:**
- [x] Update changelog
- [x] Tests
- [x] Docs
- [x] Clarify nomenclature, _nested_ components vs _embedded_ components
Commits
-------
b114594 [Twig] Embedded components
0 commit comments