latte
latte copied to clipboard
Support for n:embed
- Explain your intentions
Currently it's possible to define component with n:define
, like this
<button n:define="UiBtnPrimary, $type = 'solid'" data-type="{$type}" class="ui-btn bg-primary bg-opacity-10 font-normal">
<span n:block="title"></span>
</button>
But it's not currently possible to embed it same way with n:embed
, but latte plugin in phpstorm recognize this as valid latte attribute?
- It's up to you to make a strong case to convince the project's developers of the merits of this feature
I think that n:
macros are strong feature in latte, that no other php/js template engine has. With the strong adoption of TailwindCSS or AlpineJS, the n:define
and n:embed
would be strong feature for reusable UI components. You could define UI component with n:define
and then reuse it in the code with n:embed
. So there wouldn't be a lot of duplicated code with the same component. That's currently not possible to do in a good way with the other php/js template engines, and seems latte is one step away from this feature.
To embed that defined component, it's currently only possible to do with {embed}
, like this
{embed UiBtnPrimary, $type = 'outline'}
<span n:block="title">Hello World</span>
{/embed}
But this has it's limitations, let's say you want to extend the component with new classes, or attributes. You would have to define it as params in the n:define
and add it as variables in the brackets {}
, which could cause problems with tailwindcss detecting the classes, or other purgecss
plugins.
Something like this would be much better and easier to use
<button n:embed="UiBtnPrimary" data-action="click->lib-dialog#show" data-action-url="path.json">
<span n:block="title">Hello World</span>
</button>
Which would output to
<button data-type="outline" class="ui-btn bg-primary bg-opacity-10" data-action="click->lib-dialog#show" data-action-url="path.json">
<span>Hello World</span>
</button>
Even better would be if define
had something like js has <slot></slot>
, so you wouldn't need to write block
in embed
everytime.
<button n:define="UiBtnPrimary, $type = 'solid'" data-type="{$type}" class="ui-btn bg-primary bg-opacity-10 font-normal">
{slot}{/slot}
</button>
<button n:embed="UiBtnPrimary" data-action="click->lib-dialog#show" data-action-url="path.json">
Hello World
</button>
For a big projects that reuse a lot of UI components this would be a massive improvement. In @newlogic-digital we noticed this ourselfs. We have a lot of UI components and templates in our projects, and if something like n:embed
was possible it would result into reducing a lot of duplicate code. We try to use embed
and include
when possible, but it's not always ideal.
- Please support my efforts in maintaining this project at https://github.com/sponsors/dg
We would love to support nette and latte directly! I've sended a few emails and contacted you on twitter with no response 😞
This could probably be done, with the caveat that attributes can only be added and the tag name cannot be changed. So this wouldn't work properly:
<button n:embed="UiBtnPrimary" data-type="different type">
...
</button>
<div n:embed="UiBtnPrimary">
...
</div>
ad {slot}
: a related thought https://forum.nette.org/cs/35161-napad-embed-s-anonymnim-blokem
Has there been any movement on this? Is there an alternate solution? I was thinking of custom HTML tags, similar to Web Components in the browser.
template:
<button class="py-2 px-4 bg-blue-500 text-white font-semibold">
<span><slot></slot></span>
</button>
usage:
<x-button class="button-modifier">
Hello World
</x-button>
output:
<button class="py-2 px-4 bg-blue-500 text-white font-semibold button-modifier">
<span>Hello World</span>
</button>