Skip to content

Commit

Permalink
Merge afa75c8 into 6fe8ff3
Browse files Browse the repository at this point in the history
  • Loading branch information
yakky committed Apr 29, 2017
2 parents 6fe8ff3 + afa75c8 commit 1fd4300
Show file tree
Hide file tree
Showing 20 changed files with 390 additions and 133 deletions.
59 changes: 47 additions & 12 deletions .travis.yml
@@ -1,6 +1,7 @@
language: python

python:
- 3.6
- 3.5
- 3.4
- 3.3
Expand Down Expand Up @@ -32,10 +33,16 @@ env:
matrix:
- FRONTEND=1 UNIT=1
- FRONTEND=1 LINT=1
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- TEST_DOCS=1 DJANGO=1.10 DATABASE_URL='sqlite://localhost/:memory:' MIGRATE_OPTION='--migrate'
- DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:' MIGRATE_OPTION='--migrate'
- DJANGO=1.11 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' MIGRATE_OPTION='--migrate'
- DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'
- DJANGO=1.10 DATABASE_URL='sqlite://localhost/:memory:' MIGRATE_OPTION='--migrate'
- DJANGO=1.10 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- DJANGO=1.10 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' MIGRATE_OPTION='--migrate'
- DJANGO=1.10 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
Expand Down Expand Up @@ -93,8 +100,21 @@ notifications:
matrix:
exclude:

- python: 3.3
env: DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:' MIGRATE_OPTION='--migrate'
- python: 3.3
env: DJANGO=1.11 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.3
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' MIGRATE_OPTION='--migrate'
- python: 3.3
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.3
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'

- python: 3.3
env: TEST_DOCS=1 DJANGO=1.10 DATABASE_URL='sqlite://localhost/:memory:' MIGRATE_OPTION='--migrate'
- python: 3.3
env: DJANGO=1.10 DATABASE_URL='sqlite://localhost/:memory:' MIGRATE_OPTION='--migrate'
- python: 3.3
env: DJANGO=1.10 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.3
Expand Down Expand Up @@ -136,27 +156,37 @@ matrix:
env: FRONTEND=1 UNIT=1
- python: 3.5
env: FRONTEND=1 LINT=1
- python: 3.6
env: FRONTEND=1 UNIT=1
- python: 3.6
env: FRONTEND=1 LINT=1

- python: 3.3
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.4
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.5
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.6
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'

- python: 3.3
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.4
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.5
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.6
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'

- python: 3.3
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.4
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.5
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.8 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'
- python: 3.6
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite' MIGRATE_OPTION='--migrate'

allow_failures:

Expand All @@ -175,5 +205,10 @@ matrix:
- python: 3.5
env: DJANGO=1.9 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'

- python: 3.6
env: DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.6
env: DJANGO=1.9 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'

fast_finish: true

