misc: allow template URLs in feed and json cells (#15423)
This commit is contained in:
parent
c6b4b5b6bd
commit
a72c25dd59
|
@ -18,6 +18,9 @@
|
|||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core import validators
|
||||
from django.forms.widgets import TextInput
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
import ckeditor.fields
|
||||
|
||||
|
@ -48,3 +51,22 @@ class RichTextFormField(ckeditor.fields.RichTextFormField):
|
|||
value = value.replace(u' !', u'\u202f!')
|
||||
value = value.replace(u' ?', u'\u202f?')
|
||||
return value
|
||||
|
||||
|
||||
def templatable_url_validator(value):
|
||||
value = force_text(value)
|
||||
if '{{' in value or '{%' in value:
|
||||
# leave templates alone
|
||||
return
|
||||
validators.URLValidator()(value)
|
||||
|
||||
|
||||
class TemplatableURLField(forms.URLField):
|
||||
widget = TextInput
|
||||
default_validators = [templatable_url_validator]
|
||||
|
||||
def to_python(self, value):
|
||||
value = super(forms.URLField, self).to_python(value)
|
||||
if '{{' in value or '{%' in value:
|
||||
return value
|
||||
return super(TemplatableURLField, self).to_python(value)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2019-07-01 19:18
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('data', '0036_page_sub_slug'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='feedcell',
|
||||
name='url',
|
||||
field=models.CharField(blank=True, max_length=200, verbose_name='URL'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='jsoncell',
|
||||
name='url',
|
||||
field=models.CharField(blank=True, max_length=200, verbose_name='URL'),
|
||||
),
|
||||
]
|
|
@ -50,7 +50,7 @@ from django.forms.widgets import MediaDefiningClass
|
|||
from django.template import Context, engines, TemplateDoesNotExist
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from .fields import RichTextField
|
||||
from .fields import RichTextField, TemplatableURLField
|
||||
|
||||
from jsonfield import JSONField
|
||||
|
||||
|
@ -505,9 +505,11 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
|
|||
last_update_timestamp = models.DateTimeField(auto_now=True)
|
||||
|
||||
default_form_class = None
|
||||
manager_form_factory_kwargs = {}
|
||||
manager_form_template = 'combo/cell_form.html'
|
||||
|
||||
visible = True
|
||||
user_dependant = False
|
||||
manager_form_template = 'combo/cell_form.html'
|
||||
template_name = None
|
||||
|
||||
# get_badge(self, context); set to None so cell types can be skipped easily
|
||||
|
@ -658,7 +660,7 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
|
|||
if not fields:
|
||||
return None
|
||||
|
||||
return model_forms.modelform_factory(self.__class__, fields=fields)
|
||||
return model_forms.modelform_factory(self.__class__, fields=fields, **self.manager_form_factory_kwargs)
|
||||
|
||||
def get_options_form_class(self):
|
||||
return model_forms.modelform_factory(self.__class__,
|
||||
|
@ -907,10 +909,11 @@ class LinkCell(CellBase):
|
|||
@register_cell_class
|
||||
class FeedCell(CellBase):
|
||||
title = models.CharField(_('Title'), max_length=150, blank=True)
|
||||
url = models.URLField(_('URL'), blank=True)
|
||||
url = models.CharField(_('URL'), blank=True, max_length=200)
|
||||
limit = models.PositiveSmallIntegerField(_('Maximum number of entries'),
|
||||
null=True, blank=True)
|
||||
|
||||
manager_form_factory_kwargs = {'field_classes': {'url': TemplatableURLField}}
|
||||
template_name = 'combo/feed-cell.html'
|
||||
|
||||
class Meta:
|
||||
|
@ -1275,7 +1278,7 @@ class JsonCellBase(CellBase):
|
|||
@register_cell_class
|
||||
class JsonCell(JsonCellBase):
|
||||
title = models.CharField(_('Title'), max_length=150, blank=True)
|
||||
url = models.URLField(_('URL'), blank=True)
|
||||
url = models.CharField(_('URL'), blank=True, max_length=200)
|
||||
template_string = models.TextField(_('Display Template'), blank=True, null=True)
|
||||
cache_duration = models.PositiveIntegerField(
|
||||
_('Cache duration'), default=60)
|
||||
|
@ -1287,6 +1290,8 @@ class JsonCell(JsonCellBase):
|
|||
timeout = models.PositiveIntegerField(_('Request timeout'), default=0,
|
||||
help_text=_('In seconds. Use 0 for default system timeout'))
|
||||
|
||||
manager_form_factory_kwargs = {'field_classes': {'url': TemplatableURLField}}
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('JSON Prototype')
|
||||
|
||||
|
|
|
@ -586,6 +586,38 @@ def test_edit_text_cell(app, admin_user):
|
|||
assert TextCell.objects.get(id=cells[0].id).text == u'Hello\u00a0: World'
|
||||
|
||||
|
||||
def test_edit_json_cell(app, admin_user):
|
||||
Page.objects.all().delete()
|
||||
page = Page(title='One', slug='one', template_name='standard')
|
||||
page.save()
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/pages/%s/' % page.id)
|
||||
data_add_url = [x for x in resp.html.find_all('option') if x.text == 'JSON Prototype'][0].get('data-add-url')
|
||||
resp = app.get(data_add_url)
|
||||
|
||||
cells = CellBase.get_cells(page_id=page.id)
|
||||
assert len(cells) == 1
|
||||
assert isinstance(cells[0], JsonCell)
|
||||
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.id, cells[0].get_reference()))
|
||||
|
||||
resp = app.get('/manage/pages/%s/' % page.id)
|
||||
resp.form['cdata_jsoncell-%s-url' % cells[0].id].value = 'xxx'
|
||||
resp = resp.form.submit()
|
||||
assert 'Enter a valid URL.' in resp.text
|
||||
assert JsonCell.objects.get(id=cells[0].id).url == ''
|
||||
|
||||
resp = app.get('/manage/pages/%s/' % page.id)
|
||||
resp.form['cdata_jsoncell-%s-url' % cells[0].id].value = 'https://www.example.net/'
|
||||
resp = resp.form.submit()
|
||||
assert JsonCell.objects.get(id=cells[0].id).url == 'https://www.example.net/'
|
||||
|
||||
resp = app.get('/manage/pages/%s/' % page.id)
|
||||
resp.form['cdata_jsoncell-%s-url' % cells[0].id].value = '{{url}}'
|
||||
resp = resp.form.submit()
|
||||
assert JsonCell.objects.get(id=cells[0].id).url == '{{url}}'
|
||||
|
||||
|
||||
def test_edit_config_json_cell(app, admin_user):
|
||||
Page.objects.all().delete()
|
||||
page = Page(title='One', slug='one', template_name='standard')
|
||||
|
|
Loading…
Reference in New Issue