0001-wcs-card-cell-title-can-be-empty-56584.patch
combo/apps/wcs/forms.py | ||
---|---|---|
74 | 74 | |
75 | 75 |
class Meta: |
76 | 76 |
model = WcsCardInfosCell |
77 |
fields = ('carddef_reference', 'custom_title', 'card_id', 'custom_schema') |
|
77 |
fields = ('carddef_reference', 'title_type', 'custom_title', 'card_id', 'custom_schema')
|
|
78 | 78 |
widgets = { |
79 | 79 |
'custom_schema': forms.HiddenInput(), |
80 | 80 |
} |
combo/apps/wcs/migrations/0037_card_title_type.py | ||
---|---|---|
1 |
from django.db import migrations, models |
|
2 | ||
3 | ||
4 |
class Migration(migrations.Migration): |
|
5 | ||
6 |
dependencies = [ |
|
7 |
('wcs', '0036_remove_wcscurrentformscell_include_forms_user_can_access'), |
|
8 |
] |
|
9 | ||
10 |
operations = [ |
|
11 |
migrations.AddField( |
|
12 |
model_name='wcscardinfoscell', |
|
13 |
name='title_type', |
|
14 |
field=models.CharField( |
|
15 |
choices=[ |
|
16 |
('auto', 'Default Title (Card Label)'), |
|
17 |
('manual', 'Custom Title'), |
|
18 |
('empty', 'No Title'), |
|
19 |
], |
|
20 |
default='auto', |
|
21 |
max_length=20, |
|
22 |
verbose_name='Title', |
|
23 |
), |
|
24 |
), |
|
25 |
] |
combo/apps/wcs/migrations/0038_card_title_type.py | ||
---|---|---|
1 |
from django.db import migrations |
|
2 | ||
3 | ||
4 |
def update_title_type(apps, schema_editor): |
|
5 |
WcsCardInfosCell = apps.get_model('wcs', 'WcsCardInfosCell') |
|
6 |
for cell in WcsCardInfosCell.objects.exclude(custom_title=''): |
|
7 |
cell.title_type = 'manual' |
|
8 |
cell.save() |
|
9 | ||
10 | ||
11 |
class Migration(migrations.Migration): |
|
12 | ||
13 |
dependencies = [ |
|
14 |
('wcs', '0037_card_title_type'), |
|
15 |
] |
|
16 | ||
17 |
operations = [ |
|
18 |
migrations.RunPython(update_title_type, migrations.RunPython.noop), |
|
19 |
] |
combo/apps/wcs/models.py | ||
---|---|---|
911 | 911 |
without_user = models.BooleanField(_('Ignore the logged-in user'), default=False) |
912 | 912 |
custom_schema = JSONField(blank=True, default=dict) |
913 | 913 | |
914 |
cached_title = models.CharField(_('Title'), max_length=150) |
|
914 |
title_type = models.CharField( |
|
915 |
_('Title'), |
|
916 |
max_length=20, |
|
917 |
default='auto', |
|
918 |
blank=False, |
|
919 |
choices=[ |
|
920 |
('auto', _('Default Title (Card Label)')), |
|
921 |
('manual', _('Custom Title')), |
|
922 |
('empty', _('No Title')), |
|
923 |
], |
|
924 |
) |
|
915 | 925 |
custom_title = models.CharField(_('Custom Title'), max_length=150, blank=True) |
926 | ||
927 |
cached_title = models.CharField(_('Title'), max_length=150) |
|
916 | 928 |
cached_json = JSONField(blank=True, default=dict) |
917 | 929 | |
918 | 930 |
is_enabled = classmethod(is_wcs_enabled) |
... | ... | |
982 | 994 |
extra_context = super().get_cell_extra_context(context) |
983 | 995 |
extra_context['schema'] = self.cached_json |
984 | 996 |
# default value used if card is not found |
985 |
extra_context['title'] = self.cached_title |
|
997 |
if self.title_type in ['auto', 'manual']: |
|
998 |
extra_context['title'] = self.cached_title |
|
986 | 999 | |
987 | 1000 |
card_id = self.get_card_id(context) |
988 | 1001 |
if not card_id: |
... | ... | |
1008 | 1021 | |
1009 | 1022 |
if response.status_code == 200: |
1010 | 1023 |
extra_context['card'] = response.json() |
1011 |
try: |
|
1012 |
extra_context['title'] = Template(self.custom_title).render(Context(extra_context)) |
|
1013 |
except (VariableDoesNotExist, TemplateSyntaxError): |
|
1014 |
extra_context['title'] = '' |
|
1015 |
# custom_title gives an empty title, use default value + card text |
|
1016 |
if not extra_context['title']: |
|
1024 |
if self.title_type == 'manual': |
|
1025 |
try: |
|
1026 |
extra_context['title'] = Template(self.custom_title).render(Context(extra_context)) |
|
1027 |
except (VariableDoesNotExist, TemplateSyntaxError): |
|
1028 |
extra_context['title'] = '' |
|
1029 |
# auto title or custom_title gives an empty title, use default value + card text |
|
1030 |
if self.title_type == 'auto' or self.title_type == 'manual' and not extra_context['title']: |
|
1017 | 1031 |
extra_context['title'] = '%s - %s' % (self.cached_title, extra_context['card'].get('text')) |
1018 | 1032 | |
1019 | 1033 |
return extra_context |
combo/apps/wcs/templates/combo/wcs/card.html | ||
---|---|---|
4 | 4 | |
5 | 5 |
<div class="card"> |
6 | 6 |
{% block cell-header %} |
7 |
<h2>{{ title }}</h2> |
|
7 |
{% if title %}<h2>{{ title }}</h2>{% endif %} |
|
8 | 8 |
{% include "combo/asset_picture_fragment.html" %} |
9 | 9 |
{% endblock %} |
10 | 10 |
combo/apps/wcs/templates/combo/wcs/manager/card-infos-cell-form.html | ||
---|---|---|
80 | 80 |
</script> |
81 | 81 | |
82 | 82 |
{% endif %} |
83 | ||
84 |
{# display/hide custom_title field #} |
|
85 |
<script> |
|
86 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-title_type').on('change', function() { |
|
87 |
if ($(this).val() == 'manual') { |
|
88 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-custom_title').parent().show(); |
|
89 |
} else { |
|
90 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-custom_title').parent().hide(); |
|
91 |
} |
|
92 |
}); |
|
93 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-title_type').change(); |
|
94 |
</script> |
|
83 | 95 |
{% endblock %} |
tests/test_wcs.py | ||
---|---|---|
1755 | 1755 |
page = Page.objects.create(title='xxx', template_name='standard') |
1756 | 1756 |
cell = WcsCardInfosCell(page=page, placeholder='content', order=0) |
1757 | 1757 |
cell.carddef_reference = 'default:card_model_1' |
1758 |
cell.title_type = 'manual' |
|
1758 | 1759 |
cell.custom_title = 'Foo bar {{ card.fields.title }}' |
1759 | 1760 |
cell.save() |
1760 | 1761 | |
... | ... | |
1786 | 1787 |
assert '<h2>Card Model 1</h2>' in result # default value |
1787 | 1788 |
assert '<p>Unknown Card</p>' in result |
1788 | 1789 | |
1789 |
cell.custom_title = '' |
|
1790 |
context.pop('title') |
|
1791 |
cell.title_type = 'auto' |
|
1790 | 1792 |
cell.save() |
1791 | 1793 |
mock_send.reset_mock() |
1792 | 1794 |
result = cell.render(context) |
1793 |
assert '<h2>Card Model 1 - aa</h2>' in result # custom_title not defined, default value
|
|
1795 |
assert '<h2>Card Model 1 - aa</h2>' in result |
|
1794 | 1796 |
assert PyQuery(result).find('span.label:contains("Field A") + span').text() == 'a' |
1795 | 1797 |
assert PyQuery(result).find('span.label:contains("Field B") + span').text() == 'yes' |
1796 | 1798 |
assert PyQuery(result).find('span.label:contains("Field C") + span').text() == 'Sept. 28, 2020' |
... | ... | |
1799 | 1801 |
assert 'related_structured' not in result |
1800 | 1802 |
assert 'Field D' not in result |
1801 | 1803 | |
1804 |
context.pop('title') |
|
1805 |
cell.title_type = 'manual' |
|
1802 | 1806 |
cell.custom_title = 'Foo bar {{ card.fields.fielda }}' |
1803 | 1807 |
cell.save() |
1804 | 1808 |
result = cell.render(context) |
1805 | 1809 |
assert '<h2>Foo bar a</h2>' in result |
1806 | 1810 | |
1811 |
context.pop('title') |
|
1807 | 1812 |
cell.custom_title = '{{ foobar }}' |
1808 | 1813 |
cell.save() |
1809 | 1814 |
result = cell.render(context) |
1810 | 1815 |
assert '<h2>Card Model 1 - aa</h2>' in result # empty value from template, default value |
1811 | 1816 | |
1817 |
context.pop('title') |
|
1812 | 1818 |
cell.custom_title = '{% if %}' |
1813 | 1819 |
cell.save() |
1814 | 1820 |
result = cell.render(context) |
1815 | 1821 |
assert '<h2>Card Model 1 - aa</h2>' in result # template error, default value |
1816 | 1822 | |
1823 |
context.pop('title') |
|
1824 |
cell.title_type = 'empty' |
|
1825 |
cell.save() |
|
1826 |
result = cell.render(context) |
|
1827 |
assert '<h2>' not in result |
|
1828 | ||
1817 | 1829 | |
1818 | 1830 |
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send) |
1819 | 1831 |
def test_card_cell_render_identifier(mock_send, context, nocache): |
1820 |
- |