forked from rc/aircox
work on layout.css
This commit is contained in:
parent
fc8b15eb03
commit
e5f47be608
|
@ -444,10 +444,10 @@ class ProgramPage(Publication):
|
||||||
|
|
||||||
|
|
||||||
class Track(aircox.models.Track,Orderable):
|
class Track(aircox.models.Track,Orderable):
|
||||||
sort_order_field = 'position'
|
|
||||||
|
|
||||||
diffusion = ParentalKey('DiffusionPage',
|
diffusion = ParentalKey('DiffusionPage',
|
||||||
related_name='tracks')
|
related_name='tracks')
|
||||||
|
|
||||||
|
sort_order_field = 'position'
|
||||||
panels = [
|
panels = [
|
||||||
FieldPanel('artist'),
|
FieldPanel('artist'),
|
||||||
FieldPanel('title'),
|
FieldPanel('title'),
|
||||||
|
|
|
@ -470,6 +470,74 @@ class DatedListBase(models.Model):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TemplateMixinMeta(models.base.ModelBase):
|
||||||
|
"""
|
||||||
|
Metaclass for SectionItem, assigning needed values such as `template`.
|
||||||
|
|
||||||
|
It needs to load the item's template if the section uses the default
|
||||||
|
one, and throw error if there is an error in the template.
|
||||||
|
"""
|
||||||
|
def __new__(cls, name, bases, attrs):
|
||||||
|
from django.template.loader import get_template
|
||||||
|
from django.template import TemplateDoesNotExist
|
||||||
|
|
||||||
|
cl = super().__new__(cls, name, bases, attrs)
|
||||||
|
if not hasattr(cl, '_meta'):
|
||||||
|
return cl
|
||||||
|
|
||||||
|
if not 'template' in attrs:
|
||||||
|
cl.snake_name = camelcase_to_underscore(name)
|
||||||
|
cl.template = '{}/sections/{}.html'.format(
|
||||||
|
cl._meta.app_label,
|
||||||
|
cl.snake_name,
|
||||||
|
)
|
||||||
|
if name != 'SectionItem':
|
||||||
|
try:
|
||||||
|
get_template(cl.template)
|
||||||
|
except TemplateDoesNotExist:
|
||||||
|
cl.template = 'aircox_cms/sections/section_item.html'
|
||||||
|
return cl
|
||||||
|
|
||||||
|
|
||||||
|
class TemplateMixin(metaclass=TemplateMixinMeta):
|
||||||
|
def get_context(self, request, page):
|
||||||
|
"""
|
||||||
|
Default 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 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 section. Page is the current publication being rendered.
|
||||||
|
|
||||||
|
Rendering is similar to pages, using 'template' attribute set
|
||||||
|
by default to the app_label/sections/model_name_snake_case.html
|
||||||
|
|
||||||
|
If the default template is not found, use SectionItem's one,
|
||||||
|
that can have a context attribute 'content' that is used to render
|
||||||
|
content.
|
||||||
|
"""
|
||||||
|
context_ = self.get_context(request, *args, page=page, **kwargs)
|
||||||
|
if context:
|
||||||
|
context_.update(context)
|
||||||
|
|
||||||
|
if context.get('hide'):
|
||||||
|
return ''
|
||||||
|
return render_to_string(self.template, context_)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Sections
|
# Sections
|
||||||
#
|
#
|
||||||
|
@ -564,33 +632,8 @@ class Section(ClusterableModel):
|
||||||
return '{}: {}'.format(self.__class__.__name__, self.name or self.pk)
|
return '{}: {}'.format(self.__class__.__name__, self.name or self.pk)
|
||||||
|
|
||||||
|
|
||||||
class SectionItemMeta(models.base.ModelBase):
|
|
||||||
"""
|
|
||||||
Metaclass for SectionItem, assigning needed values such as `template`.
|
|
||||||
|
|
||||||
It needs to load the item's template if the section uses the default
|
|
||||||
one, and throw error if there is an error in the template.
|
|
||||||
"""
|
|
||||||
def __new__(cls, name, bases, attrs):
|
|
||||||
from django.template.loader import get_template
|
|
||||||
from django.template import TemplateDoesNotExist
|
|
||||||
|
|
||||||
cl = super().__new__(cls, name, bases, attrs)
|
|
||||||
if not 'template' in attrs:
|
|
||||||
cl.snake_name = camelcase_to_underscore(name)
|
|
||||||
cl.template = '{}/sections/{}.html'.format(
|
|
||||||
cl._meta.app_label,
|
|
||||||
cl.snake_name,
|
|
||||||
)
|
|
||||||
if name != 'SectionItem':
|
|
||||||
try:
|
|
||||||
get_template(cl.template)
|
|
||||||
except TemplateDoesNotExist:
|
|
||||||
cl.template = 'aircox_cms/sections/section_item.html'
|
|
||||||
return cl
|
|
||||||
|
|
||||||
@register_snippet
|
@register_snippet
|
||||||
class SectionItem(models.Model,metaclass=SectionItemMeta):
|
class SectionItem(models.Model,TemplateMixin):
|
||||||
"""
|
"""
|
||||||
Base class for a section item.
|
Base class for a section item.
|
||||||
"""
|
"""
|
||||||
|
@ -645,42 +688,6 @@ class SectionItem(models.Model,metaclass=SectionItemMeta):
|
||||||
self.real_type = type(self).__name__.lower()
|
self.real_type = type(self).__name__.lower()
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
def get_context(self, request, page):
|
|
||||||
"""
|
|
||||||
Default 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 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 section. Page is the current publication being rendered.
|
|
||||||
|
|
||||||
Rendering is similar to pages, using 'template' attribute set
|
|
||||||
by default to the app_label/sections/model_name_snake_case.html
|
|
||||||
|
|
||||||
If the default template is not found, use SectionItem's one,
|
|
||||||
that can have a context attribute 'content' that is used to render
|
|
||||||
content.
|
|
||||||
"""
|
|
||||||
context_ = self.get_context(request, *args, page=page, **kwargs)
|
|
||||||
if context:
|
|
||||||
context_.update(context)
|
|
||||||
|
|
||||||
if context.get('hide'):
|
|
||||||
return ''
|
|
||||||
return render_to_string(self.template, context_)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{}: {}'.format(
|
return '{}: {}'.format(
|
||||||
(self.real_type or 'section item').replace('section','section '),
|
(self.real_type or 'section item').replace('section','section '),
|
||||||
|
@ -808,12 +815,14 @@ class SectionLinkList(ClusterableModel, SectionItem):
|
||||||
InlinePanel('links', label=_('Links')),
|
InlinePanel('links', label=_('Links')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@register_snippet
|
@register_snippet
|
||||||
class SectionLink(RelatedLinkBase):
|
class SectionLink(RelatedLinkBase,TemplateMixin):
|
||||||
"""
|
"""
|
||||||
Render a link to a page or a given url.
|
Render a link to a page or a given url.
|
||||||
Can either be used standalone or in a SectionLinkList
|
Can either be used standalone or in a SectionLinkList
|
||||||
"""
|
"""
|
||||||
|
template = 'aircox_cms/snippets/link.html'
|
||||||
parent = ParentalKey(
|
parent = ParentalKey(
|
||||||
'SectionLinkList', related_name = 'links',
|
'SectionLinkList', related_name = 'links',
|
||||||
null = True
|
null = True
|
||||||
|
|
|
@ -62,30 +62,65 @@ ul {
|
||||||
|
|
||||||
|
|
||||||
/** content: menus **/
|
/** content: menus **/
|
||||||
nav.menu {
|
.menu {
|
||||||
padding: 0.4em;
|
padding: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu.top {
|
body > .top *,
|
||||||
padding: 0.2em;
|
body > .header * {
|
||||||
height: 2.5em;
|
vertical-align: middle;
|
||||||
margin-bottom: 1em;
|
|
||||||
background-color: white;
|
|
||||||
box-shadow: 0em 0em 0.2em black;
|
|
||||||
}
|
|
||||||
.menu.top * {
|
|
||||||
vertical-align: bottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu.top > section {
|
body > .top section,
|
||||||
|
body > .header section {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu.top a {
|
body > .top a,
|
||||||
|
body > .header a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0.2em 1em;
|
margin: 0.2em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body > .top {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: calc(100% - 0.8em);
|
||||||
|
height: 2.5em;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0em 0em 0.2em black;
|
||||||
|
transition: opacity 1.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[scrollY] > .top {
|
||||||
|
opacity: 0.1;
|
||||||
|
transition: opacity 1.5s 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > .top:hover {
|
||||||
|
opacity: 1.0;
|
||||||
|
transition: opacity 1.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body > .header {
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 3.3em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > .header > div {
|
||||||
|
width: 15000%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > .header > div > section {
|
||||||
|
margin: 0;
|
||||||
|
margin-right: -0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.page_left, .page_right {
|
.page_left, .page_right {
|
||||||
max-width: 16em;
|
max-width: 16em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,10 +108,8 @@ main.detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
main.detail > header h1.title {
|
main.detail > header h1.title {
|
||||||
position: relative;
|
|
||||||
width: calc(70% - 0.8em);
|
width: calc(70% - 0.8em);
|
||||||
margin: 0em;
|
margin: 0em;
|
||||||
margin-bottom: -2em;
|
|
||||||
padding: 0.4em;
|
padding: 0.4em;
|
||||||
background-color: rgba(255,255,255,0.8);
|
background-color: rgba(255,255,255,0.8);
|
||||||
}
|
}
|
||||||
|
@ -125,7 +123,6 @@ main.detail {
|
||||||
main.detail header .summary {
|
main.detail header .summary {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
width: calc(20% - 2em);
|
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
{% block css_extras %}{% endblock %}
|
{% block css_extras %}{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
<script src="{% static 'aircox_cms/js/bootstrap.js' %}"></script>
|
||||||
<script src="{% static 'aircox_cms/js/utils.js' %}"></script>
|
<script src="{% static 'aircox_cms/js/utils.js' %}"></script>
|
||||||
<script src="{% static 'aircox_cms/js/player.js' %}"></script>
|
<script src="{% static 'aircox_cms/js/player.js' %}"></script>
|
||||||
|
|
||||||
|
@ -36,7 +37,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<header class="header">
|
<header class="header">
|
||||||
|
<div>
|
||||||
{% render_sections position="header" %}
|
{% render_sections position="header" %}
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="page flex_row">
|
<div class="page flex_row">
|
||||||
|
@ -71,7 +74,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% block footer %}
|
{% block footer %}
|
||||||
<footer class="footer">
|
<footer class="menu footer">
|
||||||
{% render_sections position="footer" %}
|
{% render_sections position="footer" %}
|
||||||
<div class="small float_right">Propulsed by
|
<div class="small float_right">Propulsed by
|
||||||
<a href="https://github.com/bkfox/aircox">Aircox</a>
|
<a href="https://github.com/bkfox/aircox">Aircox</a>
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
{% extends "aircox_cms/sections/section_item.html" %}
|
{% extends "aircox_cms/sections/section_item.html" %}
|
||||||
{% load wagtailimages_tags %}
|
{% load wagtailimages_tags %}
|
||||||
|
{% load aircox_cms %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% for item in object_list %}
|
{% for item in self.links.all %}
|
||||||
{% with link=item.as_dict %}
|
{% render_template_mixin item %}
|
||||||
<a href="{{ link.url }}"
|
|
||||||
{% if item.css_class %}class="{{ item.css_class }}"{% endif %}>
|
|
||||||
{% if link.icon %}{% image link.icon fill-24x24 class="icon" %}{% endif %}
|
|
||||||
{{ link.text }}
|
|
||||||
</a>
|
|
||||||
{% endwith %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
{% extends "aircox_cms/sections/section_item.html" %}
|
|
||||||
{% load wagtailimages_tags %}
|
{% load wagtailimages_tags %}
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
{% with link=self.as_dict %}
|
{% with link=self.as_dict %}
|
||||||
<a href="{{ link.url }}" {% if self.info %}title="{{ self.info }}"{% endif %}>
|
<a href="{{ link.url }}" {% if self.info %}title="{{ self.info }}"{% endif %}>
|
||||||
{% if link.icon %}
|
{% if link.icon %}
|
||||||
|
@ -12,6 +10,4 @@
|
||||||
{{ link.text }}
|
{{ link.text }}
|
||||||
</a>
|
</a>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
|
|
@ -27,3 +27,15 @@ def render_sections(context, position = None):
|
||||||
for section in Section.get_sections_at(position, page)
|
for section in Section.get_sections_at(position, page)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@register.simple_tag(takes_context=True)
|
||||||
|
def render_template_mixin(context, mixin):
|
||||||
|
"""
|
||||||
|
Render correctly a template mixin, e.g SectionLink
|
||||||
|
"""
|
||||||
|
request = context.get('request')
|
||||||
|
page = context.get('page')
|
||||||
|
return mark_safe(mixin.render(request, page=page, context = {
|
||||||
|
'settings': context.get('settings')
|
||||||
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user