0001-misc-allow-template-URLs-in-feed-and-json-cells-1542.patch
combo/data/fields.py | ||
---|---|---|
18 | 18 | |
19 | 19 |
from django import forms |
20 | 20 |
from django.conf import settings |
21 |
from django.core import validators |
|
22 |
from django.forms.widgets import TextInput |
|
23 |
from django.utils.encoding import force_text |
|
21 | 24 | |
22 | 25 |
import ckeditor.fields |
23 | 26 | |
... | ... | |
48 | 51 |
value = value.replace(u' !', u'\u202f!') |
49 | 52 |
value = value.replace(u' ?', u'\u202f?') |
50 | 53 |
return value |
54 | ||
55 | ||
56 |
def templatable_url_validator(value): |
|
57 |
value = force_text(value) |
|
58 |
if '{{' in value or '{%' in value: |
|
59 |
# leave templates alone |
|
60 |
return |
|
61 |
validators.URLValidator()(value) |
|
62 | ||
63 | ||
64 |
class TemplatableURLField(forms.URLField): |
|
65 |
widget = TextInput |
|
66 |
default_validators = [templatable_url_validator] |
|
67 | ||
68 |
def to_python(self, value): |
|
69 |
value = super(forms.CharField, self).to_python(value) |
|
70 |
if '{{' in value or '{%' in value: |
|
71 |
return value |
|
72 |
return super(forms.URLField, self).to_python(value) |
combo/data/migrations/0037_auto_20190701_2118.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# Generated by Django 1.11.12 on 2019-07-01 19:18 |
|
3 |
from __future__ import unicode_literals |
|
4 | ||
5 |
from django.db import migrations, models |
|
6 | ||
7 | ||
8 |
class Migration(migrations.Migration): |
|
9 | ||
10 |
dependencies = [ |
|
11 |
('data', '0036_page_sub_slug'), |
|
12 |
] |
|
13 | ||
14 |
operations = [ |
|
15 |
migrations.AlterField( |
|
16 |
model_name='feedcell', |
|
17 |
name='url', |
|
18 |
field=models.CharField(blank=True, max_length=200, verbose_name='URL'), |
|
19 |
), |
|
20 |
migrations.AlterField( |
|
21 |
model_name='jsoncell', |
|
22 |
name='url', |
|
23 |
field=models.CharField(blank=True, max_length=200, verbose_name='URL'), |
|
24 |
), |
|
25 |
] |
combo/data/models.py | ||
---|---|---|
50 | 50 |
from django.template import Context, engines, TemplateDoesNotExist |
51 | 51 |
from django.test.client import RequestFactory |
52 | 52 | |
53 |
from .fields import RichTextField |
|
53 |
from .fields import RichTextField, TemplatableURLField
|
|
54 | 54 | |
55 | 55 |
from jsonfield import JSONField |
56 | 56 | |
... | ... | |
505 | 505 |
last_update_timestamp = models.DateTimeField(auto_now=True) |
506 | 506 | |
507 | 507 |
default_form_class = None |
508 |
manager_form_factory_kwargs = {} |
|
509 |
manager_form_template = 'combo/cell_form.html' |
|
510 | ||
508 | 511 |
visible = True |
509 | 512 |
user_dependant = False |
510 |
manager_form_template = 'combo/cell_form.html' |
|
511 | 513 |
template_name = None |
512 | 514 | |
513 | 515 |
# get_badge(self, context); set to None so cell types can be skipped easily |
... | ... | |
658 | 660 |
if not fields: |
659 | 661 |
return None |
660 | 662 | |
661 |
return model_forms.modelform_factory(self.__class__, fields=fields) |
|
663 |
return model_forms.modelform_factory(self.__class__, fields=fields, **self.manager_form_factory_kwargs)
|
|
662 | 664 | |
663 | 665 |
def get_options_form_class(self): |
664 | 666 |
return model_forms.modelform_factory(self.__class__, |
... | ... | |
907 | 909 |
@register_cell_class |
908 | 910 |
class FeedCell(CellBase): |
909 | 911 |
title = models.CharField(_('Title'), max_length=150, blank=True) |
910 |
url = models.URLField(_('URL'), blank=True)
|
|
912 |
url = models.CharField(_('URL'), blank=True, max_length=200)
|
|
911 | 913 |
limit = models.PositiveSmallIntegerField(_('Maximum number of entries'), |
912 | 914 |
null=True, blank=True) |
913 | 915 | |
916 |
manager_form_factory_kwargs = {'field_classes': {'url': TemplatableURLField}} |
|
914 | 917 |
template_name = 'combo/feed-cell.html' |
915 | 918 | |
916 | 919 |
class Meta: |
... | ... | |
1275 | 1278 |
@register_cell_class |
1276 | 1279 |
class JsonCell(JsonCellBase): |
1277 | 1280 |
title = models.CharField(_('Title'), max_length=150, blank=True) |
1278 |
url = models.URLField(_('URL'), blank=True)
|
|
1281 |
url = models.CharField(_('URL'), blank=True, max_length=200)
|
|
1279 | 1282 |
template_string = models.TextField(_('Display Template'), blank=True, null=True) |
1280 | 1283 |
cache_duration = models.PositiveIntegerField( |
1281 | 1284 |
_('Cache duration'), default=60) |
... | ... | |
1287 | 1290 |
timeout = models.PositiveIntegerField(_('Request timeout'), default=0, |
1288 | 1291 |
help_text=_('In seconds. Use 0 for default system timeout')) |
1289 | 1292 | |
1293 |
manager_form_factory_kwargs = {'field_classes': {'url': TemplatableURLField}} |
|
1294 | ||
1290 | 1295 |
class Meta: |
1291 | 1296 |
verbose_name = _('JSON Prototype') |
1292 | 1297 |
tests/test_manager.py | ||
---|---|---|
586 | 586 |
assert TextCell.objects.get(id=cells[0].id).text == u'Hello\u00a0: World' |
587 | 587 | |
588 | 588 | |
589 |
def test_edit_json_cell(app, admin_user): |
|
590 |
Page.objects.all().delete() |
|
591 |
page = Page(title='One', slug='one', template_name='standard') |
|
592 |
page.save() |
|
593 | ||
594 |
app = login(app) |
|
595 |
resp = app.get('/manage/pages/%s/' % page.id) |
|
596 |
data_add_url = [x for x in resp.html.find_all('option') if x.text == 'JSON Prototype'][0].get('data-add-url') |
|
597 |
resp = app.get(data_add_url) |
|
598 | ||
599 |
cells = CellBase.get_cells(page_id=page.id) |
|
600 |
assert len(cells) == 1 |
|
601 |
assert isinstance(cells[0], JsonCell) |
|
602 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.id, cells[0].get_reference())) |
|
603 | ||
604 |
resp = app.get('/manage/pages/%s/' % page.id) |
|
605 |
resp.form['cdata_jsoncell-%s-url' % cells[0].id].value = 'xxx' |
|
606 |
resp = resp.form.submit() |
|
607 |
assert JsonCell.objects.get(id=cells[0].id).url == '' |
|
608 | ||
609 |
resp = app.get('/manage/pages/%s/' % page.id) |
|
610 |
resp.form['cdata_jsoncell-%s-url' % cells[0].id].value = 'https://www.example.net/' |
|
611 |
resp = resp.form.submit() |
|
612 |
assert JsonCell.objects.get(id=cells[0].id).url == 'https://www.example.net/' |
|
613 | ||
614 |
resp = app.get('/manage/pages/%s/' % page.id) |
|
615 |
resp.form['cdata_jsoncell-%s-url' % cells[0].id].value = '{{url}}' |
|
616 |
resp = resp.form.submit() |
|
617 |
assert JsonCell.objects.get(id=cells[0].id).url == '{{url}}' |
|
618 | ||
619 | ||
589 | 620 |
def test_edit_config_json_cell(app, admin_user): |
590 | 621 |
Page.objects.all().delete() |
591 | 622 |
page = Page(title='One', slug='one', template_name='standard') |
592 |
- |