2 changes: 1 addition & 1 deletion cms/admin/forms.py
Expand Up @@ -234,7 +234,7 @@ class AdvancedSettingsForm(forms.ModelForm):
# This is really a 'fake' field which does not correspond to any Page attribute
# But creates a stub field to be populate by js
application_configs = forms.ChoiceField(label=_('Application configurations'),
choices=(), required=False,)
choices=(), required=False, widget=ApplicationConfigSelect)
fieldsets = (
(None, {
'fields': ('overwrite_url', 'redirect'),
Expand Down
187 changes: 118 additions & 69 deletions cms/forms/widgets.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-

from cms.utils.compat import DJANGO_1_10
from django.contrib.admin.templatetags.admin_static import static
from django.contrib.auth import get_permission_codename
from django.contrib.sites.models import Site
Expand All @@ -19,6 +19,7 @@ class PageSelectWidget(MultiWidget):
"""A widget that allows selecting a page by first selecting a site and then
a page on that site in a two step process.
"""
template_name = 'cms/widgets/pageselectwidget.html'

class Media:
js = (
Expand Down Expand Up @@ -67,13 +68,7 @@ def _has_changed(self, initial, data):
return True
return False

def render(self, name, value, attrs=None):
# THIS IS A COPY OF django.forms.widgets.MultiWidget.render()
# (except for the last line)

# value is a list of values, each corresponding to a widget
# in self.widgets.

def _build_widgets(self):
site_choices = get_site_choices()
page_choices = get_page_choices()
self.site_choices = site_choices
Expand All @@ -83,37 +78,58 @@ def render(self, name, value, attrs=None):
Select(choices=self.choices, attrs={'style': "display:none;"} ),
)

if not isinstance(value, list):
value = self.decompress(value)
output = []
final_attrs = self.build_attrs(attrs)
id_ = final_attrs.get('id', None)
for i, widget in enumerate(self.widgets):
try:
widget_value = value[i]
except IndexError:
widget_value = None
if id_:
final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
output.append(r'''<script type="text/javascript">
var CMS = window.CMS || {};
CMS.Widgets = CMS.Widgets || {};
CMS.Widgets._pageSelectWidgets = CMS.Widgets._pageSelectWidgets || [];
CMS.Widgets._pageSelectWidgets.push({
name: '%(name)s'
});
</script>''' % {
'name': name
})
return mark_safe(self.format_output(output))
def _build_script(self, name, value, attrs):
return r"""<script type="text/javascript">
var CMS = window.CMS || {};
CMS.Widgets = CMS.Widgets || {};
CMS.Widgets._pageSelectWidgets = CMS.Widgets._pageSelectWidgets || [];
CMS.Widgets._pageSelectWidgets.push({
name: '%(name)s'
});
</script>""" % {
'name': name
}

def get_context(self, name, value, attrs):
self._build_widgets()
context = super(PageSelectWidget, self).get_context(name, value, attrs)
context['widget']['script_init'] = self._build_script(name, value, context['widget']['attrs'])
return context

def render(self, name, value, attrs=None, renderer=None):
if DJANGO_1_10:
# THIS IS A COPY OF django.forms.widgets.MultiWidget.render()
# (except for the last line)

# value is a list of values, each corresponding to a widget
# in self.widgets.
self._build_widgets()

if not isinstance(value, list):
value = self.decompress(value)
output = []
final_attrs = self.build_attrs(attrs)
id_ = final_attrs.get('id', None)
for i, widget in enumerate(self.widgets):
try:
widget_value = value[i]
except IndexError:
widget_value = None
if id_:
final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
output.append(self._build_script(name, final_attrs))
return mark_safe(self.format_output(output))
else:
return super(PageSelectWidget, self).render(name, value, attrs, renderer)

def format_output(self, rendered_widgets):
return u' '.join(rendered_widgets)


class PageSmartLinkWidget(TextInput):
template_name = 'cms/widgets/pagesmartlinkwidget.html'

class Media:
css = {
Expand All @@ -138,11 +154,8 @@ def get_ajax_url(self, ajax_view):
'You should provide an ajax_view argument that can be reversed to the PageSmartLinkWidget'
)

def render(self, name=None, value=None, attrs=None):
final_attrs = self.build_attrs(attrs)
id_ = final_attrs.get('id', None)

output = [r'''<script type="text/javascript">
def _build_script(self, name, value, attrs):
return r"""<script type="text/javascript">
var CMS = window.CMS || {};
CMS.Widgets = CMS.Widgets || {};
Expand All @@ -153,15 +166,26 @@ def render(self, name=None, value=None, attrs=None):
lang: '%(language_code)s',
url: '%(ajax_url)s'
});
</script>''' % {
'element_id': id_,
'placeholder_text': final_attrs.get('placeholder_text', ''),
</script>""" % {
'element_id': attrs.get('id', ''),
'placeholder_text': attrs.get('placeholder_text', ''),
'language_code': self.language,
'ajax_url': force_text(self.ajax_url)
}]
}

output.append(super(PageSmartLinkWidget, self).render(name, value, attrs))
return mark_safe(u''.join(output))
def get_context(self, name, value, attrs):
context = super(PageSmartLinkWidget, self).get_context(name, value, attrs)
context['widget']['script_init'] = self._build_script(name, value, context['widget']['attrs'])
return context

def render(self, name, value, attrs=None, renderer=None):
if DJANGO_1_10:
final_attrs = self.build_attrs(attrs)
output = list(self._build_script(name, final_attrs))
output.append(super(PageSmartLinkWidget, self).render(name, value, attrs))
return mark_safe(u''.join(output))
else:
return super(PageSmartLinkWidget, self).render(name, value, attrs, renderer)


class UserSelectAdminWidget(Select):
Expand Down Expand Up @@ -199,7 +223,13 @@ def __init__(self, attrs=None, choices=(), app_namespaces={}):
self.app_namespaces = app_namespaces
super(AppHookSelect, self).__init__(attrs, choices)

def render_option(self, selected_choices, option_value, option_label):
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
option = super(AppHookSelect, self).create_option(name, value, label, selected, index, subindex, attrs)
if value in self.app_namespaces:
option['attrs']['data-namespace'] = escape(self.app_namespaces[value])
return option

def _build_option(self, selected_choices, option_value, option_label):
if option_value is None:
option_value = ''
option_value = force_text(option_value)
Expand All @@ -215,13 +245,11 @@ def render_option(self, selected_choices, option_value, option_label):
data_html = mark_safe(' data-namespace="%s"' % escape(self.app_namespaces[option_value]))
else:
data_html = ''
return option_value, selected_html, data_html, force_text(option_label)

return '<option value="%s"%s%s>%s</option>' % (
option_value,
selected_html,
data_html,
force_text(option_label),
)
def render_option(self, selected_choices, option_value, option_label):
option_data = self._build_option(selected_choices, option_value, option_label)
return '<option value="%s"%s%s>%s</option>' % option_data


class ApplicationConfigSelect(Select):
Expand All @@ -235,6 +263,7 @@ class ApplicationConfigSelect(Select):
A stub 'add-another' link is created and filled in with the correct URL by the same
javascript.
"""
template_name = 'cms/widgets/applicationconfigselect.html'

class Media:
js = (
Expand All @@ -245,23 +274,43 @@ def __init__(self, attrs=None, choices=(), app_configs={}):
self.app_configs = app_configs
super(ApplicationConfigSelect, self).__init__(attrs, choices)

def render(self, name, value, attrs=None, choices=()):
output = list(super(ApplicationConfigSelect, self).render(name, value, attrs))
output.append('<script>\n')
output.append('var apphooks_configuration = {\n')
def _build_script(self, name, value, attrs):
configs = []
urls = []
for application, cms_app in self.app_configs.items():
output.append("'%s': [%s]," % (application, ",".join(["['%s', '%s']" % (config.pk, escapejs(escape(config))) for config in cms_app.get_configs()]))) # noqa
output.append('\n};\n')
output.append('var apphooks_configuration_url = {\n')
configs.append("'%s': [%s]" % (application, ",".join(
["['%s', '%s']" % (config.pk, escapejs(escape(config))) for config in cms_app.get_configs()]))) # noqa
for application, cms_app in self.app_configs.items():
output.append("'%s': '%s'," % (application, cms_app.get_config_add_url()))
output.append('\n};\n')
output.append('var apphooks_configuration_value = \'%s\';\n' % value)
output.append('</script>')

related_url = ''
output.append('<a href="%s" class="add-another" id="add_%s" onclick="return showAddAnotherPopup(this);"> '
% (related_url, name))
output.append('<img src="%s" width="10" height="10" alt="%s"/></a>'
% (static('admin/img/icon_addlink.gif'), _('Add Another')))
return mark_safe(''.join(output))
urls.append("'%s': '%s'" % (application, cms_app.get_config_add_url()))
return r"""<script type="text/javascript">
var apphooks_configuration = {
%(apphooks_configurations)s
};
var apphooks_configuration_url = {
%(apphooks_url)s
};
var apphooks_configuration_value = '%(apphooks_value)s';
</script>""" % {
'apphooks_configurations': ','.join(configs),
'apphooks_url': ','.join(urls),
'apphooks_value': value,
}

def get_context(self, name, value, attrs):
context = super(ApplicationConfigSelect, self).get_context(name, value, attrs)
context['widget']['script_init'] = self._build_script(name, value, context['widget']['attrs'])
return context

def render(self, name, value, attrs=None, renderer=None):
if DJANGO_1_10:
output = list(super(ApplicationConfigSelect, self).render(name, value, attrs))
output.append(self._build_script(name, value, attrs))

related_url = ''
output.append('<a href="%s" class="add-another" id="add_%s" onclick="return showAddAnotherPopup(this);"> '
% (related_url, name))
output.append('<img src="%s" width="10" height="10" alt="%s"/></a>'
% (static('admin/img/icon_addlink.gif'), _('Add Another')))
return mark_safe(''.join(output))
else:
return super(ApplicationConfigSelect, self).render(name, value, attrs, renderer)
7 changes: 7 additions & 0 deletions cms/templates/cms/widgets/applicationconfigselect.html
@@ -0,0 +1,7 @@
{% load i18n static %}
{% include 'django/forms/widgets/select.html' %}
{{ widget.script_init|safe }}
<a href="" class="add-another" id="add_{{ widget.name }}" onclick="return showAddAnotherPopup(this);"
><img src="{% static 'admin/img/icon_addlink.gif' %}" width="10" height="10" alt="{% trans 'Add Another' %}"
/></a>

2 changes: 2 additions & 0 deletions cms/templates/cms/widgets/pageselectwidget.html
@@ -0,0 +1,2 @@
{% include 'django/forms/widgets/multiwidget.html' %}
{{ widget.script_init|safe }}
2 changes: 2 additions & 0 deletions cms/templates/cms/widgets/pagesmartlinkwidget.html
@@ -0,0 +1,2 @@
{% include 'django/forms/widgets/text.html' %}
{{ widget.script_init|safe }}

0 comments on commit 1fd4300

Please sign in to comment.