Last active
July 30, 2019 16:15
-
-
Save nicoknoll/6c9fd0cde260f0ce69918c9a1b1756dc 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) | |
""" | |
Useable Like: | |
context['test_email'] = TestEmail( | |
my_list=BulletList(list=['A', 'B']), | |
my_text=TextBlock(text='Bla Bla') | |
) | |
""" |
QuittyMR
commented
Jul 30, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment