Skip to content

Instantly share code, notes, and snippets.

@nicoknoll
Created July 30, 2019 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicoknoll/db91c8b72588c147c8b76dc69ea4e2f2 to your computer and use it in GitHub Desktop.
Save nicoknoll/db91c8b72588c147c8b76dc69ea4e2f2 to your computer and use it in GitHub Desktop.
from django.template.loader import get_template
class ValidationError(Exception):
pass
class Field:
def __init__(self, default=None, required=False, allowed_type=None):
self.allowed_type = allowed_type
self.default = default
self.required = required
def clean(self, value=None):
default = self.default() if callable(self.default) else self.default
value = value or default
self.validate(value)
return value
def validate(self, value=None):
if self.allowed_type and not isinstance(value, self.allowed_type):
msg = '{} has to be of type {}.'
raise ValidationError(msg.format(value, self.allowed_type))
if self.required and value is None:
raise ValidationError('Field is required.')
class TemplateComponent:
template_name = None
def __init__(self, **data):
assert self.template_name is not None
self.fields = self.get_fields()
self.context = {
k: field.clean(data.get(k)) for k, field in self.fields.items()
}
def get_fields(self):
return {
k: getattr(self, k) for k in dir(self)
if isinstance(getattr(self, k), Field)
}
def render_with_context(self, context):
template = get_template(self.template_name)
return template.render(context=context)
def render(self):
return self.render_with_context(self.context)
def __str__(self):
return self.render()
class TextBlock(TemplateComponent):
"""
text_block.html':
<p>{{ text }}</p>
"""
template_name = 'text_block.html'
text = Field(required=True)
class BulletList(TemplateComponent):
"""
bullet_list.html':
<ul>
{% for li in list %}
<li>{{ li }}</li>
{% endif %}
</ul>
"""
template = 'bullet_list.html'
list = Field(required=True, default=list)
class TestEmail(TemplateComponent):
"""
emails/test-email.html:
{{ my_list }}
Bla
{{ my_text }}
"""
template_name = 'emails/test-email.html'
my_list = Field(required=True, allowed_type=BulletList)
my_text = Field(required=True, allowed_type=TextBlock)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment