remove get_content() function in sections; add is_empty() and message_empty() for all sections + hiding if needed; adapt; section Content is now child of Image; remove print()
This commit is contained in:
parent
160a5db500
commit
733acf20ef
106
cms/sections.py
106
cms/sections.py
|
@ -97,6 +97,10 @@ class Section(Viewable, View):
|
||||||
* title: title of the section
|
* title: title of the section
|
||||||
* header: header of the section
|
* header: header of the section
|
||||||
* footer: footer of the section
|
* footer: footer of the section
|
||||||
|
|
||||||
|
* message_empty: if message_empty is not None, print its value as
|
||||||
|
content of the section instead of hiding it. This works also when
|
||||||
|
its value is an empty string (prints an empty string).
|
||||||
"""
|
"""
|
||||||
template_name = 'aircox/cms/website.html'
|
template_name = 'aircox/cms/website.html'
|
||||||
|
|
||||||
|
@ -108,6 +112,8 @@ class Section(Viewable, View):
|
||||||
header = ''
|
header = ''
|
||||||
footer = ''
|
footer = ''
|
||||||
|
|
||||||
|
message_empty = None
|
||||||
|
|
||||||
request = None
|
request = None
|
||||||
object = None
|
object = None
|
||||||
kwargs = None
|
kwargs = None
|
||||||
|
@ -132,8 +138,13 @@ class Section(Viewable, View):
|
||||||
self.attrs['name'] = self.name
|
self.attrs['name'] = self.name
|
||||||
self.attrs['id'] = self.name
|
self.attrs['id'] = self.name
|
||||||
|
|
||||||
def get_content(self):
|
def is_empty(self):
|
||||||
return ''
|
"""
|
||||||
|
Return True if the section content will be empty. This allows to
|
||||||
|
hide the section.
|
||||||
|
This must be implemented by the subclasses.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
def get_context_data(self, request = None, object = None, **kwargs):
|
def get_context_data(self, request = None, object = None, **kwargs):
|
||||||
if request: self.request = request
|
if request: self.request = request
|
||||||
|
@ -149,17 +160,21 @@ class Section(Viewable, View):
|
||||||
'title': self.title,
|
'title': self.title,
|
||||||
'header': self.header,
|
'header': self.header,
|
||||||
'footer': self.footer,
|
'footer': self.footer,
|
||||||
'content': self.get_content(),
|
'content': '',
|
||||||
'object': self.object,
|
'object': self.object,
|
||||||
'embed': True,
|
'embed': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
def render(self, request, object=None, context_only=False, **kwargs):
|
def render(self, request, object=None, **kwargs):
|
||||||
context = self.get_context_data(request=request, object=object, **kwargs)
|
context = self.get_context_data(request=request, object=object, **kwargs)
|
||||||
if context_only:
|
|
||||||
return context
|
is_empty = self.is_empty()
|
||||||
if not context:
|
if not context or (is_empty and not self.message_empty):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
if is_empty and self.message_empty:
|
||||||
|
context['content'] = self.message_empty
|
||||||
|
|
||||||
context['embed'] = True
|
context['embed'] = True
|
||||||
return render_to_string(self.template_name, context, request=request)
|
return render_to_string(self.template_name, context, request=request)
|
||||||
|
|
||||||
|
@ -170,45 +185,61 @@ class Image(Section):
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
* url: relative image url
|
* url: relative image url
|
||||||
* rel_attr: name of the attribute of self.object to use
|
* img_attr: name of the attribute of self.object to use
|
||||||
"""
|
"""
|
||||||
url = None
|
url = None
|
||||||
rel_attr = 'image'
|
img_attr = 'image'
|
||||||
|
|
||||||
def get_content(self, **kwargs):
|
def get_image(self):
|
||||||
if self.url is None:
|
if self.url:
|
||||||
image = getattr(self.object, self.rel_attr)
|
return static(self.url)
|
||||||
return '<img src="{}">'.format(image.url) if image else ''
|
if hasattr(self.object, self.img_attr):
|
||||||
return '<img src="{}">'.format(static(self.url))
|
image = getattr(self.object, self.img_attr)
|
||||||
|
return (image and image.url) or None
|
||||||
|
|
||||||
|
def is_empty(self):
|
||||||
|
return not self.get_image()
|
||||||
|
|
||||||
class Content(Section):
|
def get_context_data(self, *args, **kwargs):
|
||||||
|
context = super().get_context_data(*args, **kwargs)
|
||||||
|
url = self.get_image()
|
||||||
|
if url:
|
||||||
|
context['content'] += '<img src="{}">'.format(url)
|
||||||
|
return context
|
||||||
|
|
||||||
|
class Content(Image):
|
||||||
"""
|
"""
|
||||||
Render content using the self.content or relative to self.object.
|
Render content using the self.content or relative to self.object.
|
||||||
|
Since it is a child of Image, can also render an image.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
* content: raw HTML code to render
|
* content: raw HTML code to render
|
||||||
* rel_attr: name of the attribute of self.object to use
|
* content_attr: name of the attribute of self.object to use
|
||||||
* re_image_attr: if true and there is an image on the current object,
|
|
||||||
render the object's image
|
|
||||||
"""
|
"""
|
||||||
|
# FIXME: markup language -- coordinate with object's one (post/comment)?
|
||||||
content = None
|
content = None
|
||||||
rel_attr = 'content'
|
content_attr = 'content'
|
||||||
rel_image_attr = 'image'
|
|
||||||
|
|
||||||
def get_content(self):
|
def get_content(self):
|
||||||
if self.content is None:
|
if self.content:
|
||||||
content = getattr(self.object, self.rel_attr)
|
return self.content
|
||||||
|
if hasattr(self.object, self.content_attr):
|
||||||
|
return getattr(self.object, self.content_attr) or None
|
||||||
|
|
||||||
|
def is_empty(self):
|
||||||
|
return super().is_empty() and not self.get_content()
|
||||||
|
|
||||||
|
def get_context_data(self, *args, **kwargs):
|
||||||
|
context = super().get_context_data(*args, **kwargs)
|
||||||
|
content = self.get_content()
|
||||||
|
if content:
|
||||||
|
if not self.content:
|
||||||
content = escape(content)
|
content = escape(content)
|
||||||
content = re.sub(r'(^|\n\n)((\n?[^\n])+)', r'<p>\2</p>', content)
|
content = re.sub(r'(^|\n\n)((\n?[^\n])+)', r'<p>\2</p>', content)
|
||||||
content = re.sub(r'\n', r'<br>', content)
|
content = re.sub(r'\n', r'<br>', content)
|
||||||
|
|
||||||
if self.rel_image_attr and hasattr(self.object, self.rel_image_attr):
|
context['content'] += content
|
||||||
image = getattr(self.object, self.rel_image_attr)
|
return context
|
||||||
if image:
|
|
||||||
content = '<img src="{}">'.format(image.url) + content
|
|
||||||
return content
|
|
||||||
return str(self.content)
|
|
||||||
|
|
||||||
|
|
||||||
class ListItem:
|
class ListItem:
|
||||||
|
@ -245,7 +276,7 @@ class ListItem:
|
||||||
if hasattr(post, i) and not getattr(self, i):
|
if hasattr(post, i) and not getattr(self, i):
|
||||||
setattr(self, i, getattr(post, i))
|
setattr(self, i, getattr(post, i))
|
||||||
if not self.url and hasattr(post, 'url'):
|
if not self.url and hasattr(post, 'url'):
|
||||||
self.url = post.url()
|
self.url = post.url() if callable(post.url) else post.url
|
||||||
|
|
||||||
|
|
||||||
class List(Section):
|
class List(Section):
|
||||||
|
@ -264,7 +295,6 @@ class List(Section):
|
||||||
|
|
||||||
object_list = None
|
object_list = None
|
||||||
url = None
|
url = None
|
||||||
message_empty = _('nothing')
|
|
||||||
paginate_by = 4
|
paginate_by = 4
|
||||||
|
|
||||||
fields = [ 'date', 'time', 'image', 'title', 'content', 'info', 'actions' ]
|
fields = [ 'date', 'time', 'image', 'title', 'content', 'info', 'actions' ]
|
||||||
|
@ -284,6 +314,9 @@ class List(Section):
|
||||||
ListItem(item) for item in items
|
ListItem(item) for item in items
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def is_empty(self):
|
||||||
|
return not self.object_list
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_object_list(self):
|
||||||
return self.object_list
|
return self.object_list
|
||||||
|
|
||||||
|
@ -304,7 +337,8 @@ class List(Section):
|
||||||
instances of Post or ListItem.
|
instances of Post or ListItem.
|
||||||
|
|
||||||
If object_list is not given, call `get_object_list` to retrieve it.
|
If object_list is not given, call `get_object_list` to retrieve it.
|
||||||
Prepare the object_list using `self.prepare_list`.
|
Prepare the object_list using `self.prepare_list`, and make actions
|
||||||
|
for its items.
|
||||||
|
|
||||||
Set `request`, `object`, `object_list` and `kwargs` in self.
|
Set `request`, `object`, `object_list` and `kwargs` in self.
|
||||||
"""
|
"""
|
||||||
|
@ -379,7 +413,7 @@ class Comments(List):
|
||||||
css_class='comments'
|
css_class='comments'
|
||||||
truncate = 0
|
truncate = 0
|
||||||
fields = [ 'date', 'time', 'author', 'content' ]
|
fields = [ 'date', 'time', 'author', 'content' ]
|
||||||
message_empty = _('no comment yet')
|
message_empty = _('no comment has been posted yet')
|
||||||
|
|
||||||
comment_form = None
|
comment_form = None
|
||||||
success_message = ( _('Your message is awaiting for approval'),
|
success_message = ( _('Your message is awaiting for approval'),
|
||||||
|
@ -419,7 +453,6 @@ class Comments(List):
|
||||||
context.update({
|
context.update({
|
||||||
'comment_form': comment_form,
|
'comment_form': comment_form,
|
||||||
})
|
})
|
||||||
|
|
||||||
self.comment_form = None
|
self.comment_form = None
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@ -486,10 +519,12 @@ class Search(Section):
|
||||||
"""
|
"""
|
||||||
# TODO: (later) autocomplete using exposures -> might need templates
|
# TODO: (later) autocomplete using exposures -> might need templates
|
||||||
|
|
||||||
def get_content(self):
|
def get_context_data(self, *args, **kwargs):
|
||||||
import aircox.cms.routes as routes
|
import aircox.cms.routes as routes
|
||||||
|
context = super().get_context_data(*args, **kwargs)
|
||||||
url = self.model.reverse(routes.SearchRoute)
|
url = self.model.reverse(routes.SearchRoute)
|
||||||
return """
|
|
||||||
|
context['content'] += """
|
||||||
<form action="{url}" method="get">
|
<form action="{url}" method="get">
|
||||||
<input type="text" name="q" placeholder="{placeholder}"/>
|
<input type="text" name="q" placeholder="{placeholder}"/>
|
||||||
<input type="submit" {submit_style}/>
|
<input type="submit" {submit_style}/>
|
||||||
|
@ -501,6 +536,7 @@ class Search(Section):
|
||||||
},
|
},
|
||||||
submit_style = (self.no_button and 'style="display: none;"') or '',
|
submit_style = (self.no_button and 'style="display: none;"') or '',
|
||||||
)
|
)
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
@expose
|
@expose
|
||||||
|
|
1
notes.md
1
notes.md
|
@ -45,6 +45,7 @@
|
||||||
- player support diffusions with multiple archive files
|
- player support diffusions with multiple archive files
|
||||||
- view as grid
|
- view as grid
|
||||||
- actions -> noscript case, think of accessibility
|
- actions -> noscript case, think of accessibility
|
||||||
|
- comments edit/remove by the poster
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ class AddToPlaylist(Action):
|
||||||
from aircox.programs.models import Sound
|
from aircox.programs.models import Sound
|
||||||
from aircox.website.models import Diffusion
|
from aircox.website.models import Diffusion
|
||||||
|
|
||||||
print(object)
|
|
||||||
if not in_list:
|
if not in_list:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -244,8 +244,8 @@ class Sounds(sections.List):
|
||||||
return
|
return
|
||||||
|
|
||||||
sounds = programs.Sound.objects.filter(
|
sounds = programs.Sound.objects.filter(
|
||||||
diffusion = self.object.related
|
diffusion = self.object.related,
|
||||||
# public = True
|
public = True,
|
||||||
).order_by('type')
|
).order_by('type')
|
||||||
return [
|
return [
|
||||||
sections.ListItem(
|
sections.ListItem(
|
||||||
|
@ -265,6 +265,7 @@ class Schedule(Diffusions):
|
||||||
date = None
|
date = None
|
||||||
nav_date_format = '%a. %d'
|
nav_date_format = '%a. %d'
|
||||||
fields = [ 'time', 'image', 'title']
|
fields = [ 'time', 'image', 'title']
|
||||||
|
message_empty = ''
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -342,30 +343,3 @@ class Schedule(Diffusions):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#class DatesOfDiffusion(sections.List):
|
|
||||||
# title = _('Dates of diffusion')
|
|
||||||
#
|
|
||||||
# def get_object_list(self):
|
|
||||||
# diffs = list(programs.Diffusion.objects. \
|
|
||||||
# filter(initial = self.object.related). \
|
|
||||||
# exclude(type = programs.Diffusion.Type.unconfirmed)
|
|
||||||
# )
|
|
||||||
# diffs.append(self.object.related)
|
|
||||||
#
|
|
||||||
# items = []
|
|
||||||
# for diff in sorted(diffs, key = lambda d: d.date, reverse = True):
|
|
||||||
# info = ''
|
|
||||||
# if diff.initial:
|
|
||||||
# info = _('rerun')
|
|
||||||
# if diff.type == programs.Diffusion.Type.canceled:
|
|
||||||
# info += ' ' + _('canceled')
|
|
||||||
# items.append(
|
|
||||||
# sections.List.Item(None, diff.start.strftime('%c'), info, None,
|
|
||||||
# 'canceled')
|
|
||||||
# )
|
|
||||||
# return items
|
|
||||||
#
|
|
||||||
## TODO sounds
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user