add support for placeholder acquisition (#6217)

This commit is contained in:
Frédéric Péters 2014-12-30 13:10:48 +01:00
parent 3e126c8a9e
commit 4453710bd5
9 changed files with 120 additions and 10 deletions

View File

@ -79,6 +79,32 @@ class Page(models.Model):
fill_list(object_list)
return reordered
def get_unlocked_placeholders(self, cells=None):
combo_template = settings.COMBO_PUBLIC_TEMPLATES.get(self.template_name)
if self.slug == 'index':
# on the site index page, there are no unlocked placeholder.
return combo_template['placeholders'].keys()
if cells is None:
cells = CellBase.get_cells(page_id=self.id)
# on the other page sites, look for unlock markers
unlocked_placeholders = []
for cell in cells:
if not isinstance(cell, UnlockMarkerCell):
continue
if cell.page_id == self.id:
unlocked_placeholders.append(cell.placeholder)
return unlocked_placeholders
def get_locked_placeholders(self, cells=None):
combo_template = settings.COMBO_PUBLIC_TEMPLATES.get(self.template_name)
lockable_placeholders = [x for x in combo_template['placeholders'] if (
combo_template['placeholders'].get(x).get('acquired'))]
unlocked_placeholders = self.get_unlocked_placeholders(cells)
locked_placeholders = set(lockable_placeholders) - set(unlocked_placeholders)
return list(locked_placeholders)
class CellBase(models.Model):
page = models.ForeignKey(Page)
@ -86,6 +112,7 @@ class CellBase(models.Model):
order = models.PositiveIntegerField()
default_form_class = None
visible = True
class Meta:
abstract = True
@ -98,6 +125,8 @@ class CellBase(models.Model):
def get_cell_content_types(cls):
content_types = []
for klass in get_cell_classes():
if klass.visible is False:
continue
content_types.extend(klass.get_content_types())
return content_types
@ -171,6 +200,17 @@ class FortuneCell(CellBase):
return subprocess.check_output(['fortune'])
@register_cell_class
class UnlockMarkerCell(CellBase):
"""Marks an 'acquired' placeholder as unlocked."""
visible = False
class Meta:
verbose_name = _('Unlock Marker')
def render(self, context):
return ''
@register_cell_class
class BlurpCell(CellBase):
blurp_key = models.CharField(max_length=50)

View File

@ -2,7 +2,7 @@ div#meta {
margin-bottom: 1em;
}
div#available-cells {
div#sidebar {
width: 15em;
float: left;
}

View File

@ -75,7 +75,7 @@ $(function() {
});
}
});
$('#available-cells button').on('click', function() {
$('#sidebar button').on('click', function() {
window.location = $(this).data('add-url');
return false;
});

View File

@ -18,6 +18,8 @@
<label>Current template: </label> {{ object.template_name }}
</div>
<div id="sidebar">
<div id="available-cells">
<h2>Available cells</h2>
<ul>
@ -35,6 +37,19 @@
</ul>
</div>
{% if extra_placeholders %}
<div id="extra-placeholders">
<h2>Extra blocks</h2>
<ul>
{% for placeholder in extra_placeholders %}
<li><button data-add-url="{% url 'combo-manager-page-add-cell' page_pk=object.id cell_type=unlock.content_type.id variant=unlock.variant ph_key=placeholder.key %}">→ {{ placeholder.name }}</button></li>
{% endfor %}
</ul>
</div>
{% endif %}
</div> <!-- #sidebar -->
<div id="placeholders"
data-cell-order-url="{% url 'combo-manager-cell-order' page_pk=object.id %}"
>

View File

@ -25,7 +25,7 @@ from django.views.decorators.csrf import requires_csrf_token
from django.views.generic import (TemplateView, RedirectView, DetailView,
CreateView, UpdateView, ListView, DeleteView)
from combo.data.models import Page, CellBase
from combo.data.models import Page, CellBase, UnlockMarkerCell
from .forms import PageForm
@ -81,14 +81,26 @@ class PageView(DetailView):
cells = CellBase.get_cells(page_id=self.object.id)
template = self.object.template_name
placeholders = []
extra_placeholders = []
combo_template = settings.COMBO_PUBLIC_TEMPLATES.get(template)
unlocked_placeholders = self.object.get_unlocked_placeholders(cells)
for placeholder_key, placeholder in combo_template['placeholders'].items():
placeholders.append({
placeholder_dict = {
'key': placeholder_key,
'name': placeholder['name'],
'cells': [x for x in cells if x.placeholder == placeholder_key],
})
}
if placeholder.get('acquired') and not placeholder_key in unlocked_placeholders:
extra_placeholders.append(placeholder_dict)
else:
placeholder_dict['cells'] = [x for x in cells if (
x.placeholder == placeholder_key)]
placeholders.append(placeholder_dict)
context['unlock'] = UnlockMarkerCell.get_content_types()[0]
context['placeholders'] = placeholders
context['extra_placeholders'] = extra_placeholders
return context
page_view = requires_csrf_token(PageView.as_view())

View File

@ -7,5 +7,8 @@
<body>
<h1>{{ page.title }}</h1>
{% placeholder "content" %}
<hr/>
{% placeholder "footer" %}
</body>
</html>

View File

@ -24,5 +24,7 @@ div#sidebar {
<h2>Sidebar</h2>
{% placeholder "sidebar" %}
</div>
<hr/>
{% placeholder "footer" %}
</body>
</html>

View File

@ -30,10 +30,40 @@ def page(request):
raise Http404()
page = pages[-1]
combo_template = settings.COMBO_PUBLIC_TEMPLATES[page.template_name]
cells = CellBase.get_cells(page_id=page.id)
locked_placeholders = page.get_locked_placeholders(cells)
if locked_placeholders:
# there are some acquired placeholders, look in parent pages for
# appropriate content.
try:
# add the site index page as ultimate parent
pages.insert(0, Page.objects.get(slug='index'))
except Page.DoesNotExist:
pass
unlocker_cells = CellBase.get_cells(page_id__in=[x.id for x in pages])
found_placeholders = {}
for parent_page in reversed(pages[:-1]):
for placeholder in parent_page.get_unlocked_placeholders(unlocker_cells):
if not placeholder in locked_placeholders:
continue
if not placeholder in found_placeholders:
found_placeholders[placeholder] = parent_page.id
if len(found_placeholders) == len(locked_placeholders):
break
# add found cells to the page cells
for placeholder_key, page_id in found_placeholders.items():
cells.extend([x for x in unlocker_cells if x.page_id == page_id and
x.placeholder == placeholder_key])
ctx = {
'page': page,
'page_cells': CellBase.get_cells(page_id=page.id),
'page_cells': cells,
'request': request,
}
template_name = settings.COMBO_PUBLIC_TEMPLATES[page.template_name]['template']
template_name = combo_template['template']
return render(request, template_name, ctx)

View File

@ -120,7 +120,11 @@ COMBO_PUBLIC_TEMPLATES = {
'placeholders': {
'content': {
'name': 'Content',
}
},
'footer': {
'name': 'Footer',
'acquired': True,
},
}
},
'standard-sidebar': {
@ -132,7 +136,11 @@ COMBO_PUBLIC_TEMPLATES = {
},
'sidebar': {
'name': 'Sidebar',
}
},
'footer': {
'name': 'Footer',
'acquired': True,
},
}
},
}