Add site switcher to header in settings

pull/1754/head
Tim Heap 2015-10-21 16:31:13 +11:00
rodzic 72c81e8317
commit 5d81269548
8 zmienionych plików z 176 dodań i 35 usunięć

Wyświetl plik

@ -55,6 +55,7 @@ var apps = [
'wagtailstyleguide/scss/styleguide.scss'
],
}),
new App('wagtail/contrib/settings'),
];
module.exports = {

Wyświetl plik

@ -0,0 +1 @@
static/

Wyświetl plik

@ -0,0 +1,27 @@
from __future__ import absolute_import, unicode_literals
from django import forms
from django.core.urlresolvers import reverse
from wagtail.wagtailcore.models import Site
class SiteSwitchForm(forms.Form):
site = forms.ChoiceField(choices=[])
class Media:
js = [
'settings/js/site-switcher.js',
]
def __init__(self, current_site, model, **kwargs):
initial_data = {'site': self.get_change_url(current_site, model)}
super(SiteSwitchForm, self).__init__(initial=initial_data, **kwargs)
sites = [(self.get_change_url(site, model), site)
for site in Site.objects.all()]
self.fields['site'].choices = sites
@classmethod
def get_change_url(cls, site, model):
return reverse('wagtailsettings_edit', args=[
site.pk, model._meta.app_label, model._meta.model_name])

Wyświetl plik

@ -0,0 +1,12 @@
$(function() {
var $switcher = $('form#settings-site-switch select');
if (!$switcher.length) return;
var initial = $switcher.val();
$switcher.on('change', function() {
var url = $switcher.val();
if (url != initial) {
window.location = url;
}
});
});

Wyświetl plik

@ -3,10 +3,30 @@
{% block titletag %}{% blocktrans %}Editing {{ setting_type_name}} - {{ instance }}{% endblocktrans %}{% endblock %}
{% block bodyclass %}menu-settings{% endblock %}
{% block content %}
{% trans "Editing" as editing_str %}
{% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=setting_type_name|capfirst icon="cogs" %}
<header class="nice-padding">
<div class="row">
<div class="left">
<div class="col">
<h1 class="icon icon-cogs">
{% trans "Editing" %}
<span>{{ setting_type_name|capfirst }}</span>
</h1>
</div>
</div>
<div class="right">
{% if site_switcher %}
<form method="get" id="settings-site-switch">
<label for="{{ site_switcher.site.id_for_label }}">
Site:
</label>
{{ site_switcher.site }}
</form>
{% endif %}
</div>
</div>
</header>
<form action="{% url 'wagtailsettings_edit' opts.app_label opts.model_name %}" method="POST">
<form action="{% url 'wagtailsettings_edit' site.pk opts.app_label opts.model_name %}" method="POST">
{% csrf_token %}
{{ edit_handler.render_form_content }}
@ -23,7 +43,11 @@
{% block extra_css %}
{% include "wagtailadmin/pages/_editor_css.html" %}
{{ form.media.css }}
{{ site_switcher.media.css }}
{% endblock %}
{% block extra_js %}
{% include "wagtailadmin/pages/_editor_js.html" %}
{{ form.media.js }}
{{ site_switcher.media.js }}
{% endblock %}

Wyświetl plik

@ -1,3 +1,5 @@
from __future__ import absolute_import, unicode_literals
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.core.urlresolvers import reverse
@ -8,7 +10,7 @@ from wagtail.contrib.settings.registry import SettingMenuItem
from wagtail.tests.testapp.models import IconSetting, TestSetting
from wagtail.tests.utils import WagtailTestUtils
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.models import Site
from wagtail.wagtailcore.models import Page, Site
class TestSettingMenu(TestCase, WagtailTestUtils):
@ -42,20 +44,23 @@ class TestSettingMenu(TestCase, WagtailTestUtils):
self.assertEqual(classnames, {'icon', 'icon-tag', 'test-class'})
class TestSettingCreateView(TestCase, WagtailTestUtils):
class BaseTestSettingView(TestCase, WagtailTestUtils):
def get(self, site_pk=1, params={}):
url = self.edit_url('tests', 'testsetting', site_pk=site_pk)
return self.client.get(url, params)
def post(self, site_pk=1, post_data={}):
url = self.edit_url('tests', 'testsetting', site_pk=site_pk)
return self.client.post(url, post_data)
def edit_url(self, app, model, site_pk=1):
return reverse('wagtailsettings_edit', args=[site_pk, app, model])
class TestSettingCreateView(BaseTestSettingView):
def setUp(self):
self.login()
def get(self, params={}):
return self.client.get(
reverse('wagtailsettings_edit', args=('tests', 'testsetting')),
params)
def post(self, post_data={}):
return self.client.post(
reverse('wagtailsettings_edit', args=('tests', 'testsetting')),
post_data)
def test_status_code(self):
self.assertEqual(self.get().status_code, 200)
@ -75,7 +80,7 @@ class TestSettingCreateView(TestCase, WagtailTestUtils):
self.assertEqual(setting.email, 'test@example.com')
class TestSettingEditView(TestCase, WagtailTestUtils):
class TestSettingEditView(BaseTestSettingView):
def setUp(self):
default_site = Site.objects.get(is_default_site=True)
@ -87,22 +92,11 @@ class TestSettingEditView(TestCase, WagtailTestUtils):
self.login()
def get(self, params={}):
return self.client.get(
reverse('wagtailsettings_edit', args=('tests', 'testsetting')),
params)
def post(self, post_data={}):
return self.client.post(
reverse('wagtailsettings_edit', args=('tests', 'testsetting')),
post_data)
def test_status_code(self):
self.assertEqual(self.get().status_code, 200)
def test_non_existant_model(self):
response = self.client.get(
reverse('wagtailsettings_edit', args=('tests', 'foo')))
response = self.client.get(self.edit_url('test', 'foo'))
self.assertEqual(response.status_code, 404)
def test_edit_invalid(self):
@ -121,6 +115,74 @@ class TestSettingEditView(TestCase, WagtailTestUtils):
self.assertEqual(setting.email, 'test@example.com')
class TestMultiSite(BaseTestSettingView):
def setUp(self):
self.default_site = Site.objects.get(is_default_site=True)
self.other_site = Site.objects.create(hostname='example.com', root_page=Page.objects.get(pk=2))
self.login()
def test_redirect_to_default(self):
"""
Should redirect to the setting for the default site.
"""
start_url = reverse('wagtailsettings_edit', args=[
'tests', 'testsetting'])
dest_url = 'http://testserver' + reverse('wagtailsettings_edit', args=[
self.default_site.pk, 'tests', 'testsetting'])
response = self.client.get(start_url, follow=True)
self.assertEqual([(dest_url, 302)], response.redirect_chain)
def test_redirect_to_current(self):
"""
Should redirect to the setting for the current site taken from the URL,
by default
"""
start_url = reverse('wagtailsettings_edit', args=[
'tests', 'testsetting'])
dest_url = 'http://example.com' + reverse('wagtailsettings_edit', args=[
self.other_site.pk, 'tests', 'testsetting'])
response = self.client.get(start_url, follow=True, HTTP_HOST=self.other_site.hostname)
self.assertEqual([(dest_url, 302)], response.redirect_chain)
def test_switcher(self):
""" Check that the switcher form exists in the page """
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'id="settings-site-switch"')
def test_unknown_site(self):
""" Check that unknown sites throw a 404 """
response = self.get(site_pk=3)
self.assertEqual(response.status_code, 404)
def test_edit(self):
"""
Check that editing settings in multi-site mode edits the correct
setting, and leaves the other ones alone
"""
TestSetting.objects.create(
title='default',
email='default@example.com',
site=self.default_site)
TestSetting.objects.create(
title='other',
email='other@example.com',
site=self.other_site)
response = self.post(site_pk=self.other_site.pk, post_data={
'title': 'other-new', 'email': 'other-other@example.com'})
self.assertEqual(response.status_code, 302)
# Check that the correct setting was updated
other_setting = TestSetting.for_site(self.other_site)
self.assertEqual(other_setting.title, 'other-new')
self.assertEqual(other_setting.email, 'other-other@example.com')
# Check that the other setting was not updated
default_setting = TestSetting.for_site(self.default_site)
self.assertEqual(default_setting.title, 'default')
self.assertEqual(default_setting.email, 'default@example.com')
class TestAdminPermission(TestCase, WagtailTestUtils):
def test_registered_permission(self):
permission = Permission.objects.get_by_natural_key(

Wyświetl plik

@ -3,5 +3,6 @@ from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^(\w+)/(\w+)/$', views.edit, name='wagtailsettings_edit'),
url(r'^(\w+)/(\w+)/$', views.edit_current_site, name='wagtailsettings_edit'),
url(r'^(\d+)/(\w+)/(\w+)/$', views.edit, name='wagtailsettings_edit'),
]

