0001-cells-add-a-cell-type-list-of-links-11006.patch
combo/apps/wcs/models.py | ||
---|---|---|
36 | 36 | |
37 | 37 |
@register_cell_class |
38 | 38 |
class WcsFormCell(CellBase): |
39 |
template_name = 'combo/wcs/form.html' |
|
40 | ||
41 | 39 |
formdef_reference = models.CharField(_('Form'), max_length=150) |
42 | 40 | |
43 | 41 |
cached_title = models.CharField(_('Title'), max_length=150) |
44 | 42 |
cached_url = models.URLField(_('URL')) |
45 | 43 |
cached_json = JSONField(blank=True) |
46 | 44 | |
45 |
template_name = 'combo/wcs/form.html' |
|
46 |
add_as_link_label = _('add a form link') |
|
47 |
add_link_label = _('New form link') |
|
48 |
edit_link_label = _('Edit form link') |
|
49 |
add_as_link_code = 'form-link' |
|
50 | ||
47 | 51 |
is_enabled = classmethod(is_wcs_enabled) |
48 | 52 | |
49 | 53 |
class Meta: |
combo/data/forms.py | ||
---|---|---|
18 | 18 | |
19 | 19 |
from django import forms |
20 | 20 | |
21 |
from .models import Page, ParametersCell, MenuCell, LinkCell, ConfigJsonCell |
|
21 |
from .models import Page, ParametersCell, MenuCell, LinkCell, LinkListCell, ConfigJsonCell
|
|
22 | 22 |
from jsonfield.widgets import JSONWidget |
23 | 23 | |
24 | 24 |
from combo.utils import cache_during_request |
... | ... | |
41 | 41 |
break |
42 | 42 |
return self.cleaned_data |
43 | 43 | |
44 | ||
44 | 45 |
class ParametersCellForm(forms.ModelForm): |
45 | 46 |
class Meta: |
46 | 47 |
model = ParametersCell |
... | ... | |
61 | 62 |
pages = Page.get_as_reordered_flat_hierarchy(Page.objects.all()) |
62 | 63 |
return [(x.id, '%s %s' % (u'\u00a0' * x.level * 2, x.title)) for x in pages] |
63 | 64 | |
65 | ||
64 | 66 |
class MenuCellForm(forms.ModelForm): |
65 | 67 |
class Meta: |
66 | 68 |
model = MenuCell |
... | ... | |
82 | 84 |
choices=[(None, '-----')] + get_page_choices()) |
83 | 85 | |
84 | 86 | |
87 |
class LinkListCellForm(forms.ModelForm): |
|
88 |
class Meta: |
|
89 |
model = LinkListCell |
|
90 |
fields = ['title'] |
|
91 | ||
92 |
def __init__(self, *args, **kwargs): |
|
93 |
super(LinkListCellForm, self).__init__(*args, **kwargs) |
|
94 | ||
95 | ||
85 | 96 |
class ConfigJsonForm(forms.ModelForm): |
86 | 97 |
formdef = [] |
87 | 98 |
combo/data/migrations/0039_link_list_cell.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import migrations, models |
|
5 |
import django.db.models.deletion |
|
6 | ||
7 | ||
8 |
class Migration(migrations.Migration): |
|
9 | ||
10 |
dependencies = [ |
|
11 |
('auth', '0008_alter_user_username_max_length'), |
|
12 |
('data', '0038_increase_jsoncell_url_max_length'), |
|
13 |
] |
|
14 | ||
15 |
operations = [ |
|
16 |
migrations.CreateModel( |
|
17 |
name='LinkListCell', |
|
18 |
fields=[ |
|
19 |
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|
20 |
('placeholder', models.CharField(max_length=20)), |
|
21 |
('order', models.PositiveIntegerField()), |
|
22 |
('slug', models.SlugField(blank=True, verbose_name='Slug')), |
|
23 |
('extra_css_class', models.CharField(blank=True, max_length=100, verbose_name='Extra classes for CSS styling')), |
|
24 |
('public', models.BooleanField(default=True, verbose_name='Public')), |
|
25 |
('restricted_to_unlogged', models.BooleanField(default=False, verbose_name='Restrict to unlogged users')), |
|
26 |
('last_update_timestamp', models.DateTimeField(auto_now=True)), |
|
27 |
('groups', models.ManyToManyField(blank=True, to='auth.Group', verbose_name='Groups')), |
|
28 |
('title', models.CharField(max_length=150, verbose_name='Title', blank=True)), |
|
29 |
], |
|
30 |
options={ |
|
31 |
'verbose_name': 'List of links', |
|
32 |
}, |
|
33 |
), |
|
34 |
migrations.AddField( |
|
35 |
model_name='linklistcell', |
|
36 |
name='page', |
|
37 |
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='data.Page'), |
|
38 |
), |
|
39 |
] |
combo/data/models.py | ||
---|---|---|
451 | 451 |
new_page.groups.set(self.groups.all()) |
452 | 452 | |
453 | 453 |
for cell in self.get_cells(): |
454 |
if cell.placeholder and cell.placeholder.startswith('_'): |
|
455 |
continue |
|
454 | 456 |
cell.duplicate(page_target=new_page) |
455 | 457 | |
456 | 458 |
return new_page |
... | ... | |
756 | 758 |
def import_subobjects(self, cell_json): |
757 | 759 |
pass |
758 | 760 | |
759 |
def duplicate(self, page_target=None): |
|
761 |
def duplicate(self, page_target=None, placeholder=None):
|
|
760 | 762 |
# clone current cell |
761 | 763 |
new_cell = copy.deepcopy(self) |
762 | 764 |
new_cell.pk = None |
763 | 765 |
# set page |
764 | 766 |
new_cell.page = page_target or self.page |
767 |
# set placeholder |
|
768 |
new_cell.placeholder = placeholder or new_cell.placeholder |
|
765 | 769 |
# store new cell |
766 | 770 |
new_cell.save() |
767 | 771 | |
... | ... | |
905 | 909 |
anchor = models.CharField(_('Anchor'), max_length=150, blank=True) |
906 | 910 | |
907 | 911 |
template_name = 'combo/link-cell.html' |
912 |
add_as_link_label = _('add a link') |
|
913 |
add_link_label = _('New link') |
|
914 |
edit_link_label = _('Edit link') |
|
915 |
add_as_link_code = 'link' |
|
908 | 916 | |
909 | 917 |
class Meta: |
910 | 918 |
verbose_name = _('Link') |
... | ... | |
950 | 958 |
return [] |
951 | 959 | |
952 | 960 | |
961 |
@register_cell_class |
|
962 |
class LinkListCell(CellBase): |
|
963 |
title = models.CharField(_('Title'), max_length=150, blank=True) |
|
964 | ||
965 |
template_name = 'combo/link-list-cell.html' |
|
966 |
manager_form_template = 'combo/manager/link-list-cell-form.html' |
|
967 | ||
968 |
class Meta: |
|
969 |
verbose_name = _('List of links') |
|
970 | ||
971 |
@property |
|
972 |
def link_placeholder(self): |
|
973 |
return '_linkslist:{}'.format(self.pk) |
|
974 | ||
975 |
def get_items(self): |
|
976 |
return CellBase.get_cells( |
|
977 |
page=self.page, |
|
978 |
placeholder=self.link_placeholder, |
|
979 |
cell_filter=lambda x: hasattr(x, 'add_as_link_label')) |
|
980 | ||
981 |
def get_additional_label(self): |
|
982 |
title = self.title |
|
983 |
if not title: |
|
984 |
return None |
|
985 |
return utils.ellipsize(title) |
|
986 | ||
987 |
def get_cell_extra_context(self, context): |
|
988 |
extra_context = super(LinkListCell, self).get_cell_extra_context(context) |
|
989 |
links = [] |
|
990 |
for cell in context.get('page_cells', []): |
|
991 |
if not hasattr(cell, 'add_as_link_label'): |
|
992 |
continue |
|
993 |
if not cell.placeholder == self.link_placeholder: |
|
994 |
continue |
|
995 |
links.append(cell.get_cell_extra_context(context)) |
|
996 |
extra_context['links'] = links |
|
997 |
extra_context['title'] = self.title |
|
998 |
return extra_context |
|
999 | ||
1000 |
def get_link_cell_classes(self): |
|
1001 |
return CellBase.get_cell_classes(lambda x: hasattr(x, 'add_as_link_label')) |
|
1002 | ||
1003 |
def get_default_form_class(self): |
|
1004 |
from .forms import LinkListCellForm |
|
1005 |
return LinkListCellForm |
|
1006 | ||
1007 |
def render_for_search(self): |
|
1008 |
return '' |
|
1009 | ||
1010 |
def export_subobjects(self): |
|
1011 |
return {'links': json.loads( |
|
1012 |
serializers.serialize( |
|
1013 |
'json', |
|
1014 |
self.get_items(), |
|
1015 |
use_natural_foreign_keys=True, |
|
1016 |
use_natural_primary_keys=True) |
|
1017 |
)} |
|
1018 | ||
1019 |
def import_subobjects(self, cell_json): |
|
1020 |
for link in cell_json['links']: |
|
1021 |
link['fields']['placeholder'] = self.link_placeholder |
|
1022 |
for link in serializers.deserialize('json', json.dumps(cell_json['links'])): |
|
1023 |
link.save() |
|
1024 | ||
1025 |
def duplicate_m2m(self, new_cell): |
|
1026 |
# duplicate also link items |
|
1027 |
for link in self.get_items(): |
|
1028 |
link.duplicate(page_target=new_cell.page, placeholder=new_cell.link_placeholder) |
|
1029 | ||
1030 | ||
953 | 1031 |
@register_cell_class |
954 | 1032 |
class FeedCell(CellBase): |
955 | 1033 |
title = models.CharField(_('Title'), max_length=150, blank=True) |
combo/data/templates/combo/manager/link-list-cell-form.html | ||
---|---|---|
1 |
{% extends "combo/cell_form.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block cell-form %} |
|
5 |
{% with cell.get_items as links %} |
|
6 |
{% if links %} |
|
7 |
<table class="main"> |
|
8 |
<tbody class="link-list" data-link-list-order-url="{% url 'combo-manager-link-list-order' page_pk=page.pk cell_reference=cell.get_reference %}"> |
|
9 |
{% for link in links %} |
|
10 |
<tr class="link-item" data-link-item-id="{{ link.pk }}"> |
|
11 |
<td><span class="handle-link-item">⣿</span> {{ link }}</td> |
|
12 |
<td> |
|
13 |
<a rel="popup" href="{% url 'combo-manager-page-list-cell-edit-link' page_pk=page.id cell_reference=cell.get_reference link_cell_reference=link.get_reference %}">{% trans "Edit" %}</a> | |
|
14 |
<a rel="popup" href="{% url 'combo-manager-page-list-cell-delete-link' page_pk=page.id cell_reference=cell.get_reference link_cell_reference=link.get_reference %}">{% trans "Delete" %}</a> |
|
15 |
</td> |
|
16 |
</tr> |
|
17 |
{% endfor %} |
|
18 |
</tbody> |
|
19 |
</table> |
|
20 |
{% endif %} |
|
21 |
{% endwith %} |
|
22 |
<div class="buttons"> |
|
23 |
{% for klass in cell.get_link_cell_classes %} |
|
24 |
<a rel="popup" href="{% url 'combo-manager-page-list-cell-add-link' page_pk=page.id cell_reference=cell.get_reference link_code=klass.add_as_link_code %}">{{ klass.add_as_link_label }}</a> {% if not forloop.last %}|{% endif %} |
|
25 |
{% endfor %} |
|
26 |
</div> |
|
27 |
<br /> |
|
28 |
{{ form.as_p }} |
|
29 |
{% endblock %} |
combo/manager/static/js/combo.manager.js | ||
---|---|---|
220 | 220 |
return false; |
221 | 221 |
}); |
222 | 222 | |
223 |
$('.link-list').sortable({ |
|
224 |
handle: '.handle-link-item', |
|
225 |
stop: function(event, ui) { |
|
226 |
var new_order = Object(); |
|
227 |
$('.link-item').each(function(i, x) { |
|
228 |
var suffix = $(x).data('link-item-id'); |
|
229 |
new_order['pos_' + suffix] = i; |
|
230 |
}); |
|
231 |
$.ajax({ |
|
232 |
url: $(this).data('link-list-order-url'), |
|
233 |
data: new_order |
|
234 |
}); |
|
235 |
} |
|
236 |
}); |
|
237 | ||
223 | 238 |
function compute_max_height($cell) { |
224 | 239 |
var cell_id = $cell.attr('id'); |
225 | 240 |
$('style#for-' + cell_id).remove(); |
combo/manager/templates/combo/link_cell_form.html | ||
---|---|---|
1 |
{% extends "combo/manager_base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
{% if form.instance.pk %} |
|
6 |
<h2>{{ form.instance.edit_link_label }}</h2> |
|
7 |
{% else %} |
|
8 |
<h2>{{ form.instance.add_link_label }}</h2> |
|
9 |
{% endif %} |
|
10 |
{% endblock %} |
|
11 | ||
12 |
{% block content %} |
|
13 | ||
14 |
<form method="post" enctype="multipart/form-data"> |
|
15 |
{% csrf_token %} |
|
16 |
{{ form.as_p }} |
|
17 |
<div class="buttons"> |
|
18 |
<button class="submit-button">{% trans "Save" %}</button> |
|
19 |
<a class="cancel" href="{% url 'combo-manager-page-view' pk=form.instance.page_id %}">{% trans 'Cancel' %}</a> |
|
20 |
</div> |
|
21 |
</form> |
|
22 |
{% endblock %} |
combo/manager/urls.py | ||
---|---|---|
75 | 75 |
name='combo-manager-page-visibility-cell'), |
76 | 76 |
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/label$', |
77 | 77 |
views.page_get_additional_label, name='combo-manager-page-get-additional-label'), |
78 |
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/add-link/(?P<link_code>[\w-]+)$', |
|
79 |
views.page_list_cell_add_link, |
|
80 |
name='combo-manager-page-list-cell-add-link'), |
|
81 |
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/link/(?P<link_cell_reference>[\w_-]+)/$', |
|
82 |
views.page_list_cell_edit_link, |
|
83 |
name='combo-manager-page-list-cell-edit-link'), |
|
84 |
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/link/(?P<link_cell_reference>[\w_-]+)/delete$', |
|
85 |
views.page_list_cell_delete_link, |
|
86 |
name='combo-manager-page-list-cell-delete-link'), |
|
87 |
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/order$', |
|
88 |
views.link_list_order, |
|
89 |
name='combo-manager-link-list-order'), |
|
78 | 90 |
url(r'^pages/(?P<page_pk>\d+)/order$', views.cell_order, |
79 | 91 |
name='combo-manager-cell-order'), |
80 | 92 |
url(r'^pages/order$', views.page_order, |
combo/manager/views.py | ||
---|---|---|
33 | 33 |
from django.views.generic import (RedirectView, DetailView, |
34 | 34 |
CreateView, UpdateView, ListView, DeleteView, FormView) |
35 | 35 | |
36 |
from combo.data.models import Page, CellBase, ParentContentCell, PageSnapshot |
|
36 |
from combo.data.models import Page, CellBase, ParentContentCell, PageSnapshot, LinkListCell
|
|
37 | 37 |
from combo.data.library import get_cell_class |
38 | 38 |
from combo.data.utils import export_site, import_site, MissingGroups |
39 | 39 |
from combo import plugins |
... | ... | |
124 | 124 |
return super(CreateView, self).get_initial() |
125 | 125 | |
126 | 126 |
def dispatch(self, request, *args, **kwargs): |
127 |
print(request.POST) |
|
128 | 127 |
self.parent = get_object_or_404(Page, pk=kwargs['pk']) |
129 | 128 |
return super(PageAddChildView, self).dispatch(request, *args, **kwargs) |
130 | 129 | |
... | ... | |
564 | 563 |
response = HttpResponse(content_type=content_type) |
565 | 564 |
response.write(json_str) |
566 | 565 |
return response |
566 | ||
567 | ||
568 |
class PageListCellAddLinkView(CreateView): |
|
569 |
template_name = 'combo/link_cell_form.html' |
|
570 | ||
571 |
def dispatch(self, request, *args, **kwargs): |
|
572 |
try: |
|
573 |
self.cell = CellBase.get_cell(kwargs['cell_reference'], page=kwargs['page_pk']) |
|
574 |
except LinkListCell.DoesNotExist: |
|
575 |
raise Http404 |
|
576 |
for klass in self.cell.get_link_cell_classes(): |
|
577 |
if klass.add_as_link_code == kwargs['link_code']: |
|
578 |
self.model = klass |
|
579 |
break |
|
580 |
if self.model is None: |
|
581 |
raise Http404 |
|
582 |
return super(PageListCellAddLinkView, self).dispatch(request, *args, **kwargs) |
|
583 | ||
584 |
def get_form_class(self): |
|
585 |
return self.model().get_default_form_class() |
|
586 | ||
587 |
def get_form_kwargs(self): |
|
588 |
kwargs = super(PageListCellAddLinkView, self).get_form_kwargs() |
|
589 |
kwargs['instance'] = self.model(page=self.cell.page, placeholder=self.cell.link_placeholder) |
|
590 |
return kwargs |
|
591 | ||
592 |
def form_valid(self, form): |
|
593 |
orders = [x.order for x in self.cell.get_items()] |
|
594 |
if orders: |
|
595 |
form.instance.order = max(orders)+1 |
|
596 |
else: |
|
597 |
form.instance.order = 1 |
|
598 |
return super(PageListCellAddLinkView, self).form_valid(form) |
|
599 | ||
600 |
def get_success_url(self): |
|
601 |
return '%s#cell-%s' % ( |
|
602 |
reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')}), |
|
603 |
self.kwargs['cell_reference']) |
|
604 | ||
605 | ||
606 |
page_list_cell_add_link = PageListCellAddLinkView.as_view() |
|
607 | ||
608 | ||
609 |
class PageListCellEditLinkView(UpdateView): |
|
610 |
template_name = 'combo/link_cell_form.html' |
|
611 | ||
612 |
def dispatch(self, request, *args, **kwargs): |
|
613 |
try: |
|
614 |
self.cell = CellBase.get_cell(kwargs['cell_reference'], page=kwargs['page_pk']) |
|
615 |
except LinkListCell.DoesNotExist: |
|
616 |
raise Http404 |
|
617 |
try: |
|
618 |
self.object = CellBase.get_cell(kwargs['link_cell_reference'], page=kwargs['page_pk']) |
|
619 |
except ObjectDoesNotExist: |
|
620 |
raise Http404 |
|
621 |
if self.object.placeholder != self.cell.link_placeholder: |
|
622 |
raise Http404 |
|
623 |
self.model = self.object.__class__ |
|
624 |
return super(PageListCellEditLinkView, self).dispatch(request, *args, **kwargs) |
|
625 | ||
626 |
def get_object(self, *args, **kwargs): |
|
627 |
return self.object |
|
628 | ||
629 |
def get_form_class(self): |
|
630 |
return self.model().get_default_form_class() |
|
631 | ||
632 |
def form_valid(self, form): |
|
633 |
if self.request.is_ajax(): |
|
634 |
self.object = form.save() |
|
635 |
response = self.form_invalid(form) # avoid redirection |
|
636 |
else: |
|
637 |
response = super(PageListCellEditLinkView, self).form_valid(form) |
|
638 |
PageSnapshot.take(self.cell.page, request=self.request, comment=_('changed cell "%s"') % self.cell) |
|
639 |
return response |
|
640 | ||
641 |
def get_success_url(self): |
|
642 |
return '%s#cell-%s' % ( |
|
643 |
reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')}), |
|
644 |
self.kwargs['cell_reference']) |
|
645 | ||
646 | ||
647 |
page_list_cell_edit_link = PageListCellEditLinkView.as_view() |
|
648 | ||
649 | ||
650 |
class PageListCellDeleteLinkView(DeleteView): |
|
651 |
template_name = 'combo/generic_confirm_delete.html' |
|
652 | ||
653 |
def dispatch(self, request, *args, **kwargs): |
|
654 |
try: |
|
655 |
self.cell = CellBase.get_cell(kwargs['cell_reference'], page=kwargs['page_pk']) |
|
656 |
except LinkListCell.DoesNotExist: |
|
657 |
raise Http404 |
|
658 |
try: |
|
659 |
self.object = CellBase.get_cell(kwargs['link_cell_reference'], page=kwargs['page_pk']) |
|
660 |
except ObjectDoesNotExist: |
|
661 |
raise Http404 |
|
662 |
if self.object.placeholder != self.cell.link_placeholder: |
|
663 |
raise Http404 |
|
664 |
self.model = self.object.__class__ |
|
665 |
return super(PageListCellDeleteLinkView, self).dispatch(request, *args, **kwargs) |
|
666 | ||
667 |
def get_object(self, *args, **kwargs): |
|
668 |
return self.object |
|
669 | ||
670 |
def delete(self, request, *args, **kwargs): |
|
671 |
response = super(PageListCellDeleteLinkView, self).delete(request, *args, **kwargs) |
|
672 |
PageSnapshot.take(self.cell.page, request=self.request, comment=_('changed cell "%s"') % self.cell) |
|
673 |
return response |
|
674 | ||
675 |
def get_success_url(self): |
|
676 |
return '%s#cell-%s' % ( |
|
677 |
reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')}), |
|
678 |
self.kwargs['cell_reference']) |
|
679 | ||
680 | ||
681 |
page_list_cell_delete_link = PageListCellDeleteLinkView.as_view() |
|
682 | ||
683 | ||
684 |
def link_list_order(request, page_pk, cell_reference): |
|
685 |
try: |
|
686 |
cell = CellBase.get_cell(cell_reference, page=page_pk) |
|
687 |
except LinkListCell.DoesNotExist: |
|
688 |
raise Http404 |
|
689 | ||
690 |
has_changes = False |
|
691 |
for link in cell.get_items(): |
|
692 |
old_order = link.order |
|
693 |
try: |
|
694 |
new_order = int(request.GET.get('pos_' + str(link.pk))) |
|
695 |
except TypeError: |
|
696 |
continue |
|
697 |
if new_order != old_order: |
|
698 |
link.order = new_order |
|
699 |
has_changes = True |
|
700 |
link.save(update_fields=['order']) |
|
701 | ||
702 |
if has_changes: |
|
703 |
PageSnapshot.take(cell.page, request=request, comment=_('reordered cells')) |
|
704 | ||
705 |
return HttpResponse(status=204) |
combo/public/templates/combo/link-list-cell.html | ||
---|---|---|
1 |
{% block cell-content %} |
|
2 |
{% spaceless %} |
|
3 |
<div class="links-list"> |
|
4 |
{% if title %}<h2>{{title}}</h2>{% endif %} |
|
5 |
<ul> |
|
6 |
{% for link in links %} |
|
7 |
<li><a href="{{ link.url }}">{{ link.title }}</a></li> |
|
8 |
{% endfor %} |
|
9 |
</ul> |
|
10 |
</div> |
|
11 |
{% endspaceless %} |
|
12 |
{% endblock %} |
tests/test_cells.py | ||
---|---|---|
4 | 4 |
import pytest |
5 | 5 |
import requests |
6 | 6 | |
7 |
from combo.data.models import Page, CellBase, TextCell, LinkCell, MenuCell, JsonCellBase, JsonCell, ConfigJsonCell |
|
7 |
from combo.data.models import ( |
|
8 |
Page, CellBase, TextCell, LinkCell, MenuCell, JsonCellBase, |
|
9 |
JsonCell, ConfigJsonCell, LinkListCell |
|
10 |
) |
|
8 | 11 |
from django.conf import settings |
9 | 12 |
from django.db import connection |
10 | 13 |
from django.forms.widgets import Media |
... | ... | |
93 | 96 |
assert 'href=""' in cell.render(ctx) |
94 | 97 |
assert 'href="/plop"' in cell.render(ctx) |
95 | 98 | |
99 | ||
96 | 100 |
def test_link_cell(): |
97 | 101 |
page = Page(title='example page', slug='example-page') |
98 | 102 |
page.save() |
... | ... | |
130 | 134 |
assert cell.render(ctx).strip() == '<a href="http://example.net/#anchor">altertitle</a>' |
131 | 135 | |
132 | 136 | |
137 |
def test_link_list_cell(): |
|
138 |
page = Page.objects.create(title='example page', slug='example-page') |
|
139 | ||
140 |
cell = LinkListCell.objects.create(order=0, page=page) |
|
141 |
item = LinkCell.objects.create( |
|
142 |
page=page, |
|
143 |
placeholder=cell.link_placeholder, |
|
144 |
title='Example Site', |
|
145 |
url='http://example.net/', |
|
146 |
order=0, |
|
147 |
) |
|
148 | ||
149 |
ctx = {'page_cells': [item]} |
|
150 |
assert '<ul><li><a href="http://example.net/">Example Site</a></li></ul>' in cell.render(ctx) |
|
151 | ||
152 |
item.title = '' |
|
153 |
assert '<ul><li><a href="http://example.net/">http://example.net/</a></li></ul>' in cell.render(ctx) |
|
154 | ||
155 |
item.link_page = page |
|
156 |
assert '<ul><li><a href="/example-page/">example page</a></li></ul>' in cell.render(ctx) |
|
157 | ||
158 |
item.title = 'altertitle' |
|
159 |
assert '<ul><li><a href="/example-page/">altertitle</a></li></ul>' in cell.render(ctx) |
|
160 | ||
161 |
item.anchor = 'anchor' |
|
162 |
assert '<ul><li><a href="/example-page/#anchor">altertitle</a></li></ul>' in cell.render(ctx) |
|
163 | ||
164 |
item.link_page = None |
|
165 |
assert '<ul><li><a href="http://example.net/#anchor">altertitle</a></li></ul>' in cell.render(ctx) |
|
166 | ||
167 | ||
133 | 168 |
def test_menu_cell(): |
134 | 169 |
Page.objects.all().delete() |
135 | 170 |
parent = page = Page(title='Page1', slug='page1', template_name='standard') |
... | ... | |
728 | 763 | |
729 | 764 |
TextCell(page=page, placeholder='content', order=0, text='hello').save() |
730 | 765 |
assert set(Page.objects.get(id=page.id).related_cells['cell_types']) == set(['data_textcell', 'data_linkcell']) |
766 | ||
767 | ||
768 |
def test_link_list_cell_duplicate(): |
|
769 |
page = Page.objects.create(title='xxx', slug='new', template_name='standard') |
|
770 |
cell = LinkListCell.objects.create(order=0, page=page) |
|
771 |
item = LinkCell.objects.create( |
|
772 |
page=page, |
|
773 |
placeholder=cell.link_placeholder, |
|
774 |
title='Example Site', |
|
775 |
url='http://example.net/', |
|
776 |
link_page=page, |
|
777 |
order=1, |
|
778 |
) |
|
779 | ||
780 |
new_cell = cell.duplicate() |
|
781 |
assert LinkCell.objects.count() == 2 |
|
782 |
assert len(new_cell.get_items()) == 1 |
|
783 |
new_item = new_cell.get_items()[0] |
|
784 |
assert new_item.page == page |
|
785 |
assert new_item.placeholder == new_cell.link_placeholder |
|
786 |
assert new_item.pk != item.pk |
|
787 |
assert new_item.title == item.title |
|
788 |
assert new_item.url == item.url |
|
789 |
assert new_item.link_page == item.link_page |
tests/test_manager.py | ||
---|---|---|
21 | 21 |
from webtest import Upload |
22 | 22 | |
23 | 23 |
from combo.wsgi import application |
24 |
from combo.data.models import Page, CellBase, TextCell, LinkCell, ConfigJsonCell, JsonCell, PageSnapshot |
|
24 |
from combo.data.models import Page, CellBase, TextCell, LinkCell, ConfigJsonCell, JsonCell, PageSnapshot, LinkListCell
|
|
25 | 25 |
from combo.apps.assets.models import Asset |
26 | 26 |
from combo.apps.family.models import FamilyInfosCell |
27 | 27 |
from combo.apps.search.models import SearchCell |
... | ... | |
1373 | 1373 |
assert 'syntax error' not in resp.text |
1374 | 1374 |
assert JsonCell.objects.count() == 1 |
1375 | 1375 |
assert JsonCell.objects.first().template_string == '{{ ok }}' |
1376 | ||
1377 | ||
1378 |
def test_add_edit_delete_list_link_item(app, admin_user): |
|
1379 |
Page.objects.all().delete() |
|
1380 |
page = Page.objects.create(title='One', slug='one', template_name='standard') |
|
1381 |
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page) |
|
1382 |
app = login(app) |
|
1383 |
resp = app.get('/manage/pages/%s/' % page.pk) |
|
1384 | ||
1385 |
resp = resp.click(href='.*/add-link/link$') |
|
1386 |
resp.forms[0]['title'] = 'Hello world' |
|
1387 |
resp.forms[0]['url'] = 'http://example.com' |
|
1388 |
resp = resp.forms[0].submit() |
|
1389 |
assert resp.status_int == 302 |
|
1390 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference())) |
|
1391 |
assert LinkCell.objects.count() == 1 |
|
1392 |
item = LinkCell.objects.get() |
|
1393 |
assert item.title == 'Hello world' |
|
1394 |
assert item.url == 'http://example.com' |
|
1395 |
assert item.page == page |
|
1396 |
assert item.placeholder == cell.link_placeholder |
|
1397 | ||
1398 |
resp = resp.follow() |
|
1399 |
resp = resp.click(href='.*/link/%s/$' % item.get_reference()) |
|
1400 |
resp.forms[0]['title'] = 'Hello world 2' |
|
1401 |
resp.forms[0]['url'] = 'http://example2.com' |
|
1402 |
resp = resp.forms[0].submit() |
|
1403 |
assert resp.status_int == 302 |
|
1404 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference())) |
|
1405 |
assert LinkCell.objects.count() == 1 |
|
1406 |
item.refresh_from_db() |
|
1407 |
assert item.title == 'Hello world 2' |
|
1408 |
assert item.url == 'http://example2.com' |
|
1409 | ||
1410 |
resp = resp.follow() |
|
1411 |
resp = resp.click(href='.*/link/%s/delete' % item.get_reference()) |
|
1412 |
resp = resp.forms[0].submit() |
|
1413 |
assert resp.status_int == 302 |
|
1414 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference())) |
|
1415 |
assert LinkCell.objects.count() == 0 |
|
1416 | ||
1417 | ||
1418 |
def test_edit_link_list_order(app, admin_user): |
|
1419 |
Page.objects.all().delete() |
|
1420 |
page = Page.objects.create(title='One', slug='one', template_name='standard') |
|
1421 |
cell = LinkListCell.objects.create(order=0, page=page) |
|
1422 |
items = [] |
|
1423 |
for i in range(5): |
|
1424 |
items.append( |
|
1425 |
LinkCell.objects.create( |
|
1426 |
page=page, |
|
1427 |
placeholder=cell.link_placeholder, |
|
1428 |
title='Foo %s' % i, |
|
1429 |
url='http://example.net/', |
|
1430 |
link_page=page, |
|
1431 |
order=i+1, |
|
1432 |
) |
|
1433 |
) |
|
1434 | ||
1435 |
params = [] |
|
1436 |
new_order = [2, 3, 1, 4, 5] |
|
1437 |
for i, (item, new_pos) in enumerate(zip(items, new_order)): |
|
1438 |
params.append(('pos_%s' % item.pk, str(new_pos))) |
|
1439 | ||
1440 |
app = login(app) |
|
1441 |
resp = app.get('/manage/pages/%s/cell/%s/order?%s' % (page.pk, cell.get_reference(), urlencode(params))) |
|
1442 |
assert resp.status_code == 204 |
|
1443 |
for i, item in enumerate(items): |
|
1444 |
item.refresh_from_db() |
|
1445 |
assert item.order == new_order[i] |
tests/test_pages.py | ||
---|---|---|
9 | 9 |
from django.test.client import RequestFactory |
10 | 10 |
from django.utils.six import StringIO |
11 | 11 |
from django.utils.timezone import now |
12 |
from combo.data.models import Page, PageSnapshot, CellBase, TextCell, LinkCell |
|
12 |
from combo.data.models import Page, PageSnapshot, CellBase, TextCell, LinkCell, LinkListCell
|
|
13 | 13 |
from combo.data.management.commands.import_site import Command as ImportSiteCommand |
14 | 14 |
from combo.data.management.commands.export_site import Command as ExportSiteCommand |
15 | 15 |
from combo.manager.forms import PageVisibilityForm |
... | ... | |
182 | 182 |
cell2 = LinkCell(page=page2, title='foo', placeholder='content', link_page=page, order=1) |
183 | 183 |
cell2.save() |
184 | 184 | |
185 |
cell3 = LinkListCell.objects.create(page=page, placeholder='content', order=2) |
|
186 |
item1 = LinkCell.objects.create( |
|
187 |
page=page, |
|
188 |
placeholder=cell3.link_placeholder, |
|
189 |
title='Example Site', |
|
190 |
url='http://example.net/', |
|
191 |
order=0, |
|
192 |
) |
|
193 |
item2 = LinkCell.objects.create( |
|
194 |
page=page, |
|
195 |
placeholder=cell3.link_placeholder, |
|
196 |
title='blah', |
|
197 |
link_page=page2, |
|
198 |
order=1, |
|
199 |
) |
|
200 | ||
185 | 201 |
site_export = [x.get_serialized_page() for x in Page.objects.all()] |
186 | 202 |
Page.objects.all().delete() |
187 | 203 | |
... | ... | |
189 | 205 | |
190 | 206 |
new_page_1 = Page.objects.all().order_by('order')[0] |
191 | 207 |
new_page_2 = Page.objects.all().order_by('order')[1] |
192 |
assert CellBase.get_cells(page_id=new_page_1.id)[0].link_page_id == new_page_2.id |
|
193 |
assert CellBase.get_cells(page_id=new_page_2.id)[0].link_page_id == new_page_1.id |
|
208 |
new_cells_1 = CellBase.get_cells(page_id=new_page_1.id, placeholder='content') |
|
209 |
new_cells_2 = CellBase.get_cells(page_id=new_page_2.id, placeholder='content') |
|
210 |
assert new_cells_1[0].link_page_id == new_page_2.id |
|
211 |
assert new_cells_2[0].link_page_id == new_page_1.id |
|
212 |
assert len(new_cells_1[1].get_items()) == 2 |
|
213 |
new_item_1 = new_cells_1[1].get_items()[0] |
|
214 |
assert isinstance(new_item_1, LinkCell) |
|
215 |
assert new_item_1.title == item1.title |
|
216 |
assert new_item_1.url == item1.url |
|
217 |
assert new_item_1.link_page is None |
|
218 |
new_item_2 = new_cells_1[1].get_items()[1] |
|
219 |
assert isinstance(new_item_2, LinkCell) |
|
220 |
assert new_item_2.title == item2.title |
|
221 |
assert new_item_2.url == '' |
|
222 |
assert new_item_2.link_page == new_page_2 |
|
194 | 223 | |
195 | 224 | |
196 | 225 |
def test_duplicate_page(): |
tests/test_wcs.py | ||
---|---|---|
22 | 22 | |
23 | 23 |
import mock |
24 | 24 | |
25 |
from combo.data.models import Page |
|
25 |
from combo.data.models import CellBase, LinkListCell, Page
|
|
26 | 26 |
from combo.apps.search.engines import engines |
27 | 27 |
from combo.apps.wcs.models import (WcsFormCell, WcsCurrentFormsCell, |
28 | 28 |
WcsFormsOfCategoryCell, WcsCurrentDraftsCell, WcsCategoryCell, |
... | ... | |
901 | 901 | |
902 | 902 |
result = cell.render(context) |
903 | 903 |
assert '/backoffice/submission/a-private-form/' in result |
904 | ||
905 | ||
906 |
@wcs_present |
|
907 |
def test_manager_link_list_cell_duplicate(): |
|
908 |
page = Page.objects.create(title='xxx', slug='new', template_name='standard') |
|
909 |
cell = LinkListCell.objects.create(order=0, page=page) |
|
910 |
item = WcsFormCell.objects.create( |
|
911 |
page=page, |
|
912 |
placeholder=cell.link_placeholder, |
|
913 |
cached_title='A title', |
|
914 |
cached_url='http://example.com', |
|
915 |
cached_json={'foo': 'bar'}, |
|
916 |
order=1) |
|
917 | ||
918 |
new_cell = cell.duplicate() |
|
919 |
assert WcsFormCell.objects.count() == 2 |
|
920 |
assert len(new_cell.get_items()) == 1 |
|
921 |
new_item = new_cell.get_items()[0] |
|
922 |
assert new_item.page == page |
|
923 |
assert new_item.placeholder == new_cell.link_placeholder |
|
924 |
assert new_item.pk != item.pk |
|
925 |
assert new_item.cached_title == item.cached_title |
|
926 |
assert new_item.cached_url == item.cached_url |
|
927 |
assert new_item.cached_json == item.cached_json |
|
928 | ||
929 | ||
930 |
@wcs_present |
|
931 |
def test_manager_add_edit_delete_list_link_item(app, admin_user): |
|
932 |
Page.objects.all().delete() |
|
933 |
page = Page.objects.create(title='One', slug='one', template_name='standard') |
|
934 |
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page) |
|
935 |
app = login(app) |
|
936 |
resp = app.get('/manage/pages/%s/' % page.pk) |
|
937 | ||
938 |
resp = resp.click(href='.*/add-link/form-link$') |
|
939 |
resp.forms[0]['formdef_reference'] = 'default:form-title' |
|
940 |
resp = resp.forms[0].submit() |
|
941 |
assert resp.status_int == 302 |
|
942 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference())) |
|
943 |
assert WcsFormCell.objects.count() == 1 |
|
944 |
item = WcsFormCell.objects.get() |
|
945 |
assert item.formdef_reference == 'default:form-title' |
|
946 |
assert item.page == page |
|
947 |
assert item.placeholder == cell.link_placeholder |
|
948 | ||
949 |
resp = resp.follow() |
|
950 |
resp = resp.click(href='.*/link/%s/$' % item.get_reference()) |
|
951 |
resp.forms[0]['formdef_reference'] = 'default:a-private-form' |
|
952 |
resp = resp.forms[0].submit() |
|
953 |
assert resp.status_int == 302 |
|
954 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference())) |
|
955 |
assert WcsFormCell.objects.count() == 1 |
|
956 |
item.refresh_from_db() |
|
957 |
assert item.formdef_reference == 'default:a-private-form' |
|
958 | ||
959 |
resp = resp.follow() |
|
960 |
resp = resp.click(href='.*/link/%s/delete' % item.get_reference()) |
|
961 |
resp = resp.forms[0].submit() |
|
962 |
assert resp.status_int == 302 |
|
963 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference())) |
|
964 |
assert WcsFormCell.objects.count() == 0 |
|
965 | ||
966 | ||
967 |
def test_import_export_pages_with_links(): |
|
968 |
page = Page(title=u'bar', slug='bar', order=1) |
|
969 |
page.save() |
|
970 | ||
971 |
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page) |
|
972 |
item = WcsFormCell.objects.create( |
|
973 |
page=page, |
|
974 |
placeholder=cell.link_placeholder, |
|
975 |
cached_title='A title', |
|
976 |
cached_url='http://example.com', |
|
977 |
cached_json={'foo': 'bar'}, |
|
978 |
order=0, |
|
979 |
) |
|
980 | ||
981 |
site_export = [x.get_serialized_page() for x in Page.objects.all()] |
|
982 |
Page.objects.all().delete() |
|
983 | ||
984 |
Page.load_serialized_pages(site_export) |
|
985 | ||
986 |
new_page = Page.objects.get() |
|
987 |
new_cells = CellBase.get_cells(page_id=new_page.id, placeholder='content') |
|
988 |
assert len(new_cells[0].get_items()) == 1 |
|
989 |
new_item = new_cells[0].get_items()[0] |
|
990 |
assert isinstance(new_item, WcsFormCell) |
|
991 |
assert new_item.cached_title == item.cached_title |
|
992 |
assert new_item.cached_url == item.cached_url |
|
993 |
assert new_item.cached_json == item.cached_json |
|
904 |
- |