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

support alternative jinja environments #1091

Open
bbbart opened this issue Nov 15, 2022 · 3 comments
Open

support alternative jinja environments #1091

bbbart opened this issue Nov 15, 2022 · 3 comments

Comments

@bbbart
Copy link

bbbart commented Nov 15, 2022

In a plugin I'm writing, I wanted to change the jinja env, like so:

self.env.jinja_env.variable_start_string = r"\VAR{"
self.env.jinja_env.variable_end_string = "}"

in on_setup_env.

This seemed to work fine at first, but eventually I bumped into trouble at strange and (for me) unexpected places. For example, the field type select stopped working.

Eventually I figured out that Lektor is assuming in multiple locations in its source that the variable start and end strings are the default {{ and }}, for example in line 4 of https://github.com/lektor/lektor/blob/master/lektor/environment/expressions.py.

A quick test revealed to me that, at least at that particular spot, Lektor has access to the updated jinja environment settings, making this an easy fix.

Would there be an interest to support this case of alternative jinja settings in Lektor?

@dairiki
Copy link
Contributor

dairiki commented Nov 16, 2022

I'm basically open to supporting this use case, but I think doing it in a clean manner is tricky.

If I understand correctly, you are suggesting changing this:

env.jinja_env.from_string("{{ __result__(%s) }}" % expr)

to

env.jinja_env.from_string(f"{jinja_env.variable_start_string} __result__({expr!s}) {jinja_env.variable_end_string}")

What if the user configures variable_start_string to something that conflicts with any of our internal expressions? E.g. (and admittedly contrived example): what if variable_start_string = "__"?

Do we really want to change the syntax for settings like [children] slug_format (whose default value is "{{ this._id }}")? (Other examples of jinja-expanded settings include the source, item_key and item_label settings for select and checkboxes fields.)

One option might be to maintain the default {{ }} delimiters for those internally evaluated expressions?
(I think this could be done in a fairly straightforward manner using jinja environment overlays.)
I have not thought this trough fully, however. I can see opportunity for confusion in this route, too.

@bbbart
Copy link
Author

bbbart commented Nov 16, 2022

I didn't look into it in much detail, but yes, that basically would be my suggestion.

You are right though that this might lead to strange (and potentially insecure?) behaviour if the variable_start_string is set to something 'funny'. However, perhaps that could be mitigated simply with a short denylist?

Your suggestion of using jinja environment overlays seems wonderful though for internally evaluated expressions, indeed.

I'm not sure what the problem would be with "changing the syntax for settings like...", since that's basically up to the user to decide. In my case, indeed, I had to change all label values in my [model]s, for example.

@dairiki
Copy link
Contributor

dairiki commented Nov 16, 2022

I'm not sure what the problem would be with "changing the syntax for settings like...", since that's basically up to the user to decide. In my case, indeed, I had to change all label values in my [model]s, for example.

Yes, that's another example of a jinja-evaluated setting.

At this point, I guess (still not necessarily having thought things through fully) I'd suggest allowing customization of the Jinja syntax settings for the templates while leaving the Jinja syntax settings as they are (essentially, the Jinja defaults) for all the jinja-evaluated settings.

Again I think this can be achieved in a fairly straightforward manner by using a Jinja environment overlay for evaluating the "internal", jinja-evaluated settings while using the main (potentially customized) environment for evaluating the templates. (I think we want to share any custom globals and filters between those two environments.)

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

No branches or pull requests

2 participants