aircox-radiocampus/aircox_cms/views/components.py

112 lines
3.0 KiB
Python

import json
from django.db import models
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
from wagtail.wagtailcore.utils import camelcase_to_underscore
class Component:
"""
A Component is a small part of a rendered web page. It can be used
to create elements configurable by users.
"""
template_name = ""
"""
[class] Template file path
"""
hide = False
"""
The component can be hidden because there is no reason to display it
(e.g. empty list)
"""
@classmethod
def snake_name(cl):
if not hasattr(cl, '_snake_name'):
cl._snake_name = camelcase_to_underscore(cl.__name__)
return cl._snake_name
def get_context(self, request, page):
"""
Context attributes:
* self: section being rendered
* page: current page being rendered
* request: request used to render the current page
Other context attributes usable in the default section template:
* content: **safe string** set as content of the section
* hide: DO NOT render the section, render only an empty string
"""
return {
'self': self,
'page': page,
'request': request,
}
def render(self, request, page, context, *args, **kwargs):
"""
Render the component. ``Page`` is the current page being
rendered.
"""
# use a different object
context_ = self.get_context(request, *args, page=page, **kwargs)
if self.hide:
return ''
if context:
context_.update({
k: v for k, v in context.items()
if k not in context_
})
context_['page'] = page
return render_to_string(self.template_name, context_)
class ExposedData:
"""
Data object that aims to be exposed to Javascript. This provides
various utilities.
"""
model = None
"""
[class attribute] Related model/class object that is to be exposed
"""
fields = {}
"""
[class attribute] Fields of the model to be exposed, as a dict of
``{ exposed_field: model_field }``
``model_field`` can either be a function(exposed, object) or a field
name.
"""
data = None
"""
Exposed data of the instance
"""
def __init__(self, object = None, **kwargs):
self.data = {}
if object:
self.from_object(object)
self.data.update(kwargs)
def from_object(self, object):
fields = type(self).fields
for k,v in fields.items():
if self.data.get(k) != None:
continue
v = v(self, object) if callable(v) else \
getattr(object, v) if hasattr(object, v) else \
None
self.data[k] = v
def to_json(self):
"""
Return a json string of encoded data.
"""
return mark_safe(json.dumps(self.data))