Created
July 30, 2019 15:34
-
-
Save nicoknoll/db91c8b72588c147c8b76dc69ea4e2f2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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