Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add whitespace control? #115

Open
rduplain opened this issue Feb 1, 2016 · 12 comments
Open

Add whitespace control? #115

rduplain opened this issue Feb 1, 2016 · 12 comments

Comments

@rduplain
Copy link

rduplain commented Feb 1, 2016

Jinja has a useful feature where you can strip out whitespace that you've added to make your template more readable:

{% for item in seq -%}
    {{ item }}
{%- endfor %}

This will yield all elements without whitespace between them. If seq was a list of numbers from 1 to 9, the output would be 123456789.

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 the for/if/other statement and the next character.

Feature request: any interest in adding this to Selmer?

@yogthos
Copy link
Owner

yogthos commented Feb 1, 2016

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.

@borkdude
Copy link
Contributor

borkdude commented May 7, 2021

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.

@yogthos
Copy link
Owner

yogthos commented May 7, 2021

Yeah I think we could just skip emitting these nodes during parsing.

@yogthos
Copy link
Owner

yogthos commented May 7, 2021

I think the relevant bit of code for this is here.

@borkdude
Copy link
Contributor

borkdude commented May 7, 2021

I have a very hacky version here:

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?

@yogthos
Copy link
Owner

yogthos commented May 7, 2021

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.

@yogthos
Copy link
Owner

yogthos commented May 7, 2021

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.

@borkdude
Copy link
Contributor

Adding this for posterity:

Screenshot 2021-05-10 at 21 23 11

/cc @RokLenarcic

@RokLenarcic
Copy link

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.

@yogthos
Copy link
Owner

yogthos commented Jan 31, 2022

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.

@Ramblurr
Copy link

Ramblurr commented Mar 6, 2022

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

@yogthos
Copy link
Owner

yogthos commented Mar 6, 2022

This is a use case I'd be most interested in addressing as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants