Projet

Général

Profil

0001-general-refine-navigation-menu-page-visibility-28963.patch

Frédéric Péters, 17 décembre 2018 15:04

Télécharger (7,54 ko)

Voir les différences:

Subject: [PATCH] general: refine navigation/menu page visibility (#28963)

 combo/public/menu.py                          | 11 ++++--
 .../public/templates/combo/page_template.html |  2 +-
 combo/public/templatetags/combo.py            |  4 +-
 tests/test_cells.py                           | 37 ++++++++++++++++++-
 tests/test_public.py                          | 22 +++++++++++
 5 files changed, 69 insertions(+), 7 deletions(-)
combo/public/menu.py
17 17
from django.template.loader import get_template
18 18

  
19 19
from combo.data.models import Page
20
from combo.utils import NothingInCacheException
20 21

  
21 22

  
22
def render_menu(context, level=0, root_page=None, depth=1):
23
def render_menu(context, level=0, root_page=None, depth=1, ignore_visibility=False):
23 24
    context['root_page'] = root_page
24 25
    if root_page:
25 26
        level = len(root_page.get_parents_and_self())
......
27 28
    template = get_template('combo/menu.html')
28 29
    return template.render(context)
29 30

  
30
def get_menu_context(context, level=0, current_page=None, depth=1):
31
def get_menu_context(context, level=0, current_page=None, depth=1, ignore_visibility=False):
31 32
    if 'hierarchical_pages_by_id' not in context:
32 33
        context['hierarchical_pages_by_id'] = Page.get_with_hierarchy_attributes()
33 34
    pages_by_id = context['hierarchical_pages_by_id']
......
68 69
    for element in elements:
69 70
        if element.exclude_from_navigation:
70 71
            continue
71
        if not context.get('render_skeleton'):
72
        if not ignore_visibility:
73
            if context.get('render_skeleton'):
74
                if not element.public:
75
                    # mark the menu cell for asynchronous rendering.
76
                    raise NothingInCacheException()
72 77
            if not element.is_visible(context['request'].user):
73 78
                continue
74 79
        menuitem = {'page': element}
combo/public/templates/combo/page_template.html
15 15
       {% if check_badges %}data-check-badges="true"{% endif %}
16 16
       data-api-root="{{ site_base }}/api/">
17 17
 <div id="title"><h1>{{ page.title }}</h1></div>
18
 <div id="menu">{% block menu %}{% show_menu %}{% endblock %}</div>
18
 <div id="menu">{% block menu %}{% show_menu ignore_visibility=True %}{% endblock %}</div>
19 19
 <div id="content">
20 20

  
21 21
  {% block messages %}
combo/public/templatetags/combo.py
146 146
        return skeleton_text(context, self.placeholder_name, content=self.content)
147 147

  
148 148
@register.inclusion_tag('combo/menu.html', takes_context=True)
149
def show_menu(context, level=0, current_page=None, depth=1, reduce_depth=False):
149
def show_menu(context, level=0, current_page=None, depth=1, ignore_visibility=False, reduce_depth=False):
150 150
    if reduce_depth:
151 151
        depth -= 1
152 152
    new_context = {
......
154 154
        'render_skeleton': context.get('render_skeleton'),
155 155
        'request': context['request']}
156 156
    return get_menu_context(new_context, level=level, current_page=current_page,
157
            depth=depth)
157
            depth=depth, ignore_visibility=ignore_visibility)
158 158

  
159 159
@register.simple_tag(takes_context=True)
160 160
def page_absolute_url(context, page):
tests/test_cells.py
4 4
import pytest
5 5
import requests
6 6

  
7
from combo.data.models import Page, CellBase, TextCell, LinkCell, JsonCellBase, JsonCell, ConfigJsonCell
7
from combo.data.models import Page, CellBase, TextCell, LinkCell, MenuCell, JsonCellBase, JsonCell, ConfigJsonCell
8 8
from django.conf import settings
9 9
from django.db import connection
10 10
from django.forms.widgets import Media
......
109 109
    assert cell.render(ctx).strip() == '<a href="http://example.net/#anchor">altertitle</a>'
110 110

  
111 111

  
112
def test_menu_cell():
113
    Page.objects.all().delete()
114
    parent = page = Page(title='Page1', slug='page1', template_name='standard')
115
    page.save()
116
    page = Page(title='Page2', slug='page2', template_name='standard',
117
            parent=parent)
118
    page.save()
119
    page = Page(title='Page3', slug='page3', template_name='standard',
120
            parent=parent, public=False)
121
    page.save()
122
    cell = MenuCell(root_page=parent, order=0, page=parent)
123
    cell.save()
124
    request = RequestFactory().get('/page1/')
125
    request.user = None
126
    ctx = {'page': parent, 'request': request}
127
    assert 'menu-page2' in cell.render(ctx)
128
    assert 'menu-page3' not in cell.render(ctx)
129

  
130
    request.user = User(username='foo', email='foo@example.net')
131
    assert 'menu-page2' in cell.render(ctx)
132
    assert 'menu-page3' in cell.render(ctx)
133

  
134
    # check cell is deferred in skeletons if some pages are private
135
    ctx = {'page': parent, 'request': request, 'render_skeleton': True}
136
    with pytest.raises(NothingInCacheException):
137
        cell.render(ctx)
138

  
139
    # and that it's rendered directly if all pages are public
140
    page.public = True
141
    page.save()
142
    ctx = {'page': parent, 'request': request, 'render_skeleton': True}
143
    assert 'menu-page2' in cell.render(ctx)
144
    assert 'menu-page3' in cell.render(ctx)
145

  
146

  
112 147
def test_variant_templates():
113 148
    page = Page(title='example page', slug='example-page')
114 149
    page.save()
tests/test_public.py
269 269
    resp = app.get('/__skeleton__/?source=%s' % quote('http://example.net/foo/bar'))
270 270
    resp = app.get('/__skeleton__/?source=%s' % quote('http://example.net/badredir'))
271 271

  
272
    # add a page with restricted visibility
273
    page = Page(title='RestrictedVisibility', slug='restrictedvisibilit',
274
            template_name='standard', public=False)
275
    page.save()
276
    resp = app.get('/__skeleton__/?source=%s' % quote('http://127.0.0.1:8999/'))
277
    assert 'RestrictedVisibility' in resp.text
278

  
272 279

  
273 280
def test_subpage_location(app):
274 281
    Page.objects.all().delete()
......
317 324
    resp = app.get('/second/child-second/grand-child-second/', status=200)
318 325
    assert 'Grand child of second' in resp.text
319 326

  
327

  
328
def test_menu(app):
329
    Page.objects.all().delete()
330
    page = Page(title='Page1', slug='index', template_name='standard')
331
    page.save()
332
    page = Page(title='Page2', slug='page2', template_name='standard')
333
    page.save()
334
    page = Page(title='Page3', slug='page3', template_name='standard', public=False)
335
    page.save()
336
    resp = app.get('/', status=200)
337
    assert 'menu-index' in resp.text
338
    assert 'menu-page2' in resp.text
339
    assert 'menu-page3' in resp.text
340

  
341

  
320 342
def test_404(app):
321 343
    Page.objects.all().delete()
322 344
    resp = app.get('/foobar/', status=404)
323
-