nette / latte

☕ Latte: the safest & truly intuitive templates for PHP. Engine for those who want the most secure PHP sites.
https://latte.nette.org
Other
1.13k stars 109 forks source link

Html object is escaped when used to output string inside an HTML tag #313

Open BernhardBaumrock opened 2 years ago

BernhardBaumrock commented 2 years ago

Bug Description

As discussed in this thread it is not possible to return markup that does not need the |noescape filter when used inside an HTML tag.

Description of the alfred() method: https://github.com/baumrock/RockFrontend/blob/82a6a33592dc0831cd0b435bf94d507e39f7c6ac/RockFrontend.module.php#L200-L222

Expected Behavior

<div {alfred($page)}>some markup</div>

This should add a custom html string like alfred='{some json here}' that is not escaped so that the resulting html can be read by JS

<div alfred='{some json here}'>some markup</div>

Current state

At the moment I have to use the |noescape filter all the time when using alfred():

<div {alfred($page)|noescape}>some markup</div>

PS: Not sure if that is a bug or a feature request, sorry if I picked the wrong one!

milo commented 2 years ago

The HTML object is whole HTML tag. That's why it is escaped.

There is another way - custom Latte tag. It is the most powerful approach but the most complicated one. Moreover, the Latte API changed between Latte v2 and v3 so if you want to support both, more code has to be written.

In Latte v2, the name for Latte tag used to be Latte macro and you can find plenty topics on forum. These days, people still talking about it as macros.

The result would look like (as n: attribute):

<div n:alfred="$page">
    some markup
</div>

or with tag-like syntax

<div>
    {alfred $page}
        some markup
    {/alfred}
</div>

Latte is always translated into PHP and by tag API, you can control that translation process. So you can add HTML tag atrributes, insert into HTML tag body or rename HTML tags. Just to transform Latte syntax into PHP code in any way you wish.

There is a tags documentation for Latte v3.

Or maybe describe whole Alfred mechanism on forum, maybe there is a simpler way. Like this with filter:

<div alfred="{$page|alfred}">...</div>
BernhardBaumrock commented 2 years ago

Thx @milo for those ideas. I don't think that this will work though. See here for a description of the alfred method with all its possible arguments: https://github.com/baumrock/RockFrontend/blob/82a6a33592dc0831cd0b435bf94d507e39f7c6ac/RockFrontend.module.php#L200-L222

As you can see the method returns a string and all I'd love to have is to tell LATTE not to escape that string. The HTML object does unfortunately not work because it will escape the string when it is placed inside an html tag - which is always the case:

<div {alfred($page)} class="foo bar">...</div>

I'd love to make alfred just return something like a Latte\Runtime\NoEscapeString that ends up unescaped in my template files whenever I call {alfred()}. That would be a feature request then I guess. But if the HTML object should also be able to be used inside HTML tags then it would be a bug :)