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

Allow String concat in Qute when used as parameters #46246

Open
ia3andy opened this issue Feb 13, 2025 · 7 comments
Open

Allow String concat in Qute when used as parameters #46246

ia3andy opened this issue Feb 13, 2025 · 7 comments
Labels
area/qute The template engine kind/enhancement New feature or request

Comments

@ia3andy
Copy link
Contributor

ia3andy commented Feb 13, 2025

Description

Currently, this doesn't work:
{page.image('partenaires/' + partenaire.image) }

or

{page.image('partenaires/%s'.fmt(partenaire.image)}

It would be a very nice feature to make it intuitive for Java devs.

As discussed with @mkouba we could also introduce eval: to allow doing:
{page.image(eval:'partenaires/{partenaire.image}'} (which is pretty cool also)

Implementation ideas

No response

@ia3andy ia3andy added the kind/enhancement New feature or request label Feb 13, 2025
@quarkus-bot quarkus-bot bot added the area/qute The template engine label Feb 13, 2025
Copy link

quarkus-bot bot commented Feb 13, 2025

/cc @mkouba (qute)

@mkouba
Copy link
Contributor

mkouba commented Feb 13, 2025

Just a bit of context.

The "'partenaires/' + partenaire.image" part from the {page.image('partenaires/' + partenaire.image) } output expression is parsed as a separate expression. There is a rule that a qute tag must start with a curly bracket the content of a tag must start with a digit, an alphabet character, underscore, or a built-in command: #, !, |, @, /. Thefore, an output expression may not start with a string literal. One practical implication is that we can safely ignore JSON, e.g. {"foo": true}.

We might try to relax this requirement for virtual method params but even then {'foo' + bar} will not work whilst {someString.concat('foo' + bar)} would work. Which is a bit weird and maybe even more confusing.

Now, I do understand that the current situation is not ideal at all and we need to find a better way to handle this. So far we have {page.image(str:fmt('partenaires/%s',partenaire.image))} which is not very nice.

I can imagine that something like {str:concat('partenaires/', partenaire.image)} works better.

Maybe a StringBuilder-like construct: {str:builder('partenaires/').append(partenaire.image)} or even {str:builder('partenaires/') + partenaire.image}.

I know that all these are just workarounds but I'm trying to find an acceptable solution without breaking existing stuff 🤷.

As discussed with @mkouba we could also introduce eval: to allow doing:
{page.image(eval:'partenaires/{partenaire.image}'} (which is pretty cool also)

I like the idea but it would have to be {page.image(eval:['partenaires/{partenaire.image}']} otherwise we're in the same troubles as with ^.

@ia3andy
Copy link
Contributor Author

ia3andy commented Feb 13, 2025

Just a bit of context.

The "'partenaires/' + partenaire.image" part from the {page.image('partenaires/' + partenaire.image) } output expression is parsed as a separate expression. There is a rule that a qute tag must start with a curly bracket the content of a tag must start with a digit, an alphabet character, underscore, or a built-in command: #, !, |, @, /. Thefore, an output expression may not start with a string literal. One practical implication is that we can safely ignore JSON, e.g. {"foo": true}.

We might try to relax this requirement for virtual method params but even then {'foo' + bar} will not work whilst {someString.concat('foo' + bar)} would work. Which is a bit weird and maybe even more confusing.

I think it's fine because you can do:
foo{bar} while you can't do it for virtual methods.

@mkouba
Copy link
Contributor

mkouba commented Feb 13, 2025

I think it's fine because you can do:
foo{bar} while you can't do it for virtual methods.

It's not fine because it's inconsistent. You would be able to do {page.image('partenaires/%s'.format(partenaire.image))} but not {'partenaires/%s'.format(partenaire.image))}.

@ia3andy
Copy link
Contributor Author

ia3andy commented Feb 13, 2025

@mkouba what's the point of doing: {'partenaires/%s'.format(partenaire.image))} ?

@mkouba
Copy link
Contributor

mkouba commented Feb 13, 2025

@mkouba what's the point of doing: {'partenaires/%s'.format(partenaire.image))} ?

That's just an example. It could be some more complex formatting or whatever.

@ia3andy
Copy link
Contributor Author

ia3andy commented Feb 13, 2025

What do you think about this consistent rule, make it works when you have parenthesis:
{('paternaire/' + foo)} or {page.image('paternaire/' + foo)} or {#let foo = ('hello/' + b)}

and explain in the doc that we have this limitation/rule to limit conflicts with underlying syntaxes..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/qute The template engine kind/enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants