Skip to content

Commit b4dca48

Browse files
committed
Add include_md template tag.
1 parent d74455e commit b4dca48

2 files changed

Lines changed: 78 additions & 7 deletions

File tree

coltrane/renderer.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,15 @@ class StaticRequest:
3131
path: str
3232

3333

34-
def _get_markdown_content_as_html(slug: str) -> Dict[str, Optional[Dict]]:
34+
def render_markdown_path(path) -> Dict[str, Optional[Dict]]:
3535
"""
36-
Converts markdown file based on the slug into HTML.
36+
Renders the markdown file located at path.
3737
"""
3838

39-
file_path = get_content_directory() / f"{slug}.md"
4039
markdown_extras = get_markdown_extras()
4140

4241
content = markdown_path(
43-
file_path,
42+
path,
4443
extras=markdown_extras,
4544
)
4645

@@ -51,7 +50,17 @@ def _get_markdown_content_as_html(slug: str) -> Dict[str, Optional[Dict]]:
5150
return (str(content), metadata)
5251

5352

54-
def _render_html_with_django(
53+
def _get_markdown_content_as_html(slug: str) -> Dict[str, Optional[Dict]]:
54+
"""
55+
Converts markdown file based on the slug into HTML.
56+
"""
57+
58+
path = get_content_directory() / f"{slug}.md"
59+
60+
return render_markdown_path(path)
61+
62+
63+
def render_html_with_django(
5564
html: str, context: Dict, request: HttpRequest = None
5665
) -> str:
5766
"""
@@ -112,7 +121,7 @@ def render_markdown(
112121
context["data"] = data
113122

114123
# Add rendered content to the context
115-
content = _render_html_with_django(html, context, request)
124+
content = render_html_with_django(html, context, request)
116125
context["content"] = mark_safe(content)
117126
template = context["template"]
118127

coltrane/templatetags/coltrane_tags.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
from typing import Dict
22

33
from django import template
4+
from django.template.base import Node
5+
from django.template.exceptions import TemplateSyntaxError
6+
from django.template.loader_tags import construct_relative_path
47
from django.utils.safestring import SafeString
58

6-
from coltrane.renderer import get_html_and_markdown
9+
from coltrane.renderer import (
10+
get_html_and_markdown,
11+
render_html_with_django,
12+
render_markdown_path,
13+
)
714
from coltrane.retriever import get_content_directory, get_content_paths
815

916

@@ -45,3 +52,58 @@ def directory_contents(context, directory: str = None) -> Dict[str, str]:
4552
contents.append(metadata)
4653

4754
return contents
55+
56+
57+
class IncludeMarkdownNode(Node):
58+
"""
59+
Based on: `django.template.loader_tags.IncludeNode`.
60+
"""
61+
62+
context_key = "__include_markdown_context"
63+
64+
def __init__(self, template, *args, **kwargs):
65+
self.template = template
66+
super().__init__(*args, **kwargs)
67+
68+
def render(self, context):
69+
"""
70+
Render the specified template and context.
71+
"""
72+
73+
template_name = self.template.resolve(context)
74+
75+
cache = context.render_context.dicts[0].setdefault(self, {})
76+
template = cache.get(template_name)
77+
78+
if template is None:
79+
template = context.template.engine.select_template((template_name,))
80+
cache[template_name] = template
81+
82+
(html, metadata) = render_markdown_path(template.origin.name)
83+
84+
return render_html_with_django(html, metadata)
85+
86+
87+
@register.tag("include_md")
88+
def do_include_md(parser, token):
89+
"""
90+
Load a markdown template and render it with the current context.
91+
92+
Based on: `django.template.loader_tags.do_include`.
93+
94+
Example:
95+
{% include "foo/some_include" %}
96+
"""
97+
bits = token.split_contents()
98+
99+
if len(bits) < 2:
100+
raise TemplateSyntaxError(
101+
"%r tag takes at least one argument: the name of the template to "
102+
"be included." % bits[0]
103+
)
104+
105+
bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
106+
107+
return IncludeMarkdownNode(
108+
parser.compile_filter(bits[1]),
109+
)

0 commit comments

Comments
 (0)