PebbleTemplates / pebble

Java Template Engine
https://pebbletemplates.io
BSD 3-Clause "New" or "Revised" License
1.1k stars 168 forks source link

Request: {% escape "html" %} tag for multiline escaping #252

Open danneu opened 7 years ago

danneu commented 7 years ago

I'm building a documentation site where I have HTML in <pre> blocks.

This would be nice:

<pre>
{% escape "html" %}
    <h1>Hello world</h1>
{% endescape %}
</pre>

Since escape exists as a filter, it seems reasonable for it to also exist as a tag so it can be used on multiline content.

ebussieres commented 7 years ago

Sounds reasonable to me

mbosecke commented 7 years ago

There is an autoescape tag which can be used to turn off/on escaping as well as changing the escaping strategy. Is this what you're looking for?

danneu commented 7 years ago

IIRC autoescape only applies to how {{ interpolation }} is escaped.

I want to apply an explicit escaping strategy to a multiline block of text, which the escape filter alone cannot accomplish.

mbosecke commented 7 years ago

Okay, I think I understand. You want to escape the contents of the template itself, not just the dynamic results of the {{ expressions. If I'm understanding that correctly, it's a little odd because the contents of the template is completely static which means you could just write it as escaped in the first place:

<pre>
    &lt;h1&gt;Hello world&lt;/h1&gt;
</pre>

Another solution would be to pass the entire section as a variable to the template in order to have it escaped. What is your use case that you would benefit from escaping the static content within the template? I'm not optimistic that this is a common use case and this is probably better suited as a custom tag.

danneu commented 7 years ago

Since escape exists as a filter, a multiline version seems like a natural extension of the feature rather than bloat. It seems no more far-fetched than pluggable escaping strategies to a subset of a template via autoescape.

I ran into the use-case while building a documentation website where I wanted to demonstrate HTML snippets. Since I was writing the code examples into the template itself, I couldn't use the filter.

As you point out, a hack would've been to write each snippet on the server in multiline strings so that {{ snippet1 }}, {{ snippet2 }}, etc. on the template are escaped, but it's unwieldy with more than a handful of snippets.

I could escape the snippets myself, but escaped literals are hard to edit.

I can appreciate why you'd close the issue, I just wanted to share my use-case since this is a feature I've wanted before in other templating libraries.

For example, HAML has a feature where you can process a block of static content a certain way: http://haml.info/docs/yardoc/file.REFERENCE.html#filters

%p
  Our library is hosted on MaxCDN:
%p
  :escaped
    <script src="..."></script>

At any rate, thanks for hearing me out.

tboyce021 commented 7 years ago

Can't you already do this with the filter tag?

danneu commented 7 years ago

@tboyce021 This library / issue isn't fresh in my head. Can you give me an example that fulfills the pseudocode in my initial post?

jmewes commented 1 year ago

The link to the filter tag is now: https://pebbletemplates.io/wiki/tag/filter/

Given the foo variable contains the string <a href="https://example.com">Click me</a> Given a custom HtmlEscapting strategy (see https://pebbletemplates.io/wiki/guide/escaping) Given the following template

{% filter escape %}
    {{ foo }}
{% endfilter %}

When the template is rendered Then it will result in the string &lt;a href=&quot;https://example.com&quot;&gt;Click me&lt;/a&gt;