0001-general-extract-placeholder-details-from-templates-i.patch
combo/data/models.py | ||
---|---|---|
77 | 77 |
return len(set(page_groups).intersection(user.groups.all())) > 0 |
78 | 78 | |
79 | 79 | |
80 |
class Placeholder(object): |
|
81 |
def __init__(self, key, name=None, internal=False, acquired=False): |
|
82 |
self.key = key |
|
83 |
self.name = name |
|
84 |
self.internal = internal |
|
85 |
self.acquired = acquired |
|
86 | ||
87 | ||
80 | 88 |
class PageManager(models.Manager): |
81 | 89 |
def get_by_natural_key(self, path): |
82 | 90 |
parts = [x for x in path.strip('/').split('/') if x] or ['index'] |
... | ... | |
176 | 184 |
def get_template_display_name(self): |
177 | 185 |
return settings.COMBO_PUBLIC_TEMPLATES[self.template_name]['name'] |
178 | 186 | |
187 |
def get_placeholders(self, template_name=None): |
|
188 |
placeholders = [] |
|
189 | ||
190 |
page_template = settings.COMBO_PUBLIC_TEMPLATES.get(template_name or self.template_name) |
|
191 |
if page_template.get('placeholders'): |
|
192 |
# manual declaration |
|
193 |
for key, options in page_template['placeholders'].items(): |
|
194 |
placeholders.append(Placeholder(key=key, **options)) |
|
195 |
return placeholders |
|
196 | ||
197 |
template_name = settings.COMBO_PUBLIC_TEMPLATES.get(self.template_name).get('template') |
|
198 |
tmpl = template.loader.select_template([template_name]) |
|
199 |
request = RequestFactory().get(self.get_online_url()) |
|
200 |
request.user = None |
|
201 |
context = RequestContext(request, { |
|
202 |
'page': self, |
|
203 |
'request': request, |
|
204 |
'synchronous': False, |
|
205 |
'placeholder_search_mode': True, |
|
206 |
'placeholders': placeholders, |
|
207 |
}) |
|
208 |
tmpl.render(context) |
|
209 |
return placeholders |
|
210 | ||
179 | 211 |
def get_next_page(self, user=None): |
180 | 212 |
pages = Page.get_as_reordered_flat_hierarchy(Page.objects.all()) |
181 | 213 |
this_page = [x for x in pages if x.id == self.id][0] |
combo/manager/views.py | ||
---|---|---|
92 | 92 |
def form_valid(self, form): |
93 | 93 |
response = super(PageAddView, self).form_valid(form) |
94 | 94 |
if self.object.slug != 'index' or self.object.parent_id: |
95 |
combo_template = settings.COMBO_PUBLIC_TEMPLATES.get(self.object.template_name)
|
|
96 |
for placeholder_key, placeholder in combo_template['placeholders'].items():
|
|
97 |
if placeholder.get('acquired') is True:
|
|
98 |
ParentContentCell(page=self.object, placeholder=placeholder_key, order=0).save()
|
|
95 |
for placeholder in self.object.get_placeholders():
|
|
96 |
if placeholder.acquired is True:
|
|
97 |
ParentContentCell(page=self.object,
|
|
98 |
placeholder=placeholder.key, order=0).save()
|
|
99 | 99 | |
100 | 100 |
return response |
101 | 101 | |
... | ... | |
121 | 121 |
new_template_name = self.object.template_name |
122 | 122 |
response = super(PageSelectTemplateView, self).form_valid(form) |
123 | 123 |
if old_template_name != new_template_name: |
124 |
old_template = settings.COMBO_PUBLIC_TEMPLATES.get(old_template_name) |
|
125 |
new_template = settings.COMBO_PUBLIC_TEMPLATES.get(new_template_name) |
|
124 |
old_placeholder_keys = [x.key for x in self.get_object().get_placeholders()] |
|
126 | 125 |
page_cells = CellBase.get_cells(page_id=self.object.id) |
127 |
for placeholder_key, placeholder in new_template['placeholders'].items():
|
|
128 |
if not placeholder.get('acquired') is True:
|
|
126 |
for placeholder in self.object.get_placeholders(new_template_name):
|
|
127 |
if not placeholder.acquired:
|
|
129 | 128 |
continue |
130 |
if placeholder_key in old_template:
|
|
129 |
if placeholder.key in old_placeholder_keys:
|
|
131 | 130 |
continue |
132 |
if [x for x in page_cells if x.placeholder == placeholder_key]:
|
|
131 |
if [x for x in page_cells if x.placeholder == placeholder.key]:
|
|
133 | 132 |
# skip placeholders that already have cells |
134 | 133 |
continue |
135 |
ParentContentCell(page=self.object, placeholder=placeholder_key, order=0).save()
|
|
134 |
ParentContentCell(page=self.object, placeholder=placeholder.key, order=0).save()
|
|
136 | 135 |
return response |
137 | 136 | |
138 | 137 |
page_select_template = PageSelectTemplateView.as_view() |
... | ... | |
211 | 210 |
placeholders = [] |
212 | 211 |
combo_template = settings.COMBO_PUBLIC_TEMPLATES.get(template) |
213 | 212 | |
214 |
for placeholder_key, placeholder in combo_template['placeholders'].items():
|
|
213 |
for placeholder in self.object.get_placeholders():
|
|
215 | 214 |
placeholder_dict = { |
216 |
'key': placeholder_key,
|
|
217 |
'name': placeholder['name'],
|
|
215 |
'key': placeholder.key,
|
|
216 |
'name': placeholder.name,
|
|
218 | 217 |
} |
219 |
placeholder_dict['cells'] = [x for x in cells if ( |
|
220 |
x.placeholder == placeholder_key)] |
|
218 |
placeholder_dict['cells'] = [x for x in cells if x.placeholder == placeholder.key] |
|
221 | 219 |
placeholders.append(placeholder_dict) |
222 | 220 | |
223 | 221 |
context['placeholders'] = placeholders |
combo/public/templates/combo/page_template.html | ||
---|---|---|
1 |
{% load combo gadjo %}<!DOCTYPE html> |
|
1 |
{% load combo gadjo i18n %}<!DOCTYPE html>
|
|
2 | 2 |
<html> |
3 | 3 |
<head> |
4 | 4 |
<meta charset="utf-8"/> |
... | ... | |
28 | 28 |
{% endblock %} |
29 | 29 | |
30 | 30 |
{% block combo-content %} |
31 |
{% placeholder "content" %} |
|
31 |
{% trans "Content" as name %} |
|
32 |
{% placeholder "content" name=name %} |
|
32 | 33 |
{% endblock %} |
33 | 34 |
</div> |
34 | 35 |
<div id="footer"> |
35 | 36 |
{% block footer %} |
36 |
{% placeholder "footer" %} |
|
37 |
{% trans "Footer" as name %} |
|
38 |
{% placeholder "footer" name=name acquired=True %} |
|
37 | 39 |
{% skeleton_extra_placeholder footer %} |
38 | 40 |
<span style="display: none">{% now "Y-m-d H:i:s" %}</span> |
39 | 41 |
{% end_skeleton_extra_placeholder %} |
combo/public/templates/combo/page_template_sidebar.html | ||
---|---|---|
1 | 1 |
{% extends "combo/page_template.html" %} |
2 |
{% load combo %} |
|
2 |
{% load combo i18n %}
|
|
3 | 3 | |
4 | 4 |
{% block combo-content %} |
5 | 5 |
<div id="main-content"> |
6 |
{% placeholder "content" %} |
|
6 |
{% trans "Content" as name %} |
|
7 |
{% placeholder "content" name=name %} |
|
7 | 8 |
</div> |
8 | 9 |
<div id="sidebar"> |
9 |
{% placeholder "sidebar" %} |
|
10 |
{% trans "Sidebar" as name %} |
|
11 |
{% placeholder "sidebar" name=name %} |
|
10 | 12 |
</div> |
11 | 13 |
{% endblock %} |
combo/public/templatetags/combo.py | ||
---|---|---|
24 | 24 |
from django.template.base import TOKEN_BLOCK, TOKEN_VAR |
25 | 25 |
from django.utils import dateparse |
26 | 26 | |
27 |
from combo.data.models import Placeholder |
|
27 | 28 |
from combo.public.menu import get_menu_context |
28 | 29 |
from combo.utils import NothingInCacheException |
29 | 30 |
from combo.apps.dashboard.models import DashboardCell, Tile |
... | ... | |
37 | 38 |
placeholder_name, placeholder_name, content) |
38 | 39 | |
39 | 40 |
@register.inclusion_tag('combo/placeholder.html', takes_context=True) |
40 |
def placeholder(context, placeholder_name): |
|
41 |
def placeholder(context, placeholder_name, **options): |
|
42 |
if context.get('placeholder_search_mode'): |
|
43 |
context['placeholders'].append(Placeholder(key=placeholder_name, **options)) |
|
44 |
return context |
|
41 | 45 |
context['cells'] = [x for x in context.get('page_cells', []) if |
42 | 46 |
x.placeholder == placeholder_name and |
43 | 47 |
(context.get('render_skeleton') or x.is_relevant(context))] |
... | ... | |
47 | 51 |
context['skeleton'] = '' |
48 | 52 |
return context |
49 | 53 | |
54 |
@register.simple_tag(takes_context=True) |
|
55 |
def placeholder_option(context, **options): |
|
56 |
placeholder = context['placeholders'][-1] |
|
57 |
for option in options: |
|
58 |
setattr(placeholder, option, options.get(option)) |
|
59 |
return context |
|
60 | ||
50 | 61 |
@register.simple_tag(takes_context=True) |
51 | 62 |
def render_cell(context, cell): |
52 | 63 |
if context.get('render_skeleton') and cell.is_user_dependant(context): |
combo/public/views.py | ||
---|---|---|
206 | 206 | |
207 | 207 |
# add default ParentContentCells to the page |
208 | 208 |
cells = [] |
209 |
combo_template = settings.COMBO_PUBLIC_TEMPLATES[selected_page.template_name] |
|
210 |
for placeholder_key, placeholder in combo_template['placeholders'].items(): |
|
211 |
if placeholder.get('acquired') is True: |
|
212 |
cells.append(ParentContentCell(page=selected_page, placeholder=placeholder_key, order=0)) |
|
209 |
for placeholder in selected_page.get_placeholders(): |
|
210 |
if placeholder.acquired: |
|
211 |
cells.append(ParentContentCell(page=selected_page, placeholder=placeholder.key, order=0)) |
|
213 | 212 |
else: |
214 | 213 |
cells = CellBase.get_cells(page_id=selected_page.id) |
215 | 214 | |
... | ... | |
245 | 244 |
self.page.template_name = self.template_name |
246 | 245 |
self.page.save() |
247 | 246 |
combo_template = settings.COMBO_PUBLIC_TEMPLATES[self.page.template_name] |
248 |
for i, placeholder in enumerate(combo_template['placeholders'].keys()):
|
|
249 |
cell = TextCell(page=self.page, placeholder=placeholder, order=0) |
|
250 |
if placeholder == 'footer': |
|
247 |
for i, placeholder in enumerate(self.page.get_placeholders()):
|
|
248 |
cell = TextCell(page=self.page, placeholder=placeholder.key, order=0)
|
|
249 |
if placeholder.key == 'footer':
|
|
251 | 250 |
cell.text = '<p>%s</p>' % lorem_ipsum.sentence() |
252 | 251 |
else: |
253 | 252 |
cell.text = '<h2>%s</h2>%s' % ( |
... | ... | |
257 | 256 | |
258 | 257 |
if i == 0: |
259 | 258 |
# add a template selector in first placeholder |
260 |
cell = TextCell(page=self.page, placeholder=placeholder, order=1) |
|
259 |
cell = TextCell(page=self.page, placeholder=placeholder.key, order=1)
|
|
261 | 260 |
options_html = [] |
262 | 261 |
for template_key, template_dict in settings.COMBO_PUBLIC_TEMPLATES.items(): |
263 | 262 |
attr = 'value="%s"' % template_key |
combo/settings.py | ||
---|---|---|
175 | 175 |
'standard': { |
176 | 176 |
'name': _('One column'), |
177 | 177 |
'template': 'combo/page_template.html', |
178 |
'placeholders': { |
|
179 |
'content': { |
|
180 |
'name': _('Content'), |
|
181 |
}, |
|
182 |
'footer': { |
|
183 |
'name': _('Footer'), |
|
184 |
'acquired': True, |
|
185 |
}, |
|
186 |
} |
|
187 | 178 |
}, |
188 | 179 |
'standard-sidebar': { |
189 | 180 |
'name': _('One column + sidebar'), |
190 | 181 |
'template': 'combo/page_template_sidebar.html', |
191 |
'placeholders': { |
|
192 |
'content': { |
|
193 |
'name': _('Content'), |
|
194 |
}, |
|
195 |
'sidebar': { |
|
196 |
'name': _('Sidebar'), |
|
197 |
}, |
|
198 |
'footer': { |
|
199 |
'name': _('Footer'), |
|
200 |
'acquired': True, |
|
201 |
}, |
|
202 |
} |
|
203 | 182 |
}, |
204 | 183 |
'two-columns': { |
205 | 184 |
'name': _('Two columns'), |
206 | 185 |
'template': 'combo/page_template_2cols.html', |
207 |
'placeholders': { |
|
208 |
'content': { |
|
209 |
'name': _('Left Column'), |
|
210 |
}, |
|
211 |
'right': { |
|
212 |
'name': _('Right Column'), |
|
213 |
}, |
|
214 |
'footer': { |
|
215 |
'name': _('Footer'), |
|
216 |
'acquired': True, |
|
217 |
}, |
|
218 |
} |
|
219 | 186 |
}, |
220 | 187 |
'two-columns-sidebar': { |
221 | 188 |
'name': _('Two columns + sidebar'), |
222 | 189 |
'template': 'combo/page_template_2cols_sidebar.html', |
223 |
'placeholders': { |
|
224 |
'content': { |
|
225 |
'name': _('Left Column'), |
|
226 |
}, |
|
227 |
'right': { |
|
228 |
'name': _('Right Column'), |
|
229 |
}, |
|
230 |
'sidebar': { |
|
231 |
'name': _('Sidebar'), |
|
232 |
}, |
|
233 |
'footer': { |
|
234 |
'name': _('Footer'), |
|
235 |
'acquired': True, |
|
236 |
}, |
|
237 |
} |
|
190 |
# get those labels into gettext catalog |
|
191 |
'_': (_('Left Column'), _('Right Column')), |
|
238 | 192 |
}, |
239 | 193 |
} |
240 | 194 |
data/themes/gadjo/templates/combo/page_template.html | ||
---|---|---|
24 | 24 |
{% block content %} |
25 | 25 |
<div id="portal-agent-content"> |
26 | 26 |
{% block combo-content %} |
27 |
{% placeholder "content" %} |
|
27 |
{% trans "Content" as name %} |
|
28 |
{% placeholder "content" name=name %} |
|
28 | 29 |
{% endblock %} |
29 | 30 |
</div> |
30 | 31 |
{% endblock %} |
data/themes/gadjo/templates/combo/page_template_sidebar.html | ||
---|---|---|
1 | 1 |
{% extends "combo/page_template.html" %} |
2 |
{% load combo %} |
|
2 |
{% load combo i18n %}
|
|
3 | 3 | |
4 | 4 |
{% block bodyargs %}{{ block.super }} class="with-sidebar"{% endblock %} |
5 | 5 | |
6 | 6 |
{% block combo-content %} |
7 | 7 |
<div id="page-content"> |
8 |
{% placeholder "content" %} |
|
8 |
{% trans "Content" as name %} |
|
9 |
{% placeholder "content" name=name %} |
|
9 | 10 |
</div> |
10 | 11 |
{% endblock %} |
11 | 12 | |
12 | 13 |
{% block after-main-content %} |
13 | 14 |
<div id="sidebar"> |
14 |
{% placeholder "sidebar" %} |
|
15 |
{% trans "Sidebar" as name %} |
|
16 |
{% placeholder "sidebar" name=name %} |
|
15 | 17 |
</div> |
16 | 18 |
{% endblock %} |
tests/test_pages.py | ||
---|---|---|
6 | 6 | |
7 | 7 |
from django.conf import settings |
8 | 8 |
from django.contrib.auth.models import User, Group |
9 |
from django.test import override_settings |
|
9 | 10 |
from django.utils.timezone import now |
10 | 11 |
from combo.data.models import Page, CellBase, TextCell, LinkCell |
11 | 12 |
from combo.data.management.commands.import_site import Command as ImportSiteCommand |
... | ... | |
262 | 263 |
TextCell.objects.filter(pk=cell.id).update(last_update_timestamp=future_time) |
263 | 264 | |
264 | 265 |
assert page.get_last_update_time() == future_time |
266 | ||
267 |
def test_get_placeholders(): |
|
268 |
page = Page(title=u'foo', slug='foo', template_name='standard-sidebar', order=0) |
|
269 |
placeholders = page.get_placeholders() |
|
270 |
assert [x.key for x in placeholders] == ['content', 'sidebar', 'footer'] |
|
271 |
assert placeholders[0].acquired is False |
|
272 |
assert placeholders[-1].acquired is True |
|
273 | ||
274 |
with override_settings(COMBO_PUBLIC_TEMPLATES={ |
|
275 |
'standard-sidebar': { |
|
276 |
'name': 'Test', |
|
277 |
'template': 'combo/page_template_sidebar.html', |
|
278 |
'placeholders': { |
|
279 |
'content': {'name': 'Content'}, |
|
280 |
'content2': {'name': 'Second Content'}, |
|
281 |
'sidebar': {'name': 'Sidebar'}, |
|
282 |
'footer': {'name': 'Footer', 'acquired': False}, |
|
283 |
}}}): |
|
284 |
placeholders = page.get_placeholders() |
|
285 |
assert set([x.key for x in placeholders]) == set(['content', 'content2', 'sidebar', 'footer']) |
|
286 |
footer_placeholder = [x for x in placeholders if x.key == 'footer'][0] |
|
287 |
assert footer_placeholder.acquired is False |
|
265 |
- |