1
Fork 0

Use jinja2 for rendering

It does multi-line tags, which are really useful
This commit is contained in:
Jake Howard 2024-10-17 14:13:17 +01:00
parent caed8daeda
commit b882bc44dd
Signed by: jake
GPG key ID: 57AFB45680EDD477
8 changed files with 35 additions and 105 deletions

View file

@ -2,7 +2,7 @@
title: Test
tags:
- tag-1
runtime_render: false
runtime_render: true
media: ./media.txt
---

View file

@ -4,3 +4,5 @@ gunicorn
markdown
chrono
django-debug-toolbar
django-jinja
jinja2-simple-tags

View file

@ -1,4 +1,3 @@
{% load core_tags %}
<head>
<title>{{ page.title }}</title>
</head>

View file

@ -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,13 +72,18 @@ 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)) is None:
cached_template = self._template_cache[self.slug] = Template(self.content, name=self.slug)
if cached_template := self._template_cache.get(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 {
"page": self
@ -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})

View file

@ -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

View file

@ -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())

View file

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

View file

@ -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'