Wyświetl plik

@ -1,7 +1,6 @@
from django.contrib.auth.decorators import permission_required
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.shortcuts import redirect, render
from django.shortcuts import redirect, render, get_object_or_404
from django.utils.lru_cache import lru_cache
from django.utils.text import capfirst
from django.utils.translation import ugettext as _
@ -9,7 +8,9 @@ from django.utils.translation import ugettext as _
from wagtail.wagtailadmin import messages
from wagtail.wagtailadmin.edit_handlers import (
ObjectList, extract_panel_definitions_from_model_class)
from wagtail.wagtailcore.models import Site
from .forms import SiteSwitchForm
from .permissions import user_can_edit_setting_type
from .registry import registry
@ -31,15 +32,20 @@ def get_setting_edit_handler(model):
return ObjectList(panels).bind_to_model(model)
@permission_required('wagtailadmin.access_admin') # further permissions are enforced within the view
def edit(request, app_name, model_name):
def edit_current_site(request, app_name, model_name):
# Redirect the user to the edit page for the current site
return redirect('wagtailsettings_edit', request.site.pk, app_name, model_name)
def edit(request, site_pk, app_name, model_name):
model = get_model_from_url_params(app_name, model_name)
if not user_can_edit_setting_type(request.user, model):
raise PermissionDenied
site = get_object_or_404(Site, pk=site_pk)
setting_type_name = model._meta.verbose_name
instance = model.for_site(request.site)
instance = model.for_site(site)
edit_handler_class = get_setting_edit_handler(model)
form_class = edit_handler_class.get_form_class(model)
@ -56,7 +62,7 @@ def edit(request, app_name, model_name):
instance=instance
)
)
return redirect('wagtailsettings_edit', app_name, model_name)
return redirect('wagtailsettings_edit', site.pk, app_name, model_name)
else:
messages.error(request, _("The setting could not be saved due to errors."))
edit_handler = edit_handler_class(instance=instance, form=form)
@ -64,9 +70,16 @@ def edit(request, app_name, model_name):
form = form_class(instance=instance)
edit_handler = edit_handler_class(instance=instance, form=form)
# Show a site switcher form if there are multiple sites
site_switcher = None
if Site.objects.count() > 1:
site_switcher = SiteSwitchForm(site, model)
return render(request, 'wagtailsettings/edit.html', {
'opts': model._meta,
'setting_type_name': setting_type_name,
'instance': instance,
'edit_handler': edit_handler,
'site': site,
'site_switcher': site_switcher,
})