Skip to content

Commit 8107a9b

Browse files
committed
Application to store templates in database. Fixes ietf-tools#908
- Legacy-Id: 5077
1 parent ecc53e9 commit 8107a9b

13 files changed

Lines changed: 479 additions & 0 deletions

File tree

ietf/dbtemplate/__init__.py

Whitespace-only changes.

ietf/dbtemplate/forms.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django import forms
2+
3+
from ietf.dbtemplate.models import DBTemplate
4+
5+
6+
class DBTemplateForm(forms.ModelForm):
7+
8+
class Meta:
9+
model = DBTemplate
10+
fields = ('content', )

ietf/dbtemplate/migrations/0001_initial.py

Lines changed: 238 additions & 0 deletions
Large diffs are not rendered by default.

ietf/dbtemplate/migrations/__init__.py

Whitespace-only changes.

ietf/dbtemplate/models.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from django.db import models
2+
3+
from ietf.group.models import Group
4+
5+
6+
TEMPLATE_TYPES = (
7+
('plain', 'Plain'),
8+
('rst', 'reStructuredText'),
9+
('django', 'Django'),
10+
)
11+
12+
13+
class DBTemplate(models.Model):
14+
path = models.CharField(
15+
max_length=255,
16+
unique=True,
17+
blank=False,
18+
null=False,
19+
)
20+
title = models.CharField(
21+
max_length=255,
22+
blank=False,
23+
null=False,
24+
)
25+
help_text = models.TextField(
26+
blank=True,
27+
null=True,
28+
)
29+
template_type = models.CharField(
30+
max_length=10,
31+
choices=TEMPLATE_TYPES,
32+
default='rst',
33+
)
34+
content = models.TextField(
35+
blank=False,
36+
null=False,
37+
)
38+
group = models.ForeignKey(
39+
Group,
40+
blank=True,
41+
null=True,
42+
)
43+
44+
def __unicode__(self):
45+
return self.title

ietf/dbtemplate/resources/rst.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
%(html_body)s

ietf/dbtemplate/template.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import os
2+
import string
3+
from docutils.core import publish_string
4+
5+
from django.template import Template as DjangoTemplate, TemplateDoesNotExist, TemplateEncodingError
6+
from django.template.loader import BaseLoader
7+
from django.utils.encoding import smart_unicode
8+
9+
from ietf.dbtemplate.models import DBTemplate
10+
11+
12+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
13+
RST_TEMPLATE = os.path.join(BASE_DIR, 'resources/rst.txt')
14+
15+
16+
class Template(object):
17+
18+
def __init__(self, template_string, origin=None, name='<Unknown Template>'):
19+
try:
20+
template_string = smart_unicode(template_string)
21+
except UnicodeDecodeError:
22+
raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.")
23+
self.template_string = string.Template(template_string)
24+
self.name = name
25+
26+
def render(self, context):
27+
raise NotImplemented
28+
29+
30+
class PlainTemplate(Template):
31+
32+
def render(self, context):
33+
context_dict = {}
34+
for d in context.dicts:
35+
context_dict.update(d)
36+
return self.template_string.safe_substitute(context_dict)
37+
38+
39+
class RSTTemplate(PlainTemplate):
40+
41+
def render(self, context):
42+
interpolated_string = super(RSTTemplate, self).render(context)
43+
return publish_string(source=interpolated_string,
44+
writer_name='html',
45+
settings_overrides={
46+
'input_encoding': 'unicode',
47+
'output_encoding': 'unicode',
48+
'embed_stylesheet': False,
49+
'xml_declaration': False,
50+
'template': RST_TEMPLATE,
51+
})
52+
53+
54+
class Loader(BaseLoader):
55+
56+
def load_template_source(self, template_name, template_dirs=None):
57+
try:
58+
template = DBTemplate.objects.get(path=template_name)
59+
if template.template_type == 'rst':
60+
return (RSTTemplate(template.content), template)
61+
elif template.template_type == 'django':
62+
return (DjangoTemplate(template.content), template)
63+
return (PlainTemplate(template.content), template)
64+
except DBTemplate.DoesNotExist:
65+
raise TemplateDoesNotExist(template_name)
66+
67+
68+
_loader = Loader()
69+
70+
71+
def load_template_source(template_name, template_dirs=None):
72+
# For backwards compatibility
73+
import warnings
74+
warnings.warn(
75+
"'ietf.dbtemplate.template.load_template_source' is deprecated; use 'ietf.dbtemplate.template.Loader' instead.",
76+
PendingDeprecationWarning
77+
)
78+
return _loader.load_template_source(template_name, template_dirs)
79+
load_template_source.is_usable = True
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
<h1>Template: {{ template }}</h1>
5+
6+
<h2>Meta information</h2>
7+
<dl>
8+
<dt>Title</dt>
9+
<dd>{{ template.title }}</dt>
10+
<dt>Group</dt>
11+
<dd>{{ template.group }}</dd>
12+
<dt>Template type</dt>
13+
<dd>{{ template.get_template_type_display }}
14+
{% ifequal template.template_type "rst" %}
15+
<p>This template uses the syntax of reStructuredText. Get a quick reference at <a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">http://docutils.sourceforge.net/docs/user/rst/quickref.html</a>.</p>
16+
<p>You can do variable interpolation with $varialbe if the template allows any variable.</p>
17+
{% endifequal %}
18+
{% ifequal template.template_type "django" %}
19+
<p>This template uses the syntax of the default django template framework. Get more info at <a href="https://docs.djangoproject.com/en/dev/topics/templates/">https://docs.djangoproject.com/en/dev/topics/templates/</a>.</p>
20+
<p>You can do variable interpolation with the current django markup &#123;&#123;variable&#125;&#125; if the template allows any variable.</p>
21+
{% endifequal %}
22+
{% ifequal template.template_type "plain" %}
23+
<p>This template uses plain text, so no markup is used. You can do variable interpolation with $variable if the template allows any variable.</p>
24+
{% endifequal %}
25+
</dd>
26+
{% if template.help_text %}
27+
<dt>Extra info about this template</dt>
28+
<dd>{{ template.help_text }}</dd>
29+
{% endif %}
30+
</dl>
31+
32+
<h2>Edit template content</h2>
33+
<form action="" method="post">
34+
{{ form.as_p }}
35+
<input type="submit" value="Submit changes" />
36+
</form>
37+
{% endblock content %}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
<h1>Defined templates for group {{ group }}</h1>
5+
6+
{% if template_list %}
7+
<ul>
8+
{% for template in template_list %}
9+
<li><a href="{% url template_edit group.acronym template.id %}">{{ template }}</a></li>
10+
{% endfor %}
11+
</ul>
12+
{% else %}
13+
<p>There are no templates defined for this group.</p>
14+
{% endif %}
15+
{% endblock content %}

ietf/dbtemplate/urls.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.conf.urls.defaults import patterns, url
2+
3+
4+
urlpatterns = patterns('ietf.dbtemplate.views',
5+
url(r'^(?P<acronym>[\w.@+-]+)/$', 'template_list', name='template_list'),
6+
url(r'^(?P<acronym>[\w.@+-]+)/(?P<template_id>[\d]+)/$', 'template_edit', name='template_edit'),
7+
)

0 commit comments

Comments
 (0)