ventojs / vento

🌬 A template engine for Deno & Node
https://vento.js.org/
MIT License
153 stars 9 forks source link

Tag `autoTrim` plugin #35

Closed wrapperup closed 4 months ago

wrapperup commented 4 months ago

This adds a new plugin (unused by default) called autoTrim, which automatically trims away logic tags, or tags that don't render anything.

By default, the tags that are trimmed by default are: set, if, else, for, function (and async), export, import, comments and JavaScript.

The plugin also takes options:

env.use(autoTrim({
  tags: [...]
});

If enabled, any of the listed tags will be trimmed away, as if it didn't exist in the markup. It respects newlines, so it only snips out the tag, while preserving your markup.

For example,

{{ if true }}
  Hello, {{ name }}!
  {{ set variable = 10 }}
{{ /if }}

would output

  Hello, Name!

instead of


  Hello, Name!
oscarotero commented 4 months ago

Thanks! Now that we have the token preprocessors, I was thinking of moving the space trimming to a preprocessor. So probably I need to do this change before implementing this.

Also, I found some issues with this implementation:

<ul>
  {{ for n of 3 }}
  <li>
    Number: {{ n }}
  </li>
  {{ /for }}
</ul>

Generate the following input (removing the spaces generated by the for and/for tags, but not {{ n }}).

<ul>
  <li>
    Number: 1
  </li>
  <li>
    Number: 2
  </li>
  <li>
    Number: 3
  </li>
</ul>

Your implementation removes all spaces, even the spaces after the colon Number:1 instead of Number: 1.

<ul><li>
    Number:1</li><li>
    Number:2</li><li>
    Number:3</li></ul>
wrapperup commented 4 months ago

It should work only for some tags, not all. For example, conditional tags like for or if should be trimmed automatically but printing variables should't. What I would like to do is, with the following code:

I had the same thought, but it would require a change to tag plugins I think. The tokenizer needs to be aware of tags that are purely evaluated (if/else, for, set, etc), vs tags that output stuff (include, layout, value interpolation). So plugins that add tags would need to register their tags.

oscarotero commented 4 months ago

Hi. I saw that you update this PR to implement the autotrim option in the trim token preprocessor. I think it should be a different preprocessor. The trim I've added just re-implement the current behavior under a preprocessor and it's enabled by default.

The autotrim option should be a different preprocessor, that the user can use but not enabled by default (at least for now). This is an example of how I imagine it:

const tmpl = vento();

tmpl.use(autotrim({
  tags: ["if", "/if", "for", "/for", "import", ...etc] // Default values
));

The trim is different as with the - character, because it should trim only until a linebreak is found. For example:

<p>
  {{ if salute }}
  Hello
  {{ /if }}
</p>

The idea is to output this:

<p>
  Hello
</p>

So the trim should be:

oscarotero commented 4 months ago

Fantastic work. Thank you so much!