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

Jinja2 #134

Closed
fjbardelli opened this issue Nov 9, 2022 · 2 comments
Closed

Jinja2 #134

fjbardelli opened this issue Nov 9, 2022 · 2 comments

Comments

@fjbardelli
Copy link

Is posible edit jinja2 templete?

@nad2000
Copy link

nad2000 commented Nov 1, 2024

@fjbardelli, it can be done using Jijna2 environment, that sets up by the Jinja2 engine (https://github.com/django/django/blob/main/django/template/backends/jinja2.py#L28), replacing the loader it sets up by default with Jinja2 ChoiceLoader using environment setting function according to https://docs.djangoproject.com/en/5.1/topics/templates/#django.template.backends.jinja2.Jinja2, for example (the Jinja2 environment module of your application, eg, jinja2_env.py):

def environment(loader=None, **options):
    if loader:
        options["loader"] = ChoiceLoader(
            [
                loader,
                DbLoader(),
            ]
        )

    env = Environment(**options)
    env.globals.update(
        {
            "get_messages": messages.get_messages,
            "crispy": crispy,
            "static": static,
            "url": lambda viewname, urlconf=None, current_app=None, *args, **kwargs: reverse(
                viewname=viewname,
                urlconf=urlconf,
                args=args or None,
                kwargs=kwargs or None,
                current_app=current_app,
            ),
        }
    )
    env.filters["basename"] = basename
    env.install_gettext_translations(translation)
    return env

where DbLoader is a Jinja2 loader that loads the templates from dbteplates:

...
from jinja2 import Environment, pass_context, BaseLoader, TemplateNotFound, ChoiceLoader
from dbtemplates.models import Template


class DbLoader(BaseLoader):

    def get_source(self, environment, template):
        # site = Site.objects.get_current()
        # site_id = site and site.pk
        site_id = settings.SITE_ID.site_id  # if it uses 'django-multisite'
        t = (
            Template.objects.filter(
                Q(name__exact=template), Q(sites__pk=site_id) | Q(sites__isnull=True)
            )
            .order_by("-sites__pk")
            .first()
        )
        if not t:
            raise TemplateNotFound(template)
        lc = t.last_changed
        pk = t.pk
        breakpoint()
        return (
            t.content,
            f"{template}::{pk}::{site_id}",
            lambda: not (Template.objects.filter(pk=pk, last_changed__gt=lc).exists()),  # TODO: ???
        )

I reckon it might be possible to improve performance by using the dbtemplates cache instead of a DB lookup for testing if the template was updated.

And the application config:

TEMPLATES = [
    {
        # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        ....
    },
    {
        "BACKEND": "django.template.backends.jinja2.Jinja2",
        "DIRS": [str(APPS_DIR / "jinja2")],
        "APP_DIRS": True,
        "OPTIONS": {
            "environment": "jinja2_env.environment",
            "extensions": ["jinja2.ext.i18n"],
        },
    },
]

That should work and search for Jinja2 templates if it fails to find the template in the filesystem.

@fjbardelli
Copy link
Author

Thank you very much for the answer

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