rewrite a bit how views and sections work; section's prepare function; website interfaces; section.as_view returns a view containing it and usable as it

This commit is contained in:
bkfox
2016-07-18 02:40:11 +02:00
parent 32a30004d6
commit 4e5d90fb1d
7 changed files with 306 additions and 202 deletions

View File

@ -29,20 +29,19 @@ class Viewable:
@classmethod
def as_view (cl, *args, **kwargs):
"""
Similar to View.as_view, but instead, wrap a constructor of the
given class that is used as is.
Create a view containing the current viewable, using a subclass
of aircox.cms.views.BaseView.
All the arguments are passed to the view directly.
"""
def func(**kwargs_):
if kwargs_:
kwargs.update(kwargs_)
instance = cl(*args, **kwargs)
return instance
return func
from aircox.cms.views import PageView
kwargs['sections'] = cl
return PageView.as_view(*args, **kwargs)
@classmethod
def extends (cl, **kwargs):
"""
Return a sub class where the given attribute have been updated
using kwargs.
"""
class Sub(cl):
pass
@ -60,13 +59,20 @@ class Sections(Viewable, list):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def prepare(self, *args, **kwargs):
"""
prepare all children sections
"""
for i, section in enumerate(self):
if callable(section) or type(section) == type:
self[i] = section()
self[i].prepare(*args, **kwargs)
def render(self, *args, **kwargs):
if args:
self.prepare(*args, **kwargs)
return ''.join([
section.render(*args, **kwargs)
section.render()
for section in self
])
@ -127,6 +133,7 @@ class Section(Viewable, View):
its value is an empty string (prints an empty string).
"""
view = None
request = None
object = None
kwargs = None
@ -138,8 +145,8 @@ class Section(Viewable, View):
else:
self.css_class = css_class
def __init__ (self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __init__ (self, **kwargs):
super().__init__(**kwargs)
self.add_css_class('section')
if type(self) != Section:
@ -159,11 +166,7 @@ class Section(Viewable, View):
"""
return False
def get_context_data(self, request = None, object = None, **kwargs):
if request: self.request = request
if object: self.object = object
if kwargs: self.kwargs = kwargs
def get_context_data(self):
return {
'view': self,
'exp': (hasattr(self, '_exposure') and self._exposure) or None,
@ -178,8 +181,24 @@ class Section(Viewable, View):
'embed': True,
}
def render(self, request, object=None, **kwargs):
context = self.get_context_data(request=request, object=object, **kwargs)
def prepare(self, view, **kwargs):
"""
initialize the object with valuable informations.
"""
self.view = view
self.request = view.request
self.kwargs = view.kwargs
if hasattr(view, 'object'):
self.object = view.object
def render(self, *args, **kwargs):
"""
Render the section as a string. Use *args and **kwargs to prepare
the section, then get_context_data and render.
"""
if args and not self.view:
self.prepare(*args, **kwargs)
context = self.get_context_data()
is_empty = self.is_empty()
if not context or (is_empty and not self.message_empty):
@ -189,7 +208,9 @@ class Section(Viewable, View):
context['content'] = self.message_empty
context['embed'] = True
return render_to_string(self.template_name, context, request=request)
return render_to_string(
self.template_name, context, request=self.request
)
class Image(Section):
@ -336,11 +357,17 @@ class List(Section):
ListItem(item) for item in items
]
@classmethod
def as_view(cl, *args, **kwargs):
from aircox.cms.views import PostListView
kwargs['sections'] = cl
return PostListView.as_view(*args, **kwargs)
def is_empty(self):
return not self.object_list
def get_object_list(self):
return self.object_list
return self.object_list or []
def prepare_list(self, object_list):
"""
@ -349,8 +376,7 @@ class List(Section):
"""
return object_list
def get_context_data(self, request, object=None, object_list=None,
*args, **kwargs):
def get_context_data(self, *args, object_list=None, **kwargs):
"""
Return a context that is passed to the template at rendering, with
the following values:
@ -364,21 +390,20 @@ class List(Section):
Set `request`, `object`, `object_list` and `kwargs` in self.
"""
if request: self.request = request
if object: self.object = object
if kwargs: self.kwargs = kwargs
if args:
self.prepare(*args, **kwargs)
if object_list is None:
object_list = self.object_list or self.get_object_list()
if not object_list and not self.message_empty:
return
return {}
self.object_list = object_list
if object_list:
object_list = self.prepare_list(object_list)
Actions.make(request, object_list = object_list)
Actions.make(self.request, object_list = object_list)
context = super().get_context_data(request, object, *args, **kwargs)
context = super().get_context_data()
context.update({
'list': self,
'object_list': object_list[:self.paginate_by]
@ -510,13 +535,16 @@ class Menu(Section):
if not self.attrs:
self.attrs = {}
def get_context_data(self, *args, **kwargs):
super().get_context_data(*args, **kwargs)
def prepare(self, *args, **kwargs):
super().prepare(*args, **kwargs)
self.sections.prepare(*args, **kwargs)
def get_context_data(self):
return {
'tag': self.tag,
'css_class': self.css_class,
'attrs': self.attrs,
'content': self.sections.render(*args, **kwargs)
'content': self.sections.render()
}
@ -579,16 +607,18 @@ class Calendar(Section):
date = date.replace(day = 1)
first, count = calendar.monthrange(date.year, date.month)
def make_date(date, day):
date += tz.timedelta(days=day)
return (
date, self.model.reverse(
routes.DateRoute, year = date.year,
month = date.month, day = date.day
)
)
context.update({
'first_weekday': first,
'days': [
(date + tz.timedelta(days=day), self.model.reverse(
routes.DateRoute, year = date.year, month = date.month,
day = day
)
) for day in range(0, count)
],
'days': [ make_date(date, day) for day in range(0, count) ],
'today': datetime.date.today(),
'this_month': date,
'prev_month': date - tz.timedelta(days=10),