Open tacman opened 1 year ago
Hmm, possible to only enable the components in the container under certain conditions? (So only one say menu component is ever available)
yes, or prioritize the components, so if there are multiple ones. Or namespace them?
Just brainstorming.
Again, I love Twig Components. I've converted all my macros (except the knp_menu) and most of my non-trivial twig functions/filters to Twig Components, and can't imagine going back.
I do wish PHPStorm was aware of them though!
Your idea does sound cool (using without namespacing). In principal, it allows switching "themes" easily.
Does adding a priority
work with service locators?
Does adding a
priority
work with service locators?
I still struggle with service locators, the compiler pass, etc.
On a related note (but I can open this in a new issue if that's appropriate), is there a way to implement a render call that bypasses the twig template altogether? I was playing around with rewriting the knp menu render twig template as a component:
https://github.com/KnpLabs/KnpMenu/blob/master/src/Knp/Menu/Resources/views/knp_menu.html.twig
Here's a block, for example.
{% block item %}
{% if item.displayed %}
{# building the class of the item #}
{%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %}
{%- if matcher.isCurrent(item) %}
{%- set classes = classes|merge([options.currentClass]) %}
{%- elseif matcher.isAncestor(item, options.matchingDepth) %}
{%- set classes = classes|merge([options.ancestorClass]) %}
{%- endif %}
{%- if item.actsLikeFirst %}
{%- set classes = classes|merge([options.firstClass]) %}
{%- endif %}
{%- if item.actsLikeLast %}
{%- set classes = classes|merge([options.lastClass]) %}
{%- endif %}
Whenever I see lots of twig logic, I wonder if it can be a component, and leverage using PHP. In this particular template, there's a trivial about of HTML, some open and close list tags (ul, li, div, span), and LOTS of logic for maintaining attributes.
In this case, a component might not even be the right answer, probably a custom menu renderer would be correct, but I was curious if there's a way to override the render call. If so, that could also be a spot to look for the other twig templates.
Again, just brainstorming. In my particular project, I gave up on theme switching and copies all the components into the new bundle. Eventually, I clean up the demo repo and my bundle enough so I can share it, I'm really pleased with using components in it.
I still struggle with service locators, the compiler pass, etc.
Ok, I will have to play with this.
is there a way to implement a render call that bypasses the twig template altogether
At one point we played with the idea of self-rendering components. We didn't implement because we couldn't think of a valid use-case but maybe this is it?
@kbond , any changes that would allow a custom template to be passed in? It looks like the template is stored private $template property of Attribute and set in the constructor, but there's no setter. If there were, maybe I could pass the template in as a property and set it in preMount?
What about having a $template
property on the component? Then in your component's configured template, do:
{{ include(template) }}
This could be injected into the component based on some kind of config or, if the property is public, using component('my_component', {template: 'custom_template.html.twig'})
hmm, interesting idea. I'll play around with that. Thanks.
I had a similar issue. I think it can be great to have the ability to set a template dynamically for a component. For example to have the ability to choose a template based on some configuration. What do you think about adding a function like withTemplate(): string in the Component class to be able to choose dynamically a template?
What do you think about adding a function like withTemplate(): string in the Component class to be able to choose dynamically a template?
What class would the method be on?
In the Component class
#[AsTwigComponent]
class MyComponent
{
public function __construct(
// binded config
string $templateBundlePath
) {}
#[WithTemplate]
public function getTemplate(): string
{
return $templateBundlePath . '/path/my_component.html.twig'
}
}
Revisiting this issue.
<twig:Alert theme='bootstrap5' type='danger'>Alert message</twig>
<twig:Alert theme='bootstrap4' type='danger'>Alert message</twig>
<twig:Alert theme='tailwind' type='warning'>Warning message</twig>
I think like the AlertComponent to render "templates/components/$theme/Alert.html.twig", rather than adding the theme logic to the single template, where I would be able to control the template to be rendered by setting a property.
As mentioned above, I could add a template property, but that moves a lot of logic to the call.
<twig:Alert template="@Mybundle/component/alert/tailwind.html.twig" type='warning'>Warning message</twig>
And realistically, the theme is going to be set somewhere else, injected into the component, then the component will figure out which template to use (like Symfony form themes).
Still just brainstorming. But I think dynamic templates would be useful at the component level, maybe something like the #[#WithTemplate] that @WebMamba suggests.
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
Hello? This issue is about to be closed if nobody replies.
I still like the idea of dynamically defining the template name. Twig is great for rendering, but some things are complicated to do when adding conditional logic.
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
I'm restructuring my theme bundle to accommodate swapping out specific stylesheets and javascript, and am not sure how to configure the twig components.
What I'm shooting for:
The goal is that free/open source projects can require sneat-bundle (which depends on bootstrap-bundle), and other projects that need another theme can do the same thing. Ideally, switching out themes would be as simply as uninstalling one and installing the other.
For example, imagine a CardComponent, which generates the HTML for https://getbootstrap.com/docs/5.0/components/card/ if bootstrap-bundle is installed, or fancier cards like https://demos.themeselection.com/sneat-bootstrap-html-admin-template-free/html/cards-basic.html if another theme is loaded. Obviously, the base component would take all the options available, and silently fail or display a warning if a particular feature wasn't implemented for that theme.
So the goal is that the developer (me) can simply
In theory this sounds doable, that it might be able to work the way symfony templates do, cascading through various directories until it finds the right component and template.
So in the example above, I'd like to first look for the component in velzon, my paid theme, and if it's not there, look in sneat, the free theme, and if it's not there, look in bootstrap, which will always been installed. Similarly, when looking for the card.html.twig template defined in the component
I'd like to cascade the templates.
Perhaps this isn't the right approach, or isn't worth the complexity. But I figured I'd ask. Thanks