lektor / lektor

The lektor static file content management system

Home Page:https://www.getlektor.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

support alternative jinja environments

bbbart opened this issue · comments

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?

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.

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.

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.)