-
-
Notifications
You must be signed in to change notification settings - Fork 357
[RFC][Twig] "Anonymous" components #283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
e80cdbc
to
a6f28a6
Compare
seem weird to have direct html, what about something like this? {# path/to/template.html.twig #}
- <div{{ attributes }}>{{ prop1 }}</div>
+ {% component 'my_component' %}<div{{ attributes }}>{{ prop1 }}</div>{% endcomponent %}
{# render: (attributes *must* be sent as a "sub-key" #}
- {{ component('path/to/template.html.twig', { prop1: 'value', { attributes: { class: 'mb-1' } } }) }}
+ {{ component('my_component', { prop1: 'value', { attributes: { class: 'mb-1' } } }) }} |
I'd love to see a rough example of what this might look like with anonymous components to give more context :) |
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
I'm shelving this for now. There is currently little benefit to using this over Twig's standard include/embed. Using the attributes feature is the only useful thing but they have to be passed as an If anything, we could explore adding an |
This is pretty rough still but looking for input. This is basically
include()
but with theattributes
system available.This feature will be much more useful once/if embedded components are added. You'd be able to have anonymous components with slots.
TODO:
templates/components/*
, I think we should allow: