cells: json cell params (repeat, make_global, template_string) (#54236)
This commit is contained in:
parent
6b2b381a54
commit
07a81ad81d
|
@ -1671,6 +1671,7 @@ class JsonCellBase(CellBase):
|
|||
force_async = False
|
||||
log_errors = True
|
||||
timeout = None
|
||||
make_global = False
|
||||
actions = {}
|
||||
additional_data = None
|
||||
# [
|
||||
|
@ -1827,6 +1828,16 @@ class JsonCellBase(CellBase):
|
|||
|
||||
return extra_context
|
||||
|
||||
def modify_global_context(self, context, request):
|
||||
if self.make_global:
|
||||
synchronous = context.get('synchronous')
|
||||
context['synchronous'] = True
|
||||
try:
|
||||
preloaded_data = self.get_cell_extra_context(context)
|
||||
context[self.make_global] = preloaded_data.get(self.first_data_key)
|
||||
finally:
|
||||
context['synchronous'] = synchronous
|
||||
|
||||
@property
|
||||
def template_name(self):
|
||||
json_content = self._json_content
|
||||
|
@ -1979,6 +1990,14 @@ class ConfigJsonCell(JsonCellBase):
|
|||
def ajax_refresh(self):
|
||||
return settings.JSON_CELL_TYPES[self.key].get('auto_refresh', None)
|
||||
|
||||
@property
|
||||
def make_global(self):
|
||||
return settings.JSON_CELL_TYPES[self.key].get('make_global', False)
|
||||
|
||||
@property
|
||||
def repeat(self):
|
||||
return settings.JSON_CELL_TYPES[self.key].get('repeat')
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
return settings.JSON_CELL_TYPES[self.key]['url']
|
||||
|
@ -2035,6 +2054,11 @@ class ConfigJsonCell(JsonCellBase):
|
|||
context['parameters'] = self.parameters
|
||||
return context
|
||||
|
||||
def render(self, context):
|
||||
if 'template_string' in self.parameters:
|
||||
self.template_string = self.parameters['template_string']
|
||||
return super().render(context)
|
||||
|
||||
|
||||
@receiver(pre_save, sender=Page)
|
||||
def create_redirects(sender, instance, raw, **kwargs):
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
data-ajax-cell-loading-message="{{ cell.loading_message }}"
|
||||
data-ajax-cell-error-message="{% trans "Loading error" %}"
|
||||
{% if cell.ajax_refresh %}data-ajax-cell-refresh="{{ cell.ajax_refresh }}"{% endif %}
|
||||
{% if request.extra_context_data %}data-extra-context="{{ request.extra_context_data|signed|urlencode }}"{% endif %}
|
||||
{% with cell|extra_context:request as extra_context %}
|
||||
{% if extra_context %}data-extra-context="{{ extra_context|signed|urlencode }}"{% endif %}
|
||||
{% endwith %}
|
||||
><div>{% render_cell cell %}</div></div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
import json
|
||||
import math
|
||||
|
@ -39,7 +40,7 @@ try:
|
|||
except ImportError:
|
||||
from django.template.base import TOKEN_BLOCK, TOKEN_VAR, TOKEN_COMMENT
|
||||
|
||||
from django.template import defaultfilters
|
||||
from django.template import Template, TemplateSyntaxError, defaultfilters
|
||||
from django.template.defaultfilters import stringfilter
|
||||
from django.utils import dateparse, six
|
||||
from django.utils.encoding import force_text
|
||||
|
@ -107,6 +108,28 @@ def placeholder(context, placeholder_name, **options):
|
|||
context['skeleton'] = skeleton_text(context, placeholder_name)
|
||||
else:
|
||||
context['skeleton'] = ''
|
||||
|
||||
if not context.get('placeholder_search_mode'):
|
||||
for cell in [x for x in context['cells'] if hasattr(x, 'repeat')]:
|
||||
repeat_template = cell.repeat
|
||||
if not repeat_template:
|
||||
continue
|
||||
|
||||
try:
|
||||
repeat = int(Template(repeat_template).render(context))
|
||||
except (ValueError, TemplateSyntaxError, VariableDoesNotExist):
|
||||
continue
|
||||
cell_idx = context['cells'].index(cell)
|
||||
context['cells'].remove(cell)
|
||||
if repeat == 0:
|
||||
continue
|
||||
repeated_cells = []
|
||||
for i in range(repeat):
|
||||
new_cell = copy.copy(cell)
|
||||
new_cell.repeat_index = i
|
||||
repeated_cells.append(new_cell)
|
||||
context['cells'][cell_idx:cell_idx] = repeated_cells
|
||||
|
||||
return context
|
||||
|
||||
|
||||
|
@ -311,7 +334,10 @@ def get(obj, key):
|
|||
try:
|
||||
return obj.get(key)
|
||||
except AttributeError:
|
||||
return None
|
||||
try:
|
||||
return obj[key]
|
||||
except (IndexError, KeyError, TypeError):
|
||||
return None
|
||||
|
||||
|
||||
@register.filter
|
||||
|
@ -672,3 +698,11 @@ def phonenumber_fr(value, separator=' '):
|
|||
|
||||
# unknown
|
||||
return value
|
||||
|
||||
|
||||
@register.filter
|
||||
def extra_context(cell, request):
|
||||
ctx = copy.copy(getattr(request, 'extra_context_data', {}) or {})
|
||||
if hasattr(cell, 'repeat_index'):
|
||||
ctx['repeat_index'] = cell.repeat_index
|
||||
return ctx
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import datetime
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
@ -794,6 +795,151 @@ def test_config_json_cell_with_param_in_url(app):
|
|||
assert requests_get.call_args[-1]['timeout'] == 42
|
||||
|
||||
|
||||
def test_config_json_cell_with_template_string(settings, context):
|
||||
settings.JSON_CELL_TYPES = {
|
||||
'test-config-json-cell': {
|
||||
'name': 'Foobar',
|
||||
'url': 'http://foo',
|
||||
'form': [
|
||||
{"varname": "identifier", "type": "string", "label": "Identifier"},
|
||||
{"varname": "template_string", "type": "text", "label": "Template"},
|
||||
],
|
||||
},
|
||||
}
|
||||
page = Page.objects.create(title='example page', slug='example-page')
|
||||
cell = ConfigJsonCell.objects.create(
|
||||
page=page,
|
||||
placeholder='content',
|
||||
order=1,
|
||||
key='test-config-json-cell',
|
||||
parameters={'identifier': 'plop', 'template_string': 'Foo Bar {{ identifier }}'},
|
||||
)
|
||||
|
||||
with mock.patch('combo.utils.requests.get') as requests_get:
|
||||
data = {'data': []}
|
||||
requests_get.return_value = mock_json_response(content=json.dumps(data), status_code=200)
|
||||
assert cell.render({}) == 'Foo Bar plop'
|
||||
|
||||
|
||||
def test_config_json_cell_with_global(settings, app):
|
||||
settings.JSON_CELL_TYPES = {
|
||||
'test-config-json-cell': {
|
||||
'name': 'Foobar',
|
||||
'url': 'http://foo',
|
||||
'make_global': 'new_global_context',
|
||||
'form': [
|
||||
{"varname": "template_string", "type": "text", "label": "Template"},
|
||||
],
|
||||
},
|
||||
'test-config-json-cell-2': {
|
||||
'name': 'Foobar 2',
|
||||
'url': 'http://foo',
|
||||
'form': [
|
||||
{"varname": "template_string", "type": "text", "label": "Template"},
|
||||
],
|
||||
},
|
||||
}
|
||||
page = Page.objects.create(title='example page', slug='example-page')
|
||||
cell1 = ConfigJsonCell.objects.create(
|
||||
page=page,
|
||||
placeholder='content',
|
||||
order=1,
|
||||
key='test-config-json-cell',
|
||||
parameters={'template_string': 'Foo Bar'},
|
||||
)
|
||||
cell2 = ConfigJsonCell.objects.create(
|
||||
page=page,
|
||||
placeholder='content',
|
||||
order=2,
|
||||
key='test-config-json-cell-2',
|
||||
parameters={'template_string': 'Foo Bar'},
|
||||
)
|
||||
with mock.patch('combo.utils.requests.get') as requests_get:
|
||||
data = {'data': []}
|
||||
requests_get.return_value = mock_json_response(content=json.dumps(data), status_code=200)
|
||||
url = reverse(
|
||||
'combo-public-ajax-page-cell',
|
||||
kwargs={'page_pk': page.pk, 'cell_reference': cell1.get_reference()},
|
||||
)
|
||||
resp = app.get(url)
|
||||
assert resp.context['new_global_context'] == data
|
||||
url = reverse(
|
||||
'combo-public-ajax-page-cell',
|
||||
kwargs={'page_pk': page.pk, 'cell_reference': cell2.get_reference()},
|
||||
)
|
||||
resp = app.get(url)
|
||||
assert resp.context['new_global_context'] == data
|
||||
|
||||
|
||||
def test_config_json_cell_with_repeat(settings, app):
|
||||
settings.JSON_CELL_TYPES = {
|
||||
'test-config-json-cell': {
|
||||
'name': 'Foobar',
|
||||
'url': 'http://foo',
|
||||
'form': [
|
||||
{"varname": "template_string", "type": "text", "label": "Template"},
|
||||
],
|
||||
},
|
||||
'test-config-json-cell-2': {
|
||||
'name': 'Foobar 2',
|
||||
'url': 'http://foo',
|
||||
'repeat': '3',
|
||||
'form': [
|
||||
{"varname": "template_string", "type": "text", "label": "Template"},
|
||||
],
|
||||
},
|
||||
}
|
||||
page = Page.objects.create(title='example page', slug='example-page')
|
||||
cell1 = ConfigJsonCell.objects.create(
|
||||
page=page,
|
||||
placeholder='content',
|
||||
order=1,
|
||||
key='test-config-json-cell',
|
||||
parameters={'template_string': 'Foo Bar'},
|
||||
)
|
||||
cell2 = ConfigJsonCell.objects.create(
|
||||
page=page,
|
||||
placeholder='content',
|
||||
order=2,
|
||||
key='test-config-json-cell-2',
|
||||
parameters={'template_string': 'Foo Bar {{ repeat_index }}'},
|
||||
)
|
||||
|
||||
with mock.patch('combo.utils.requests.get') as requests_get:
|
||||
data = {'data': []}
|
||||
requests_get.return_value = mock_json_response(content=json.dumps(data), status_code=200)
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 4
|
||||
assert resp.context['cells'][0].pk == cell1.pk
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
cell_url = reverse(
|
||||
'combo-public-ajax-page-cell',
|
||||
kwargs={'page_pk': page.pk, 'cell_reference': cell2.get_reference()},
|
||||
)
|
||||
for i in range(0, 3):
|
||||
assert resp.context['cells'][i + 1].pk == cell2.pk
|
||||
assert resp.context['cells'][i + 1].repeat_index == i
|
||||
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[i + 1])
|
||||
assert cell_resp.context['repeat_index'] == i
|
||||
assert cell_resp.text == 'Foo Bar %s' % i
|
||||
|
||||
# repeat: not an int
|
||||
settings.JSON_CELL_TYPES['test-config-json-cell-2']['repeat'] = 'foo'
|
||||
with mock.patch('combo.utils.requests.get') as requests_get:
|
||||
data = {'data': []}
|
||||
requests_get.return_value = mock_json_response(content=json.dumps(data), status_code=200)
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 2
|
||||
|
||||
# repeat: template error
|
||||
settings.JSON_CELL_TYPES['test-config-json-cell-2']['repeat'] = '{% foo %}'
|
||||
with mock.patch('combo.utils.requests.get') as requests_get:
|
||||
data = {'data': []}
|
||||
requests_get.return_value = mock_json_response(content=json.dumps(data), status_code=200)
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 2
|
||||
|
||||
|
||||
def test_config_json_cell_validity(settings, context):
|
||||
settings.JSON_CELL_TYPES = {
|
||||
'test-config-json-cell': {
|
||||
|
|
Loading…
Reference in New Issue