From b882bc44dd3f87823414e1f48f936ea7e5e7892e Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Thu, 17 Oct 2024 14:13:17 +0100 Subject: [PATCH] Use jinja2 for rendering It does multi-line tags, which are really useful --- content/core.Page/testdir/test2.md | 2 +- requirements.txt | 2 + .../core/{templates => jinja2}/content.html | 1 - yamdl_playground/core/models.py | 21 +++-- yamdl_playground/core/simple_tags.py | 86 ------------------- .../core/templatetags/__init__.py | 10 +++ .../core/templatetags/core_tags.py | 9 -- yamdl_playground/settings.py | 9 ++ 8 files changed, 35 insertions(+), 105 deletions(-) rename yamdl_playground/core/{templates => jinja2}/content.html (87%) delete mode 100644 yamdl_playground/core/simple_tags.py create mode 100644 yamdl_playground/core/templatetags/__init__.py delete mode 100644 yamdl_playground/core/templatetags/core_tags.py diff --git a/content/core.Page/testdir/test2.md b/content/core.Page/testdir/test2.md index 3038be5..b8c60c9 100644 --- a/content/core.Page/testdir/test2.md +++ b/content/core.Page/testdir/test2.md @@ -2,7 +2,7 @@ title: Test tags: - tag-1 -runtime_render: false +runtime_render: true media: ./media.txt --- diff --git a/requirements.txt b/requirements.txt index 4880143..b15f614 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ gunicorn markdown chrono django-debug-toolbar +django-jinja +jinja2-simple-tags diff --git a/yamdl_playground/core/templates/content.html b/yamdl_playground/core/jinja2/content.html similarity index 87% rename from yamdl_playground/core/templates/content.html rename to yamdl_playground/core/jinja2/content.html index f74ce32..be1e576 100644 --- a/yamdl_playground/core/templates/content.html +++ b/yamdl_playground/core/jinja2/content.html @@ -1,4 +1,3 @@ -{% load core_tags %} {{ page.title }} diff --git a/yamdl_playground/core/models.py b/yamdl_playground/core/models.py index 86116a3..adc921b 100644 --- a/yamdl_playground/core/models.py +++ b/yamdl_playground/core/models.py @@ -1,12 +1,12 @@ from django.db import models import markdown from django.utils.functional import cached_property -from django.template import Template, Context from django.core.files.storage import storages from django.core.files import File from pathlib import Path import os.path - +from django.template import engines +from django_jinja.backend import Origin class Tag(models.Model): __yamdl__ = True @@ -72,12 +72,17 @@ class Page(models.Model): @cached_property def content_template(self): - if self.runtime_render: - return Template(self.content, name=self.slug) + if cached_template := self._template_cache.get(self.slug): + return cached_template - if (cached_template := self._template_cache.get(self.slug)) is None: - cached_template = self._template_cache[self.slug] = Template(self.content, name=self.slug) - return cached_template + template = engines["jinja2"].from_string(self.content) + template.origin = Origin(name=self.slug, template_name=self.slug) + template.name = self.slug + + if not self.runtime_render: + self._template_cache[self.slug] = template + + return template def get_context(self): return { @@ -88,4 +93,4 @@ class Page(models.Model): if extra_context is None: extra_context = {} - return self.content_template.render(Context({**self.get_context(), **extra_context})) + return self.content_template.render({**self.get_context(), **extra_context}) diff --git a/yamdl_playground/core/simple_tags.py b/yamdl_playground/core/simple_tags.py deleted file mode 100644 index 0958c53..0000000 --- a/yamdl_playground/core/simple_tags.py +++ /dev/null @@ -1,86 +0,0 @@ -from inspect import getfullargspec, unwrap -from django.template.library import parse_bits, SimpleNode -from django.template.exceptions import TemplateSyntaxError -from functools import wraps - -class SimpleBlockNode(SimpleNode): - def __init__(self, nodelist, *args, **kwargs): - super().__init__(*args, **kwargs) - self.nodelist = nodelist - - def get_resolved_arguments(self, context): - resolved_args, resolved_kwargs = super().get_resolved_arguments(context) - - # Restore the "content" argument. - # It will move depending on whether takes_context was passed. - resolved_args.insert( - 1 if self.takes_context else 0, self.nodelist.render(context) - ) - - return resolved_args, resolved_kwargs - - -def simple_block_tag(register, takes_context=None, name=None): - def dec(func): - ( - params, - varargs, - varkw, - defaults, - kwonly, - kwonly_defaults, - _, - ) = getfullargspec(unwrap(func)) - function_name = name or func.__name__ - - @wraps(func) - def compile_func(parser, token): - tag_params = params.copy() - - if takes_context: - if len(tag_params) >= 2 and tag_params[1] == "content": - del tag_params[1] - else: - raise TemplateSyntaxError( - f"'{function_name}' is decorated with takes_context=True so" - " it must have a first argument of 'context' and a second " - "argument of 'content'" - ) - else: - if tag_params and tag_params[0] == "content": - del tag_params[0] - else: - raise TemplateSyntaxError( - f"'{function_name}' must have a first argument of 'content'" - ) - - bits = token.split_contents()[1:] - target_var = None - if len(bits) >= 2 and bits[-2] == "as": - target_var = bits[-1] - bits = bits[:-2] - - nodelist = parser.parse((f"end{function_name}",)) - parser.delete_first_token() - - args, kwargs = parse_bits( - parser, - bits, - tag_params, - varargs, - varkw, - defaults, - kwonly, - kwonly_defaults, - takes_context, - function_name, - ) - - return SimpleBlockNode( - nodelist, func, takes_context, args, kwargs, target_var - ) - - register.tag(function_name, compile_func) - return func - - return dec diff --git a/yamdl_playground/core/templatetags/__init__.py b/yamdl_playground/core/templatetags/__init__.py new file mode 100644 index 0000000..efb9289 --- /dev/null +++ b/yamdl_playground/core/templatetags/__init__.py @@ -0,0 +1,10 @@ +from django_jinja import library + +from jinja2_simple_tags import ContainerTag + +@library.extension +class MyTag(ContainerTag): + tags = {"mytag"} + + def render(self, caller=None): + return "foo{}bar".format(caller()) diff --git a/yamdl_playground/core/templatetags/core_tags.py b/yamdl_playground/core/templatetags/core_tags.py deleted file mode 100644 index c809abe..0000000 --- a/yamdl_playground/core/templatetags/core_tags.py +++ /dev/null @@ -1,9 +0,0 @@ -from yamdl_playground.core.simple_tags import simple_block_tag -from django import template - -register = template.Library() - - -@simple_block_tag(register, takes_context=True) -def mytag(context, content): - return "foo{}bar".format(content) diff --git a/yamdl_playground/settings.py b/yamdl_playground/settings.py index 6a659ca..4de11ff 100644 --- a/yamdl_playground/settings.py +++ b/yamdl_playground/settings.py @@ -58,6 +58,15 @@ TEMPLATES = [ ], }, }, + { + 'BACKEND': 'django_jinja.jinja2.Jinja2', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'app_dirname': "jinja2", + "match_extension": ".html" + } + }, ] WSGI_APPLICATION = 'yamdl_playground.wsgi.application'