1
Fork 0

Optionally render pages at runtime

This commit is contained in:
Jake Howard 2024-08-03 14:02:33 +01:00
parent babec7cc2d
commit 5044f6d822
Signed by: jake
GPG key ID: 57AFB45680EDD477
3 changed files with 26 additions and 4 deletions

View file

@ -2,6 +2,7 @@
title: Test
tags:
- tag-1
runtime_render: false
---
# Heading

View file

@ -1,7 +1,7 @@
from django.db import models
import markdown
from django.utils.functional import cached_property
from django.template import Template
from django.template import Template, Context
class Tag(models.Model):
__yamdl__ = True
@ -19,6 +19,7 @@ class Page(models.Model):
title = models.CharField(max_length=255)
raw_content = models.TextField()
runtime_render = models.BooleanField(default=False)
content = models.TextField()
toc = models.JSONField()
slug = models.CharField(max_length=128, unique=True, db_index=True, default=None, null=True)
@ -35,12 +36,18 @@ class Page(models.Model):
data["raw_content"] = content
data["content"] = md.convert(content)
data["toc"] = {
"html": md.toc,
"tokens": md.toc_tokens
}
instance = cls.objects.create(**data)
instance = cls(**data)
if not instance.runtime_render:
instance.content = instance.render_content()
instance.save()
if tags:
instance.tags.set(tags)
@ -49,6 +56,20 @@ 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)
return cached_template
def get_context(self):
return {
"page": self
}
def render_content(self, extra_context=None):
if extra_context is None:
extra_context = {}
return self.content_template.render(Context({**self.get_context(), **extra_context}))

View file

@ -2,8 +2,8 @@ from .models import Page
from django.http import HttpResponse
from django.db import connections
from django.shortcuts import get_object_or_404, render
from django.template import Context
from django.views.decorators.cache import cache_page
from django.utils.safestring import mark_safe
def search(request):
@ -19,7 +19,7 @@ def content(request, slug):
return render(request, "content.html", {
"page": page,
"content": page.content_template.render(Context({"request": request, "page": page}))
"content": page.render_content({"request": request}) if page.runtime_render else mark_safe(page.content)
})
cached_content = cache_page(600, cache="mem")(content)