Open rduplain opened 8 years ago
I'm not opposed to the feature, but I likely wouldn't have time to look at it in the near future. I could help with a pr if you're up for taking a look at it though.
One obvervation made during a short experimental session:
The node structure looks like this (when printed from render-template
:
user=> (selmer/render "{% if foo %} {{foo \n\n|json}} {% endif %}" {:foo 1})
:node #object[selmer.node.FunctionNode 0x648fa5b1 "selmer.node.FunctionNode@648fa5b1"]
:node #object[selmer.node.TextNode 0x74b5bb08 " "]
:node #object[selmer.node.FunctionNode 0x1da81d82 "selmer.node.FunctionNode@1da81d82"]
:node #object[selmer.node.TextNode 0x46d7ae7a " "]
:node #object[selmer.node.TextNode 0x151f9ad7 ""]
Maybe we can introduce a new type of node called a SkipTextNode
which ignores text nodes (or only blank text nodes?) during rendering, until the next SkipTextNode
.
And this SkipTextNode
gets inserted during parsing after reading the -%
sign?
Or maybe we could avoid generating these text nodes to begin with during parsing, when you encounter the minus signs.
Maybe I'm already thinking too much about the implementation, but it seems that this feature is possible to implement.
Yeah I think we could just skip emitting these nodes during parsing.
I have a very hacky version here:
https://github.com/yogthos/Selmer/compare/master...borkdude:whitespace-control
user=> (selmer/render "{% if foo %} \n hello \n {% endif %}" {:foo 1})
" \n hello \n "
user=> (selmer/render "{% if foo -%} \n hello \n {% endif %}" {:foo 1})
"hello"
I'm not sure if that's going into the right direction and also not sure if I'm a big fan of this magic syntax...
Would some other syntax work, like:
{% if foo }{% trim %}
Yolo. All the whitespace you want!
{% endtrim %}
{% endif %}
or is such a construct already possible, somehow?
Adding a trim tag should work, but there's still a problem of the tags themselves leaving a blank line. With the way the parser works currently, there would be blank lines where the tags which I assume wouldn't be desirable.
based on our slack brainstorming, let's go with {% if(trim, x, y) foo %}
syntax where tag name could be followed by some arguments in parens akin to a function call. These could provide hints for how tag body would be further manipulated, such as trimming white space or empty lines.
Adding this for posterity:
/cc @roklenarcic
Any progress on this feature? The proposed solutions don't work because they control whitespace inside the tag, when the problem is the whitespace outside the tag. Here's a minimal example of a block of text that cannot be produced by the current Selmer version:
- Level: {{ level }}
- Color: {{ color }}
- Shape: {{ shape }}
Where level, color and shape are all optional, and if missing their line shouldn't be rendered and there must be no empty lines.
I likely won't have a chance to look at this in the near future, but I'm definitely open for a PR to add the feature. I agree that it would be useful to provide hints to control the space outside the tags.
Throwing another use case in here. Lines containing only selmer tags (e.g., {% for thing in things %}
) end up as blank lines in the rendered output. For rendering plain-text (my use case) this is quite unfortunate.
In jinja this is handled with the trim_blocks and lstrip_blocks options (see https://jinja.palletsprojects.com/en/3.0.x/templates/#whitespace-control)
Btw, with the unlimited slack history.. here's the link to the thread screenshotted above: https://clojurians.slack.com/archives/C06MAR553/p1620329458137300
This is a use case I'd be most interested in addressing as well.
Jinja has a useful feature where you can strip out whitespace that you've added to make your template more readable:
http://jinja.pocoo.org/docs/dev/templates/#whitespace-control
In other words, adding a
-
to get-%}
will indicate that all whitespace should be removed between thefor
/if
/other statement and the next character.Feature request: any interest in adding this to Selmer?