Open unitof opened 4 years ago
I took a look at the built-in cycle
tag to see if it handles quotes strings any differently, but it has the same behavior.
In other words, I don't think it's currently possible to write a {% cycle %}
tag that cycles between strings that include spaces, without literal "
s being included in the output.
(render "{% for i in items %}This is {% cycle \"an apple\" \"a banana\" %}. {% endfor %}" {:items (range 5)})
=>
"This is \"an apple\". This is \"a banana\". This is \"an apple\". This is \"a banana\". This is \"an apple\". "
Removing the literal quotes formats the output as desired, but—of course—treats the strings as four separate arguments:
(render "{% for i in items %}This is {% cycle an apple a banana %}. {% endfor %}" {:items (range 5)})
=>
"This is an. This is apple. This is a. This is banana. This is an. "
My desired output (in this specific example) is:
"This is an apple. This is a banana. This is an apple. This is a banana. This is an apple. "
Is there any tag syntax workaround to achieve that?
Note that this behavior also applies to tag-content
within block-style tags, which is actually where it's most relevant to my current work.
I definitely could add a (clojure.string/replace tag-content #"\"" "")
to my custom tag function, but that feels a bit icky.
Yeah, the best option at the moment is to do replace in the custom tag. I'd be open to adding support for handling quoted strings, but I probably won't be able to get around to it in the near future. If you'd be ok doing a PR for this, I could certainly help with that.
Alright, I'll see if I have time to learn how to approach this! But for now will do the replace
workaround.
Would you prefer that this change the default behavior (quotes always get removed, but that technically would break backward compatibility), or be a new setting on the parser, like (parser strip-quotes-on!)
?
Also would need to figure out how it could support quotes if they are desired in output strings. Probably via a double-escaping like \\\"
.
I think it would be best to avoid breaking changes to make upgrading smoother, so escaping would be preferable.
the render function could preserve the old behavior via and options field, or add the behavior via options.
Yeah, adding flags to hint behavior would be a reasonable approach here.
Obviously I didn't get to this—sorry! Still eager to try, but I'm very very new to Clojure so would take me a while and I may need help. Feel free to take it on someone else before I do!
Definitely no rush, and if you do get around to it then I'm happy to help with a review.
We rely on this behavior explicitly at work, with a custom tag we've added that takes arguments generated by a (JS) preprocessor. We check in the tag if the argument starts and ends with "
and if so, we attempt to read it as EDN to convert it to a plain string (and if that fails, we leave it as-is). We also use that as a hint that the argument string should then be render
'd -- and we wouldn't want to call render
on all (string) arguments.
Which is a long-winded way of saying "please don't change the default behavior but make this possible via some option to the render functions".
PR: https://github.com/yogthos/Selmer/pull/304 adds resolve-arg
which will return the literal without the double quotes. If you don't want to also render the arg if a template, you can just use (parse-literal arg)
from selmer.filter-parser. parse-literal
will remove the double quotes if any.
And new release 1.12.59 is up on Clojars with the feature.
Is it possible to have a quoted string as an argument to a tag, without the surrounding quotes being preserved in the output?
Selmer, as expected, does treat the quoted string as a single argument, but passes the string to the tag function with its quotes, escaped, as part of the string.
Or perhaps there's another notation which allows a string with spaces to be treated as a single argument?
Using
render-file
removes the need to escape the quotes in the template file, but still introduces them in the output:file.txt:
The
{% safe %}
tag has no discernible effect:file.txt: