From a4a3ef8147f3dfcb36df0a0067924da00dc8b11e Mon Sep 17 00:00:00 2001 From: Eric Drechsel Date: Wed, 21 Jan 2015 10:49:25 -0800 Subject: [PATCH 01/61] #901 allow absolute path references in External link chooser tab --- wagtail/wagtailadmin/forms.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailadmin/forms.py b/wagtail/wagtailadmin/forms.py index f62d7ae319..de07ac01c0 100644 --- a/wagtail/wagtailadmin/forms.py +++ b/wagtail/wagtailadmin/forms.py @@ -1,4 +1,6 @@ from django import forms +from django.core import validators +from django.forms.widgets import TextInput from django.contrib.auth import get_user_model from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm from django.utils.translation import ugettext as _ @@ -6,6 +8,25 @@ from django.utils.translation import ungettext, ugettext_lazy from wagtail.wagtailadmin.widgets import AdminPageChooser from wagtail.wagtailcore.models import Page +class URLOrAbsolutePathValidator(validators.URLValidator): + @staticmethod + def is_absolute_path(value): + return value.startswith('/') + + def __call__(self, value): + if URLOrAbsolutePathValidator.is_absolute_path(value): + return None + else: + return super(URLOrAbsolutePathValidator, self).__call__(value) + +class URLOrAbsolutePathField(forms.URLField): + widget = TextInput + default_validators = [URLOrAbsolutePathValidator()] + + def to_python(self, value): + if not URLOrAbsolutePathValidator.is_absolute_path(value): + value = super(URLOrAbsolutePathField, self).to_python(value) + return value class SearchForm(forms.Form): def __init__(self, *args, **kwargs): @@ -22,11 +43,11 @@ class SearchForm(forms.Form): class ExternalLinkChooserForm(forms.Form): - url = forms.URLField(required=True) + url = URLOrAbsolutePathField(required=True) class ExternalLinkChooserWithLinkTextForm(forms.Form): - url = forms.URLField(required=True) + url = URLOrAbsolutePathField(required=True) link_text = forms.CharField(required=True) From 577183ba898723a828a2fdb7f34b93d65e49090f Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 4 Feb 2015 20:19:17 +0000 Subject: [PATCH 02/61] Added some tests for vary key generation --- .../tests/test_image_operations.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/wagtail/wagtailimages/tests/test_image_operations.py b/wagtail/wagtailimages/tests/test_image_operations.py index f4dce96428..36d77c2e88 100644 --- a/wagtail/wagtailimages/tests/test_image_operations.py +++ b/wagtail/wagtailimages/tests/test_image_operations.py @@ -2,7 +2,7 @@ import unittest from wagtail.wagtailimages import image_operations from wagtail.wagtailimages.exceptions import InvalidFilterSpecError -from wagtail.wagtailimages.models import Image +from wagtail.wagtailimages.models import Image, Filter class WillowOperationRecorder(object): @@ -318,3 +318,33 @@ class TestWidthHeightOperation(ImageOperationTestCase): ] TestWidthHeightOperation.setup_test_methods() + + +class TestVaryKey(unittest.TestCase): + def test_vary_key(self): + image = Image(width=1000, height=1000) + fil = Filter(spec='max-100x100') + vary_key = fil.get_vary_key(image) + + self.assertEqual(vary_key, 'da39a3ee') + + def test_vary_key_fill_filter(self): + image = Image(width=1000, height=1000) + fil = Filter(spec='fill-100x100') + vary_key = fil.get_vary_key(image) + + self.assertEqual(vary_key, 'da39a3ee') + + def test_vary_key_fill_filter_with_focal_point(self): + image = Image( + width=1000, + height=1000, + focal_point_width=100, + focal_point_height=100, + focal_point_x=500, + focal_point_y=500, + ) + fil = Filter(spec='fill-100x100') + vary_key = fil.get_vary_key(image) + + self.assertEqual(vary_key, 'fa9841ef') From 3b37a52a255e023286d1094902b86c920d65eca8 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 4 Feb 2015 20:44:41 +0000 Subject: [PATCH 03/61] Replaced get_vary with vary_fields --- wagtail/wagtailimages/image_operations.py | 17 ++--------------- wagtail/wagtailimages/models.py | 6 ++++-- .../tests/test_image_operations.py | 2 +- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/wagtail/wagtailimages/image_operations.py b/wagtail/wagtailimages/image_operations.py index 3a7884a08a..9eb86a067e 100644 --- a/wagtail/wagtailimages/image_operations.py +++ b/wagtail/wagtailimages/image_operations.py @@ -38,6 +38,8 @@ class DoNothingOperation(Operation): class FillOperation(Operation): + vary_fields = ('focal_point_width', 'focal_point_height', 'focal_point_x', 'focal_point_y') + def construct(self, size, *extra): # Get width and height width_str, height_str = size.split('x') @@ -175,21 +177,6 @@ class FillOperation(Operation): willow.resize(width, height) - def get_vary(self, image): - focal_point = image.get_focal_point() - - if focal_point is not None: - focal_point_key = "%(x)d-%(y)d-%(width)dx%(height)d" % { - 'x': int(focal_point.centroid_x), - 'y': int(focal_point.centroid_y), - 'width': int(focal_point.width), - 'height': int(focal_point.height), - } - else: - focal_point_key = '' - - return [focal_point_key] - class MinMaxOperation(Operation): def construct(self, size): diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index abda78a182..1fcb2ed802 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -302,8 +302,10 @@ class Filter(models.Model): vary = [] for operation in self.operations: - if hasattr(operation, 'get_vary'): - vary.extend(operation.get_vary(image)) + for field in getattr(operation, 'vary_fields', []): + value = getattr(image, field) + if value is not None: + vary.append(str(value)) return vary diff --git a/wagtail/wagtailimages/tests/test_image_operations.py b/wagtail/wagtailimages/tests/test_image_operations.py index 36d77c2e88..fc8028cc24 100644 --- a/wagtail/wagtailimages/tests/test_image_operations.py +++ b/wagtail/wagtailimages/tests/test_image_operations.py @@ -347,4 +347,4 @@ class TestVaryKey(unittest.TestCase): fil = Filter(spec='fill-100x100') vary_key = fil.get_vary_key(image) - self.assertEqual(vary_key, 'fa9841ef') + self.assertEqual(vary_key, '0bbe3b2f') From 09f053ce1e11a0092ada5d190a95942833f4da09 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 4 Feb 2015 20:49:45 +0000 Subject: [PATCH 04/61] Make vary_key a blank string if there are no vary fields This addresses an issue which causes all renditions in a project to be regenerated after an upgrade to Wagtail 0.9. --- wagtail/wagtailimages/models.py | 6 ++++-- wagtail/wagtailimages/tests/test_image_operations.py | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index 1fcb2ed802..4fa0f6d795 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -311,10 +311,12 @@ class Filter(models.Model): def get_vary_key(self, image): vary_string = '-'.join(self.get_vary(image)) - vary_key = hashlib.sha1(vary_string.encode('utf-8')).hexdigest() - return vary_key[:8] + # Return blank string if there are no vary fields + if not vary_string: + return '' + return hashlib.sha1(vary_string.encode('utf-8')).hexdigest()[:8] _registered_operations = None diff --git a/wagtail/wagtailimages/tests/test_image_operations.py b/wagtail/wagtailimages/tests/test_image_operations.py index fc8028cc24..0218bce7de 100644 --- a/wagtail/wagtailimages/tests/test_image_operations.py +++ b/wagtail/wagtailimages/tests/test_image_operations.py @@ -326,14 +326,14 @@ class TestVaryKey(unittest.TestCase): fil = Filter(spec='max-100x100') vary_key = fil.get_vary_key(image) - self.assertEqual(vary_key, 'da39a3ee') + self.assertEqual(vary_key, '') def test_vary_key_fill_filter(self): image = Image(width=1000, height=1000) fil = Filter(spec='fill-100x100') vary_key = fil.get_vary_key(image) - self.assertEqual(vary_key, 'da39a3ee') + self.assertEqual(vary_key, '') def test_vary_key_fill_filter_with_focal_point(self): image = Image( From 0564bd6880f857e71c4b535b860908d2c7f46ece Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 4 Feb 2015 20:58:10 +0000 Subject: [PATCH 05/61] Add fields into vary even if they dont have a value --- wagtail/wagtailimages/models.py | 5 ++--- wagtail/wagtailimages/tests/test_image_operations.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index 4fa0f6d795..ad5fb63e6c 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -303,9 +303,8 @@ class Filter(models.Model): for operation in self.operations: for field in getattr(operation, 'vary_fields', []): - value = getattr(image, field) - if value is not None: - vary.append(str(value)) + value = getattr(image, field, '') + vary.append(str(value)) return vary diff --git a/wagtail/wagtailimages/tests/test_image_operations.py b/wagtail/wagtailimages/tests/test_image_operations.py index 0218bce7de..ba7634e348 100644 --- a/wagtail/wagtailimages/tests/test_image_operations.py +++ b/wagtail/wagtailimages/tests/test_image_operations.py @@ -333,7 +333,7 @@ class TestVaryKey(unittest.TestCase): fil = Filter(spec='fill-100x100') vary_key = fil.get_vary_key(image) - self.assertEqual(vary_key, '') + self.assertEqual(vary_key, '2e16d0ba') def test_vary_key_fill_filter_with_focal_point(self): image = Image( From 43641192c20d4de19f662dd7828919b24386ae16 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Fri, 6 Feb 2015 09:57:42 +0000 Subject: [PATCH 06/61] Fixed a couple of references to django.forms.util --- wagtail/wagtailadmin/menu.py | 7 +------ wagtail/wagtailembeds/views/chooser.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/wagtail/wagtailadmin/menu.py b/wagtail/wagtailadmin/menu.py index df8bf76373..5fa4ff7cff 100644 --- a/wagtail/wagtailadmin/menu.py +++ b/wagtail/wagtailadmin/menu.py @@ -2,13 +2,8 @@ from __future__ import unicode_literals from six import text_type, with_metaclass -try: - # renamed util -> utils in Django 1.7; try the new name first - from django.forms.utils import flatatt -except ImportError: - from django.forms.util import flatatt - from django.forms import MediaDefiningClass, Media +from django.forms.utils import flatatt from django.utils.text import slugify from django.utils.html import format_html from django.utils.safestring import mark_safe diff --git a/wagtail/wagtailembeds/views/chooser.py b/wagtail/wagtailembeds/views/chooser.py index 5892ed91ba..da10e802e9 100644 --- a/wagtail/wagtailembeds/views/chooser.py +++ b/wagtail/wagtailembeds/views/chooser.py @@ -1,4 +1,4 @@ -from django.forms.util import ErrorList +from django.forms.utils import ErrorList from django.utils.translation import ugettext as _ from wagtail.wagtailadmin.modal_workflow import render_modal_workflow From cf0e17d94c834c17ac30f3e21a1258688bdd7d53 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Fri, 6 Feb 2015 10:22:38 +0000 Subject: [PATCH 07/61] Added tests for resolve_model_string To make sure I don't change its behaviour in the next commit --- wagtail/wagtailcore/tests/tests.py | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/wagtail/wagtailcore/tests/tests.py b/wagtail/wagtailcore/tests/tests.py index 7cc1509cd2..c53494648f 100644 --- a/wagtail/wagtailcore/tests/tests.py +++ b/wagtail/wagtailcore/tests/tests.py @@ -1,7 +1,10 @@ +import unittest + from django.test import TestCase from django.core.cache import cache from wagtail.wagtailcore.models import Page, Site +from wagtail.wagtailcore.utils import resolve_model_string from wagtail.tests.models import SimplePage @@ -142,3 +145,42 @@ class TestSiteRootPathsCache(TestCase): # Check url self.assertEqual(homepage.url, '/') + + +class TestResolveModelString(TestCase): + def test_resolve_from_string(self): + model = resolve_model_string('wagtailcore.Page') + + self.assertEqual(model, Page) + + def test_resolve_from_string_with_default_app(self): + model = resolve_model_string('Page', default_app='wagtailcore') + + self.assertEqual(model, Page) + + def test_resolve_from_string_with_different_default_app(self): + model = resolve_model_string('wagtailcore.Page', default_app='wagtailadmin') + + self.assertEqual(model, Page) + + def test_resolve_from_class(self): + model = resolve_model_string(Page) + + self.assertEqual(model, Page) + + def test_resolve_from_string_invalid(self): + self.assertRaises(ValueError, resolve_model_string, 'wagtail.wagtailcore.Page') + + def test_resolve_from_string_with_incorrect_default_app(self): + self.assertRaises(LookupError, resolve_model_string, 'Page', default_app='wagtailadmin') + + def test_resolve_from_string_with_no_default_app(self): + self.assertRaises(ValueError, resolve_model_string, 'Page') + + @unittest.expectedFailure # Raising LookupError instead + def test_resolve_from_class_that_isnt_a_model(self): + self.assertRaises(ValueError, resolve_model_string, object) + + @unittest.expectedFailure # Raising LookupError instead + def test_resolve_from_bad_type(self): + self.assertRaises(ValueError, resolve_model_string, resolve_model_string) From 354a5aaa8025f5f5e9f3ae628a4e5bff8aadc2f1 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Fri, 6 Feb 2015 10:25:42 +0000 Subject: [PATCH 08/61] Removed reference to django.db.get_models in resolve_model_string --- wagtail/wagtailcore/utils.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wagtail/wagtailcore/utils.py b/wagtail/wagtailcore/utils.py index 1880684bc6..fbff60abb1 100644 --- a/wagtail/wagtailcore/utils.py +++ b/wagtail/wagtailcore/utils.py @@ -1,7 +1,9 @@ import re -from django.db.models import Model, get_model from six import string_types +from django.db.models import Model +from django.apps import apps + def camelcase_to_underscore(str): # http://djangosnippets.org/snippets/585/ @@ -26,10 +28,7 @@ def resolve_model_string(model_string, default_app=None): "should be in the form app_label.model_name".format( model_string), model_string) - model = get_model(app_label, model_name) - if not model: - raise LookupError("Can not resolve {0!r} into a model".format(model_string), model_string) - return model + return apps.get_model(app_label, model_name) elif isinstance(model_string, type) and issubclass(model_string, Model): return model_string From 9cf1a81034eb372d391dcf68e8c6c1896d5365b5 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Fri, 6 Feb 2015 10:28:07 +0000 Subject: [PATCH 09/61] Fixed another reference to django.db.get_models --- wagtail/wagtailcore/query.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailcore/query.py b/wagtail/wagtailcore/query.py index cc86d52b74..8911fe8be0 100644 --- a/wagtail/wagtailcore/query.py +++ b/wagtail/wagtailcore/query.py @@ -1,5 +1,7 @@ -from django.db.models import Q, get_models +from django.db.models import Q from django.contrib.contenttypes.models import ContentType +from django.apps import apps + from treebeard.mp_tree import MP_NodeQuerySet from wagtail.wagtailsearch.backends import get_search_backend @@ -154,7 +156,7 @@ class PageQuerySet(MP_NodeQuerySet): def type_q(self, klass): content_types = ContentType.objects.get_for_models(*[ - model for model in get_models() + model for model in apps.get_models() if issubclass(model, klass) ]).values() From d0b0d57ca5e5ff2940fe2364e3453b26550549ba Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Fri, 6 Feb 2015 10:34:39 +0000 Subject: [PATCH 10/61] Ignore PendingDeprecationWarnings --- wagtail/tests/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wagtail/tests/utils.py b/wagtail/tests/utils.py index f4cd561ab8..1abfb01167 100644 --- a/wagtail/tests/utils.py +++ b/wagtail/tests/utils.py @@ -25,9 +25,9 @@ class WagtailTestUtils(object): with warnings.catch_warnings(record=True) as warning_list: # catch all warnings yield - # rethrow all warnings that were not DeprecationWarnings + # rethrow all warnings that were not DeprecationWarnings or PendingDeprecationWarnings for w in warning_list: - if not issubclass(w.category, DeprecationWarning): + if not issubclass(w.category, (DeprecationWarning, PendingDeprecationWarning)): warnings.showwarning(message=w.message, category=w.category, filename=w.filename, lineno=w.lineno, file=w.file, line=w.line) # borrowed from https://github.com/django/django/commit/9f427617e4559012e1c2fd8fce46cbe225d8515d From 50e4cdf8b8306c64f46d5629ea7bf50b0a51145b Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Fri, 6 Feb 2015 10:39:04 +0000 Subject: [PATCH 11/61] Replaced SortedDict with OrderedDict --- wagtail/wagtailforms/forms.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailforms/forms.py b/wagtail/wagtailforms/forms.py index b91a378f61..2c1ba5fea8 100644 --- a/wagtail/wagtailforms/forms.py +++ b/wagtail/wagtailforms/forms.py @@ -1,5 +1,6 @@ +from collections import OrderedDict + import django.forms -from django.utils.datastructures import SortedDict class BaseForm(django.forms.Form): @@ -75,7 +76,7 @@ class FormBuilder(object): @property def formfields(self): - formfields = SortedDict() + formfields = OrderedDict() for field in self.fields: options = self.get_field_options(field) From 61bd2511a821900fd2b707b14e72bc41834264a7 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 6 Feb 2015 12:15:34 +0000 Subject: [PATCH 12/61] Don't bother to pass show_help_text to templates, because no templates ever use it. This means that the show_help_text parameter to render_as_field now has no effect, so we can safely remove it from the one call that uses it --- wagtail/wagtailadmin/edit_handlers.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py index 49caf2059d..a67dcd4688 100644 --- a/wagtail/wagtailadmin/edit_handlers.py +++ b/wagtail/wagtailadmin/edit_handlers.py @@ -422,7 +422,7 @@ class BaseFieldPanel(EditHandler): def render_as_object(self): return mark_safe(render_to_string(self.object_template, { 'self': self, - 'field_content': self.render_as_field(show_help_text=False), + 'field_content': self.render_as_field(), })) field_template = "wagtailadmin/edit_handlers/field_panel_field.html" @@ -431,7 +431,6 @@ class BaseFieldPanel(EditHandler): context = { 'field': self.bound_field, 'field_type': self.field_type(), - 'show_help_text': show_help_text, } context.update(extra_context) return mark_safe(render_to_string(self.field_template, context)) @@ -502,7 +501,6 @@ class BaseChooserPanel(BaseFieldPanel): 'field': self.bound_field, self.object_type_name: instance_obj, 'is_chosen': bool(instance_obj), - 'show_help_text': show_help_text, } context.update(extra_context) return mark_safe(render_to_string(self.field_template, context)) From e3216fad45f8a57a197afeb69af695482ed82946 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 6 Feb 2015 12:21:41 +0000 Subject: [PATCH 13/61] now the only call to render_as_field with any parameters whatsoever is where BasePageChooserPanel.render_as_field calls super - so only BaseChooserPanel.render_as_field needs to retain those parameters, and only extra_context --- wagtail/wagtailadmin/edit_handlers.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py index a67dcd4688..5e490dd9ad 100644 --- a/wagtail/wagtailadmin/edit_handlers.py +++ b/wagtail/wagtailadmin/edit_handlers.py @@ -427,12 +427,11 @@ class BaseFieldPanel(EditHandler): field_template = "wagtailadmin/edit_handlers/field_panel_field.html" - def render_as_field(self, show_help_text=True, extra_context={}): + def render_as_field(self): context = { 'field': self.bound_field, 'field_type': self.field_type(), } - context.update(extra_context) return mark_safe(render_to_string(self.field_template, context)) @classmethod @@ -495,7 +494,7 @@ class BaseChooserPanel(BaseFieldPanel): # like every other unpopulated field type. Yay consistency! return None - def render_as_field(self, show_help_text=True, extra_context={}): + def render_as_field(self, extra_context={}): instance_obj = self.get_chosen_item() context = { 'field': self.bound_field, @@ -537,13 +536,12 @@ class BasePageChooserPanel(BaseChooserPanel): return cls._target_content_type - def render_as_field(self, show_help_text=True, extra_context={}): + def render_as_field(self): context = { 'choose_another_text_str': ugettext_lazy("Choose another page"), 'choose_one_text_str': ugettext_lazy("Choose a page"), } - context.update(extra_context) - return super(BasePageChooserPanel, self).render_as_field(show_help_text, context) + return super(BasePageChooserPanel, self).render_as_field(extra_context=context) class PageChooserPanel(object): From e8246f6c4bdeb63aee809048c8d69a4119002e1c Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 6 Feb 2015 12:54:09 +0000 Subject: [PATCH 14/61] introduce a common AdminChooser superclass for all our Admin*Choosers --- wagtail/wagtailadmin/widgets.py | 5 ++++- wagtail/wagtaildocs/widgets.py | 8 ++------ wagtail/wagtailimages/widgets.py | 8 ++------ wagtail/wagtailsnippets/widgets.py | 7 ++----- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/wagtail/wagtailadmin/widgets.py b/wagtail/wagtailadmin/widgets.py index f8282082cb..3b12b95d24 100644 --- a/wagtail/wagtailadmin/widgets.py +++ b/wagtail/wagtailadmin/widgets.py @@ -34,8 +34,11 @@ class AdminTagWidget(WidgetWithScript, TagWidget): json.dumps(reverse('wagtailadmin_tag_autocomplete'))) -class AdminPageChooser(WidgetWithScript, widgets.Input): +class AdminChooser(WidgetWithScript, widgets.Input): input_type = 'hidden' + + +class AdminPageChooser(AdminChooser): target_content_type = None def __init__(self, content_type=None, **kwargs): diff --git a/wagtail/wagtaildocs/widgets.py b/wagtail/wagtaildocs/widgets.py index fd23bec8ce..643cfae660 100644 --- a/wagtail/wagtaildocs/widgets.py +++ b/wagtail/wagtaildocs/widgets.py @@ -2,13 +2,9 @@ from __future__ import absolute_import, unicode_literals import json -from django.forms import widgets - -from wagtail.utils.widgets import WidgetWithScript +from wagtail.wagtailadmin.widgets import AdminChooser -class AdminDocumentChooser(WidgetWithScript, widgets.Input): - input_type = 'hidden' - +class AdminDocumentChooser(AdminChooser): def render_js_init(self, id_, name, value): return "createDocumentChooser({0});".format(json.dumps(id_)) diff --git a/wagtail/wagtailimages/widgets.py b/wagtail/wagtailimages/widgets.py index 3580e74a18..82b278dc1b 100644 --- a/wagtail/wagtailimages/widgets.py +++ b/wagtail/wagtailimages/widgets.py @@ -2,13 +2,9 @@ from __future__ import absolute_import, unicode_literals import json -from django.forms import widgets - -from wagtail.utils.widgets import WidgetWithScript +from wagtail.wagtailadmin.widgets import AdminChooser -class AdminImageChooser(WidgetWithScript, widgets.Input): - input_type = 'hidden' - +class AdminImageChooser(AdminChooser): def render_js_init(self, id_, name, value): return "createImageChooser({0});".format(json.dumps(id_)) diff --git a/wagtail/wagtailsnippets/widgets.py b/wagtail/wagtailsnippets/widgets.py index 00945e06fc..7abf95a036 100644 --- a/wagtail/wagtailsnippets/widgets.py +++ b/wagtail/wagtailsnippets/widgets.py @@ -2,13 +2,10 @@ from __future__ import absolute_import, unicode_literals import json -from django.forms import widgets - -from wagtail.utils.widgets import WidgetWithScript +from wagtail.wagtailadmin.widgets import AdminChooser -class AdminSnippetChooser(WidgetWithScript, widgets.Input): - input_type = 'hidden' +class AdminSnippetChooser(AdminChooser): target_content_type = None def __init__(self, content_type=None, **kwargs): From 932f532b80cab6f125b102a72128b46706242299 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 6 Feb 2015 14:43:54 +0000 Subject: [PATCH 15/61] Set choose_one_text, choose_another_text and clear_choice_text as overrideable properties on AdminChooser so that we don't have to do template inheritance gymnastics to pass them around --- .../templates/wagtailstyleguide/base.html | 6 +++--- wagtail/wagtailadmin/edit_handlers.py | 10 +--------- .../edit_handlers/chooser_panel.html | 6 +++--- .../edit_handlers/page_chooser_panel.html | 3 --- .../templates/wagtailadmin/pages/copy.html | 4 +--- wagtail/wagtailadmin/widgets.py | 16 ++++++++++++++++ .../edit_handlers/document_chooser_panel.html | 4 ---- wagtail/wagtaildocs/widgets.py | 5 +++++ .../edit_handlers/image_chooser_panel.html | 4 ---- wagtail/wagtailimages/widgets.py | 6 ++++++ .../editorspicks/includes/editorspicks_form.html | 6 ++---- wagtail/wagtailsites/forms.py | 5 ++++- .../templates/wagtailsites/create.html | 6 ++---- .../templates/wagtailsites/edit.html | 7 ++----- wagtail/wagtailsnippets/edit_handlers.py | 2 +- .../edit_handlers/snippet_chooser_panel.html | 3 --- wagtail/wagtailsnippets/widgets.py | 7 +++++++ .../groups/includes/page_permissions_form.html | 7 ++----- 18 files changed, 55 insertions(+), 52 deletions(-) diff --git a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html index 89f6704c42..de0019f84c 100644 --- a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html +++ b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html @@ -348,11 +348,11 @@ {% if field.name == 'file' %} {% include "wagtailimages/images/_file_field.html" %} {% elif field.name == 'page_chooser' %} -
  • {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=field choose_one_text_str="Choose a page" choose_another_text_str="Choose another page" only %}
  • +
  • {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=field only %}
  • {% elif field.name == 'image_chooser' %} -
  • {% include "wagtailimages/edit_handlers/image_chooser_panel.html" with field=field choose_one_text_str="Choose an image" choose_another_text_str="Choose another image" only %}
  • +
  • {% include "wagtailimages/edit_handlers/image_chooser_panel.html" with field=field only %}
  • {% elif field.name == 'document_chooser' %} -
  • {% include "wagtaildocs/edit_handlers/document_chooser_panel.html" with field=field choose_one_text_str="Choose a document" choose_another_text_str="Choose another document" only %}
  • +
  • {% include "wagtaildocs/edit_handlers/document_chooser_panel.html" with field=field only %}
  • {% else %} {% include "wagtailadmin/shared/field_as_li.html" %} {% endif %} diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py index 5e490dd9ad..8aa047fc5e 100644 --- a/wagtail/wagtailadmin/edit_handlers.py +++ b/wagtail/wagtailadmin/edit_handlers.py @@ -494,14 +494,13 @@ class BaseChooserPanel(BaseFieldPanel): # like every other unpopulated field type. Yay consistency! return None - def render_as_field(self, extra_context={}): + def render_as_field(self): instance_obj = self.get_chosen_item() context = { 'field': self.bound_field, self.object_type_name: instance_obj, 'is_chosen': bool(instance_obj), } - context.update(extra_context) return mark_safe(render_to_string(self.field_template, context)) @@ -536,13 +535,6 @@ class BasePageChooserPanel(BaseChooserPanel): return cls._target_content_type - def render_as_field(self): - context = { - 'choose_another_text_str': ugettext_lazy("Choose another page"), - 'choose_one_text_str': ugettext_lazy("Choose a page"), - } - return super(BasePageChooserPanel, self).render_as_field(extra_context=context) - class PageChooserPanel(object): def __init__(self, field_name, page_type=None): diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html index bf583c1ddd..65a627479e 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html @@ -17,14 +17,14 @@
    {% if not field.field.required %} - + {% endif %} - +
    - +
    diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html index fbca951cae..800d40e651 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html @@ -3,6 +3,3 @@ {% block chosen_state_view %} {{ page.title }} {% endblock %} - -{% block choose_another_button_label %}{{ choose_another_text_str }}{% endblock %} -{% block choose_button_label %}{{ choose_one_text_str }}{% endblock %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html index ef155ef9a8..26f3196cbf 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html @@ -15,9 +15,7 @@ {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_slug %}
  • - {% trans "Change page" as choose_another_text_str %} - {% trans "Choose page" as choose_one_text_str %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.new_parent_page page=parent_page is_chosen=True choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.new_parent_page page=parent_page is_chosen=True only %}
  • {% if form.copy_subpages %} diff --git a/wagtail/wagtailadmin/widgets.py b/wagtail/wagtailadmin/widgets.py index 3b12b95d24..7bf92a7cda 100644 --- a/wagtail/wagtailadmin/widgets.py +++ b/wagtail/wagtailadmin/widgets.py @@ -5,6 +5,7 @@ import json from django.core.urlresolvers import reverse from django.forms import widgets from django.contrib.contenttypes.models import ContentType +from django.utils.translation import ugettext_lazy as _ from wagtail.utils.widgets import WidgetWithScript from wagtail.wagtailcore.models import Page @@ -36,10 +37,25 @@ class AdminTagWidget(WidgetWithScript, TagWidget): class AdminChooser(WidgetWithScript, widgets.Input): input_type = 'hidden' + choose_one_text = _("Choose an item") + choose_another_text = _("Choose another item") + clear_choice_text = _("Clear choice") + + def __init__(self, **kwargs): + # allow choose_one_text / choose_another_text to be overridden per-instance + if 'choose_one_text' in kwargs: + self.choose_one_text = kwargs.pop('choose_one_text') + if 'choose_another_text' in kwargs: + self.choose_another_text = kwargs.pop('choose_another_text') + if 'clear_choice_text' in kwargs: + self.clear_choice_text = kwargs.pop('clear_choice_text') + super(AdminChooser, self).__init__(**kwargs) class AdminPageChooser(AdminChooser): target_content_type = None + choose_one_text = _('Choose a page') + choose_another_text = _('Choose another page') def __init__(self, content_type=None, **kwargs): super(AdminPageChooser, self).__init__(**kwargs) diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html b/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html index cc3f679cc7..59dc2ed2a6 100644 --- a/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html +++ b/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html @@ -5,7 +5,3 @@ {% block chosen_state_view %} {{ document.title }} {% endblock %} - -{% block clear_button_label %}{% trans "Clear choice" %}{% endblock %} -{% block choose_another_button_label %}{% trans "Choose another document" %}{% endblock %} -{% block choose_button_label %}{% trans "Choose a document" %}{% endblock %} diff --git a/wagtail/wagtaildocs/widgets.py b/wagtail/wagtaildocs/widgets.py index 643cfae660..e5d490f516 100644 --- a/wagtail/wagtaildocs/widgets.py +++ b/wagtail/wagtaildocs/widgets.py @@ -2,9 +2,14 @@ from __future__ import absolute_import, unicode_literals import json +from django.utils.translation import ugettext_lazy as _ + from wagtail.wagtailadmin.widgets import AdminChooser class AdminDocumentChooser(AdminChooser): + choose_one_text = _('Choose a document') + choose_another_text = _('Choose another document') + def render_js_init(self, id_, name, value): return "createDocumentChooser({0});".format(json.dumps(id_)) diff --git a/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html b/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html index abae4c9058..38df1be800 100644 --- a/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html +++ b/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html @@ -13,7 +13,3 @@ {% endif %} {% endblock %} - -{% block clear_button_label %}{% trans "Clear image" %}{% endblock %} -{% block choose_another_button_label %}{% trans "Choose another image" %}{% endblock %} -{% block choose_button_label %}{% trans "Choose an image" %}{% endblock %} diff --git a/wagtail/wagtailimages/widgets.py b/wagtail/wagtailimages/widgets.py index 82b278dc1b..4bce835051 100644 --- a/wagtail/wagtailimages/widgets.py +++ b/wagtail/wagtailimages/widgets.py @@ -2,9 +2,15 @@ from __future__ import absolute_import, unicode_literals import json +from django.utils.translation import ugettext_lazy as _ + from wagtail.wagtailadmin.widgets import AdminChooser class AdminImageChooser(AdminChooser): + choose_one_text = _('Choose an image') + choose_another_text = _('Choose another image') + clear_choice_text = _('Clear image') + def render_js_init(self, id_, name, value): return "createImageChooser({0});".format(json.dumps(id_)) diff --git a/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html b/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html index aae5fdabea..64fbbd7247 100644 --- a/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html +++ b/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html @@ -10,12 +10,10 @@ {% trans "Promoted search result" %}
    • - {% trans "Choose another page" as choose_another_text_str %} - {% trans "Choose a page" as choose_one_text_str %} {% if form.instance.page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page is_chosen=True choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page is_chosen=True only %} {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page is_chosen=False choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page is_chosen=False only %} {% endif %}
    • diff --git a/wagtail/wagtailsites/forms.py b/wagtail/wagtailsites/forms.py index 7235d43130..b4f6350ba6 100644 --- a/wagtail/wagtailsites/forms.py +++ b/wagtail/wagtailsites/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.utils.translation import ugettext_lazy as _ from wagtail.wagtailcore.models import Site from wagtail.wagtailadmin.widgets import AdminPageChooser @@ -7,7 +8,9 @@ from wagtail.wagtailadmin.widgets import AdminPageChooser class SiteForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(SiteForm, self).__init__(*args, **kwargs) - self.fields['root_page'].widget = AdminPageChooser() + self.fields['root_page'].widget = AdminPageChooser( + choose_one_text=_('Choose a root page'), choose_another_text=_('Choose a different root page') + ) required_css_class = "required" diff --git a/wagtail/wagtailsites/templates/wagtailsites/create.html b/wagtail/wagtailsites/templates/wagtailsites/create.html index 55db92061d..fc8aae7112 100644 --- a/wagtail/wagtailsites/templates/wagtailsites/create.html +++ b/wagtail/wagtailsites/templates/wagtailsites/create.html @@ -17,12 +17,10 @@ {% include "wagtailadmin/shared/field_as_li.html" with field=form.port %}
    • - {% trans "Choose a different root page" as choose_another_text_str %} - {% trans "Choose a root page" as choose_one_text_str %} {% if form.instance.root_page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page is_chosen=True choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page is_chosen=True only %} {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page is_chosen=False choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page is_chosen=False only %} {% endif %}
    • diff --git a/wagtail/wagtailsites/templates/wagtailsites/edit.html b/wagtail/wagtailsites/templates/wagtailsites/edit.html index cc04bac0ec..5125e4423c 100644 --- a/wagtail/wagtailsites/templates/wagtailsites/edit.html +++ b/wagtail/wagtailsites/templates/wagtailsites/edit.html @@ -18,13 +18,10 @@ {% include "wagtailadmin/shared/field_as_li.html" with field=form.port %}
    • - {% trans "Change page" as choose_another_text_str %} - {% trans "Choose page" as choose_one_text_str %} - {% if form.instance.root_page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page is_chosen=True choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page is_chosen=True only %} {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page is_chosen=False choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page is_chosen=False only %} {% endif %}
    • diff --git a/wagtail/wagtailsnippets/edit_handlers.py b/wagtail/wagtailsnippets/edit_handlers.py index 2e230715b4..6f23d6ba34 100644 --- a/wagtail/wagtailsnippets/edit_handlers.py +++ b/wagtail/wagtailsnippets/edit_handlers.py @@ -18,7 +18,7 @@ class BaseSnippetChooserPanel(BaseChooserPanel): @classmethod def widget_overrides(cls): return {cls.field_name: AdminSnippetChooser( - content_type=cls.content_type())} + content_type=cls.content_type(), snippet_type_name=cls.snippet_type_name)} @classmethod def content_type(cls): diff --git a/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html b/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html index d58da62460..1dc2c40ebe 100644 --- a/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html +++ b/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html @@ -6,6 +6,3 @@ {% block chosen_state_view %} {% if is_chosen %}{{ item }}{% endif %} {% endblock %} - -{% block choose_another_button_label %}{% blocktrans %}Choose another {{ snippet_type_name }}{% endblocktrans %}{% endblock %} -{% block choose_button_label %}{% blocktrans %}Choose {{ snippet_type_name }}{% endblocktrans %}{% endblock %} diff --git a/wagtail/wagtailsnippets/widgets.py b/wagtail/wagtailsnippets/widgets.py index 7abf95a036..dcf73dafaf 100644 --- a/wagtail/wagtailsnippets/widgets.py +++ b/wagtail/wagtailsnippets/widgets.py @@ -2,6 +2,8 @@ from __future__ import absolute_import, unicode_literals import json +from django.utils.translation import ugettext_lazy as _ + from wagtail.wagtailadmin.widgets import AdminChooser @@ -9,6 +11,11 @@ class AdminSnippetChooser(AdminChooser): target_content_type = None def __init__(self, content_type=None, **kwargs): + if 'snippet_type_name' in kwargs: + snippet_type_name = kwargs.pop('snippet_type_name') + self.choose_one_text = _('Choose %s') % snippet_type_name + self.choose_another_text = _('Choose another %s') % snippet_type_name + super(AdminSnippetChooser, self).__init__(**kwargs) if content_type is not None: self.target_content_type = content_type diff --git a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html index 2521b11fe5..57a270b99a 100644 --- a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html +++ b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html @@ -1,13 +1,10 @@ {% load i18n %} - {% trans "Edit page" as choose_another_text_str %} - {% trans "Choose page" as choose_one_text_str %} - {% if form.instance.page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page is_chosen=True choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page is_chosen=True only %} {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page is_chosen=False choose_one_text_str=choose_one_text_str choose_another_text_str=choose_another_text_str only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page is_chosen=False only %} {% endif %} From 55c585d03e411e3b1b8cb3dff3455d29810c4581 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 6 Feb 2015 15:52:40 +0000 Subject: [PATCH 16/61] Update *_chooser_panel.html templates so that they don't have to be passed an is_chosen flag --- wagtail/wagtailadmin/edit_handlers.py | 2 +- .../templates/wagtailadmin/edit_handlers/chooser_panel.html | 2 +- wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html | 2 +- .../editorspicks/includes/editorspicks_form.html | 6 +----- wagtail/wagtailsites/templates/wagtailsites/create.html | 6 +----- wagtail/wagtailsites/templates/wagtailsites/edit.html | 6 +----- wagtail/wagtailsnippets/edit_handlers.py | 4 +--- .../edit_handlers/snippet_chooser_panel.html | 2 +- .../wagtailusers/groups/includes/page_permissions_form.html | 6 +----- 9 files changed, 9 insertions(+), 27 deletions(-) diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py index 8aa047fc5e..35c404264b 100644 --- a/wagtail/wagtailadmin/edit_handlers.py +++ b/wagtail/wagtailadmin/edit_handlers.py @@ -499,7 +499,7 @@ class BaseChooserPanel(BaseFieldPanel): context = { 'field': self.bound_field, self.object_type_name: instance_obj, - 'is_chosen': bool(instance_obj), + 'is_chosen': bool(instance_obj), # DEPRECATED - passed to templates for backwards compatibility only } return mark_safe(render_to_string(self.field_template, context)) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html index 65a627479e..a3073f0377 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html @@ -10,7 +10,7 @@ {% block form_field %} -
      +
      {% block chosen_state_view %}{% endblock %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html index 26f3196cbf..a7751ebc2c 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html @@ -15,7 +15,7 @@ {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_slug %}
    • - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.new_parent_page page=parent_page is_chosen=True only %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.new_parent_page page=parent_page only %}
    • {% if form.copy_subpages %} diff --git a/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html b/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html index 64fbbd7247..ea023d3520 100644 --- a/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html +++ b/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html @@ -10,11 +10,7 @@ {% trans "Promoted search result" %}
      • - {% if form.instance.page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page is_chosen=True only %} - {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page is_chosen=False only %} - {% endif %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page only %}
      • {% include "wagtailadmin/shared/field.html" with field=form.description only %} diff --git a/wagtail/wagtailsites/templates/wagtailsites/create.html b/wagtail/wagtailsites/templates/wagtailsites/create.html index fc8aae7112..ce71534f15 100644 --- a/wagtail/wagtailsites/templates/wagtailsites/create.html +++ b/wagtail/wagtailsites/templates/wagtailsites/create.html @@ -17,11 +17,7 @@ {% include "wagtailadmin/shared/field_as_li.html" with field=form.port %}
      • - {% if form.instance.root_page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page is_chosen=True only %} - {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page is_chosen=False only %} - {% endif %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page only %}
      • {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_default_site %} diff --git a/wagtail/wagtailsites/templates/wagtailsites/edit.html b/wagtail/wagtailsites/templates/wagtailsites/edit.html index 5125e4423c..aa15635866 100644 --- a/wagtail/wagtailsites/templates/wagtailsites/edit.html +++ b/wagtail/wagtailsites/templates/wagtailsites/edit.html @@ -18,11 +18,7 @@ {% include "wagtailadmin/shared/field_as_li.html" with field=form.port %}
      • - {% if form.instance.root_page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page is_chosen=True only %} - {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page is_chosen=False only %} - {% endif %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page only %}
      • {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_default_site %} diff --git a/wagtail/wagtailsnippets/edit_handlers.py b/wagtail/wagtailsnippets/edit_handlers.py index 6f23d6ba34..3490f6a6f2 100644 --- a/wagtail/wagtailsnippets/edit_handlers.py +++ b/wagtail/wagtailsnippets/edit_handlers.py @@ -28,14 +28,12 @@ class BaseSnippetChooserPanel(BaseChooserPanel): return cls._content_type - def render_as_field(self, show_help_text=True): + def render_as_field(self): instance_obj = self.get_chosen_item() return mark_safe(render_to_string(self.field_template, { 'field': self.bound_field, self.object_type_name: instance_obj, 'snippet_type_name': self.snippet_type_name, - 'is_chosen': bool(instance_obj), - 'show_help_text': show_help_text, })) diff --git a/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html b/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html index 1dc2c40ebe..0249e930ae 100644 --- a/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html +++ b/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html @@ -4,5 +4,5 @@ {% block chooser_class %}snippet-chooser{% endblock %} {% block chosen_state_view %} - {% if is_chosen %}{{ item }}{% endif %} + {{ item }} {% endblock %} diff --git a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html index 57a270b99a..1e6a5c3897 100644 --- a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html +++ b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html @@ -1,11 +1,7 @@ {% load i18n %} - {% if form.instance.page %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page is_chosen=True only %} - {% else %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page is_chosen=False only %} - {% endif %} + {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page only %} {% include "wagtailadmin/edit_handlers/field_panel_field.html" with field=form.permission_type only %} From f56d927be08ccba228163aac389c3fe6cbfee49f Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 6 Feb 2015 16:40:51 +0000 Subject: [PATCH 17/61] provide a render_html method on WidgetWithScript so that subclasses can override the HTML part of the rendering too --- wagtail/utils/widgets.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/wagtail/utils/widgets.py b/wagtail/utils/widgets.py index 8ae51ce6b9..04fc0f0f8f 100644 --- a/wagtail/utils/widgets.py +++ b/wagtail/utils/widgets.py @@ -5,16 +5,20 @@ from django.utils.safestring import mark_safe class WidgetWithScript(Widget): + def render_html(self, name, value, attrs): + """Render the HTML (non-JS) portion of the field markup""" + return super(WidgetWithScript, self).render(name, value, attrs) + def render(self, name, value, attrs=None): - widget = super(WidgetWithScript, self).render(name, value, attrs) + widget_html = self.render_html(name, value, attrs) final_attrs = self.build_attrs(attrs, name=name) id_ = final_attrs.get('id', None) if id_ is None: - return widget + return widget_html js = self.render_js_init(id_, name, value) - out = '{0}'.format(widget, js) + out = '{0}'.format(widget_html, js) return mark_safe(out) def render_js_init(self, id_, name, value): From 8f655cd74d6f5fe289eafa1810fb9a37b8fe41ca Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Fri, 6 Feb 2015 17:07:30 +0000 Subject: [PATCH 18/61] make WidgetWithScript explicitly fail in the absence of an ID attribute --- wagtail/utils/widgets.py | 12 +++++++----- wagtail/wagtailadmin/widgets.py | 9 +++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/wagtail/utils/widgets.py b/wagtail/utils/widgets.py index 04fc0f0f8f..cc52ba1c94 100644 --- a/wagtail/utils/widgets.py +++ b/wagtail/utils/widgets.py @@ -10,12 +10,14 @@ class WidgetWithScript(Widget): return super(WidgetWithScript, self).render(name, value, attrs) def render(self, name, value, attrs=None): - widget_html = self.render_html(name, value, attrs) + # no point trying to come up with sensible semantics for when 'id' is missing from attrs, + # so let's make sure it fails early in the process + try: + id_ = attrs['id'] + except KeyError, TypeError: + raise TypeError("WidgetWithScript cannot be rendered without an 'id' attribute") - final_attrs = self.build_attrs(attrs, name=name) - id_ = final_attrs.get('id', None) - if id_ is None: - return widget_html + widget_html = self.render_html(name, value, attrs) js = self.render_js_init(id_, name, value) out = '{0}'.format(widget_html, js) diff --git a/wagtail/wagtailadmin/widgets.py b/wagtail/wagtailadmin/widgets.py index 7bf92a7cda..702b10c796 100644 --- a/wagtail/wagtailadmin/widgets.py +++ b/wagtail/wagtailadmin/widgets.py @@ -6,6 +6,7 @@ from django.core.urlresolvers import reverse from django.forms import widgets from django.contrib.contenttypes.models import ContentType from django.utils.translation import ugettext_lazy as _ +from django.template.loader import render_to_string from wagtail.utils.widgets import WidgetWithScript from wagtail.wagtailcore.models import Page @@ -61,6 +62,14 @@ class AdminPageChooser(AdminChooser): super(AdminPageChooser, self).__init__(**kwargs) self.target_content_type = content_type or ContentType.objects.get_for_model(Page) + def render_html(self, name, value, attrs): + original_field_html = super(AdminPageChooser, self).render_html(name, value, attrs) + + return render_to_string("wagtailadmin/widgets/page_chooser.html", { + 'original_field_html': original_field_html, + 'widget': self, + }) + def render_js_init(self, id_, name, value): page = Page.objects.get(pk=value) if value else None parent = page.get_parent() if page else None From f4b1a3938a1f2a21d561114e15b2d886a320ecee Mon Sep 17 00:00:00 2001 From: benjaoming Date: Fri, 6 Feb 2015 21:28:34 -0800 Subject: [PATCH 19/61] Remove unused import Image Don't see this used anywhere...!? --- docs/core_components/pages/creating_pages.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/core_components/pages/creating_pages.rst b/docs/core_components/pages/creating_pages.rst index 24e598549e..61bcf712de 100644 --- a/docs/core_components/pages/creating_pages.rst +++ b/docs/core_components/pages/creating_pages.rst @@ -20,7 +20,6 @@ This example represents a typical blog post: from wagtail.wagtailcore.fields import RichTextField from wagtail.wagtailadmin.edit_handlers import FieldPanel from wagtail.wagtailimages.edit_handlers import ImageChooserPanel - from wagtail.wagtailimages.models import Image class BlogPage(Page): body = RichTextField() From a8f53c4b03c28e36902220672f3066fc4cb26908 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Sun, 8 Feb 2015 13:40:35 +0000 Subject: [PATCH 20/61] Added a failing test for #968 --- wagtail/wagtailimages/tests/test_image_operations.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wagtail/wagtailimages/tests/test_image_operations.py b/wagtail/wagtailimages/tests/test_image_operations.py index f4dce96428..38d6be06c4 100644 --- a/wagtail/wagtailimages/tests/test_image_operations.py +++ b/wagtail/wagtailimages/tests/test_image_operations.py @@ -151,6 +151,13 @@ class TestFillOperation(ImageOperationTestCase): ('resize', (800, 600), {}), ]), + # Basic usage with an oddly-sized original image + # This checks for a rounding precision issue (#968) + ('fill-200x200', Image(width=539, height=720), [ + ('crop', (0, 90, 539, 629), {}), + ('resize', (200, 200), {}), + ]), + # Closeness shouldn't have any effect when used without a focal point ('fill-800x600-c100', Image(width=1000, height=1000), [ ('crop', (0, 125, 1000, 875), {}), From b2b790e38756e25a222dc1b9a500a0f50b369ccb Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Sun, 8 Feb 2015 13:57:07 +0000 Subject: [PATCH 21/61] Improved precision of "fill" operation resizing Fixes #968 --- wagtail/wagtailimages/image_operations.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/wagtail/wagtailimages/image_operations.py b/wagtail/wagtailimages/image_operations.py index 3a7884a08a..f71b7290ab 100644 --- a/wagtail/wagtailimages/image_operations.py +++ b/wagtail/wagtailimages/image_operations.py @@ -158,22 +158,16 @@ class FillOperation(Operation): # Crop! willow.crop(int(left), int(top), int(right), int(bottom)) - # Resize the final image + # Get scale for resizing + # The scale should be the same for both the horizontal and + # vertical axes aftercrop_width, aftercrop_height = willow.get_size() - horz_scale = self.width / aftercrop_width - vert_scale = self.height / aftercrop_height + scale = self.width / aftercrop_width - if aftercrop_width <= self.width or aftercrop_height <= self.height: - return - - if horz_scale > vert_scale: - width = self.width - height = int(aftercrop_height * horz_scale) - else: - width = int(aftercrop_width * vert_scale) - height = self.height - - willow.resize(width, height) + # Only resize if the image is too big + if scale < 1.0: + # Resize! + willow.resize(self.width, self.height) def get_vary(self, image): focal_point = image.get_focal_point() From 357a5c7449f3a1f3d20ee9b091082d16f143d42f Mon Sep 17 00:00:00 2001 From: Alejandro Varas Date: Wed, 10 Sep 2014 12:32:26 -0300 Subject: [PATCH 22/61] Fixed TypeError raised by `richtext` template tag --- .../wagtailcore/templatetags/wagtailcore_tags.py | 4 +++- wagtail/wagtailcore/tests/tests.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/wagtail/wagtailcore/templatetags/wagtailcore_tags.py b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py index b68a66d636..c3b660a16a 100644 --- a/wagtail/wagtailcore/templatetags/wagtailcore_tags.py +++ b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py @@ -35,4 +35,6 @@ def wagtail_version(): @register.filter def richtext(value): - return mark_safe('
        ' + expand_db_html(value) + '
        ') + if value: + return mark_safe('
        ' + expand_db_html(value) + '
        ') + return '' diff --git a/wagtail/wagtailcore/tests/tests.py b/wagtail/wagtailcore/tests/tests.py index c53494648f..3531a35aeb 100644 --- a/wagtail/wagtailcore/tests/tests.py +++ b/wagtail/wagtailcore/tests/tests.py @@ -4,6 +4,7 @@ from django.test import TestCase from django.core.cache import cache from wagtail.wagtailcore.models import Page, Site +from wagtail.wagtailcore.templatetags.wagtailcore_tags import richtext from wagtail.wagtailcore.utils import resolve_model_string from wagtail.tests.models import SimplePage @@ -184,3 +185,16 @@ class TestResolveModelString(TestCase): @unittest.expectedFailure # Raising LookupError instead def test_resolve_from_bad_type(self): self.assertRaises(ValueError, resolve_model_string, resolve_model_string) + + +class TestRichtextTag(TestCase): + + def test_typeerror(self): + """`richtext` fails when it's called with `value` being not a string + or buffer. + """ + value = None + + result = richtext(value) + + self.assertEqual(result, '') From ca4cc125f252fdef0ec9ea035347d4a3421505fb Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 4 Feb 2015 23:39:28 +0000 Subject: [PATCH 23/61] Added drone config --- .drone.yml | 8 ++++++++ wagtail/tests/settings.py | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000000..eba35f8bc1 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,8 @@ +image: kaedroho/django-base +script: + - pip3.4 install mock python-dateutil pytz elasticsearch + - python3.4 setup.py install + - python3.4 runtests.py +services: + - postgres + - dockerfile/elasticsearch diff --git a/wagtail/tests/settings.py b/wagtail/tests/settings.py index 461b61fa60..57fd9c101a 100644 --- a/wagtail/tests/settings.py +++ b/wagtail/tests/settings.py @@ -16,6 +16,8 @@ DATABASES = { 'TEST_NAME': os.environ.get('DATABASE_NAME', 'test_wagtaildemo'), 'USER': os.environ.get('DATABASE_USER', 'postgres'), 'PASSWORD': os.environ.get('DATABASE_PASS', None), + 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', None), + 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', None), } } @@ -121,6 +123,13 @@ try: 'TIMEOUT': 10, 'max_retries': 1, } + + # Check if we're running in Drone + if 'ELASTICSEARCH_PORT_9200_TCP_PORT' in os.environ: + ip = os.environ.get('ELASTICSEARCH_PORT_9200_TCP_ADDR') + port = os.environ.get('ELASTICSEARCH_PORT_9200_TCP_PORT') + + WAGTAILSEARCH_BACKENDS['elasticsearch']['URLS'] = ['http://%s:%s/' % (ip, port)] except ImportError: pass From 89bb3787e3b0ed99210ff4bd23b34ec32720e537 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 9 Feb 2015 12:35:19 +0000 Subject: [PATCH 24/61] Improvements to #620 As per https://github.com/torchbox/wagtail/pull/620#issuecomment-59203932 Also improved the tests a little bit --- .../templatetags/wagtailcore_tags.py | 9 ++++++--- wagtail/wagtailcore/tests/tests.py | 17 ++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/wagtail/wagtailcore/templatetags/wagtailcore_tags.py b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py index c3b660a16a..c0cf66e29b 100644 --- a/wagtail/wagtailcore/templatetags/wagtailcore_tags.py +++ b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py @@ -35,6 +35,9 @@ def wagtail_version(): @register.filter def richtext(value): - if value: - return mark_safe('
        ' + expand_db_html(value) + '
        ') - return '' + if value is not None: + html = expand_db_html(value) + else: + html = '' + + return mark_safe('
        ' + html + '
        ') diff --git a/wagtail/wagtailcore/tests/tests.py b/wagtail/wagtailcore/tests/tests.py index 3531a35aeb..fd2e4de937 100644 --- a/wagtail/wagtailcore/tests/tests.py +++ b/wagtail/wagtailcore/tests/tests.py @@ -2,6 +2,7 @@ import unittest from django.test import TestCase from django.core.cache import cache +from django.utils.safestring import SafeString from wagtail.wagtailcore.models import Page, Site from wagtail.wagtailcore.templatetags.wagtailcore_tags import richtext @@ -188,13 +189,11 @@ class TestResolveModelString(TestCase): class TestRichtextTag(TestCase): + def test_call_with_text(self): + result = richtext("Hello world!") + self.assertEqual(result, '
        Hello world!
        ') + self.assertIsInstance(result, SafeString) - def test_typeerror(self): - """`richtext` fails when it's called with `value` being not a string - or buffer. - """ - value = None - - result = richtext(value) - - self.assertEqual(result, '') + def test_call_with_none(self): + result = richtext(None) + self.assertEqual(result, '
        ') From d4ab7e833fdb043d2b5fdff5c0ed68582af0fe13 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 9 Feb 2015 12:39:12 +0000 Subject: [PATCH 25/61] Changelog, release notes and contributor entry for #620 --- CHANGELOG.txt | 1 + CONTRIBUTORS.rst | 1 + docs/releases/0.8.5.rst | 1 + 3 files changed, 3 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2e2977ab48..c60f672d26 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -34,6 +34,7 @@ Changelog * Fix: Storage backends that return raw ContentFile objects are now handled correctly when resizing images (@georgewhewell) * Fix: Punctuation characters are no longer stripped when performing search queries * Fix: When adding tags where there were none before, it is now possible to save a single tag with multiple words in it +* Fix: richtext template tag no longer raises TypeError if None is passed into it (Alejandro Varas) 0.8.4 (04.12.2014) ~~~~~~~~~~~~~~~~~~ diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index d0c34417c2..44992e71ad 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -42,6 +42,7 @@ Contributors * georgewhewell * Frank Wiles * Sebastian Spiegel +* Alejandro Varas Translators =========== diff --git a/docs/releases/0.8.5.rst b/docs/releases/0.8.5.rst index f75f93e60b..482d660a03 100644 --- a/docs/releases/0.8.5.rst +++ b/docs/releases/0.8.5.rst @@ -20,3 +20,4 @@ Bug fixes * Storage backends that return raw ContentFile objects are now handled correctly when resizing images * Punctuation characters are no longer stripped when performing search queries * When adding tags where there were none before, it is now possible to save a single tag with multiple words in it + * ``richtext`` template tag no longer raises ``TypeError`` if ``None`` is passed into it From 6e2faa0b66fd85d470a5e51fa98e94456340630f Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 18:26:35 +0000 Subject: [PATCH 26/61] Move the page chooser HTML markup from page_chooser_panel.html entirely within the AdminPageChooser widget's render() method --- .../edit_handlers/page_chooser_panel.html | 7 ++--- .../wagtailadmin/widgets/chooser.html | 29 +++++++++++++++++++ .../wagtailadmin/widgets/page_chooser.html | 5 ++++ wagtail/wagtailadmin/widgets.py | 18 +++++++++++- 4 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 wagtail/wagtailadmin/templates/wagtailadmin/widgets/chooser.html create mode 100644 wagtail/wagtailadmin/templates/wagtailadmin/widgets/page_chooser.html diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html index 800d40e651..165bca0178 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/page_chooser_panel.html @@ -1,5 +1,2 @@ -{% extends "wagtailadmin/edit_handlers/chooser_panel.html" %} - -{% block chosen_state_view %} - {{ page.title }} -{% endblock %} +{# Page chooser is now implemented as an entirely standard form widget - page_chooser_panel.html is redundant #} +{% include "wagtailadmin/shared/field.html" %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/widgets/chooser.html b/wagtail/wagtailadmin/templates/wagtailadmin/widgets/chooser.html new file mode 100644 index 0000000000..cc5e9218f0 --- /dev/null +++ b/wagtail/wagtailadmin/templates/wagtailadmin/widgets/chooser.html @@ -0,0 +1,29 @@ +{% load i18n %} +{% comment %} + Either the chosen or unchosen div will be shown, depending on the presence + of the 'blank' class on the container. + + Any element with the 'action-choose' class will open the page chooser modal + when clicked. +{% endcomment %} + +
        + +
        + {% block chosen_state_view %}{% endblock %} + +
        + {% if not widget.is_required %} + + {% endif %} + +
        +
        + +
        + +
        + +
        + +{{ original_field_html }} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/widgets/page_chooser.html b/wagtail/wagtailadmin/templates/wagtailadmin/widgets/page_chooser.html new file mode 100644 index 0000000000..487cce366f --- /dev/null +++ b/wagtail/wagtailadmin/templates/wagtailadmin/widgets/page_chooser.html @@ -0,0 +1,5 @@ +{% extends "wagtailadmin/widgets/chooser.html" %} + +{% block chosen_state_view %} + {{ page.title }} +{% endblock %} diff --git a/wagtail/wagtailadmin/widgets.py b/wagtail/wagtailadmin/widgets.py index 702b10c796..e53bfb5c1b 100644 --- a/wagtail/wagtailadmin/widgets.py +++ b/wagtail/wagtailadmin/widgets.py @@ -42,6 +42,16 @@ class AdminChooser(WidgetWithScript, widgets.Input): choose_another_text = _("Choose another item") clear_choice_text = _("Clear choice") + def get_instance(self, model_class, value): + # helper method for cleanly turning 'value' into an instance object + if value is None: + return None + + try: + return model_class.objects.get(pk=value) + except model_class.DoesNotExist: + return None + def __init__(self, **kwargs): # allow choose_one_text / choose_another_text to be overridden per-instance if 'choose_one_text' in kwargs: @@ -65,9 +75,15 @@ class AdminPageChooser(AdminChooser): def render_html(self, name, value, attrs): original_field_html = super(AdminPageChooser, self).render_html(name, value, attrs) + model_class = self.target_content_type.model_class() + instance = self.get_instance(model_class, value) + return render_to_string("wagtailadmin/widgets/page_chooser.html", { - 'original_field_html': original_field_html, 'widget': self, + 'original_field_html': original_field_html, + 'attrs': attrs, + 'value': value, + 'page': instance, }) def render_js_init(self, id_, name, value): From fe797437e79086e22c6bfca4c65fcefb513ec488 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 18:47:11 +0000 Subject: [PATCH 27/61] Remove now-redundant references to page_chooser_panel.html --- .../wagtailstyleguide/templates/wagtailstyleguide/base.html | 2 -- wagtail/wagtailadmin/edit_handlers.py | 3 +-- wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html | 5 +---- wagtail/wagtailadmin/views/pages.py | 1 - .../editorspicks/includes/editorspicks_form.html | 2 +- wagtail/wagtailsites/templates/wagtailsites/create.html | 6 +----- wagtail/wagtailsites/templates/wagtailsites/edit.html | 6 +----- .../wagtailusers/groups/includes/page_permissions_form.html | 2 +- 8 files changed, 6 insertions(+), 21 deletions(-) diff --git a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html index de0019f84c..c0288caca7 100644 --- a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html +++ b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html @@ -347,8 +347,6 @@ {% for field in example_form %} {% if field.name == 'file' %} {% include "wagtailimages/images/_file_field.html" %} - {% elif field.name == 'page_chooser' %} -
      • {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=field only %}
      • {% elif field.name == 'image_chooser' %}
      • {% include "wagtailimages/edit_handlers/image_chooser_panel.html" with field=field only %}
      • {% elif field.name == 'document_chooser' %} diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py index 35c404264b..19b5d6a271 100644 --- a/wagtail/wagtailadmin/edit_handlers.py +++ b/wagtail/wagtailadmin/edit_handlers.py @@ -480,7 +480,7 @@ class BaseChooserPanel(BaseFieldPanel): a hidden foreign key input. Subclasses provide: - * field_template + * field_template (only required if the default template of field_panel_field.html is not usable) * object_type_name - something like 'image' which will be used as the var name for the object instance in the field_template """ @@ -505,7 +505,6 @@ class BaseChooserPanel(BaseFieldPanel): class BasePageChooserPanel(BaseChooserPanel): - field_template = "wagtailadmin/edit_handlers/page_chooser_panel.html" object_type_name = "page" _target_content_type = None diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html index a7751ebc2c..b0ccf33970 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/copy.html @@ -13,10 +13,7 @@
          {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_title %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_slug %} - -
        • - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.new_parent_page page=parent_page only %} -
        • + {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_parent_page %} {% if form.copy_subpages %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.copy_subpages %} diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index b5e05ac4f7..a9c5c6fe5c 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -698,7 +698,6 @@ def copy(request, page_id): return render(request, 'wagtailadmin/pages/copy.html', { 'page': page, - 'parent_page': parent_page, 'form': form, }) diff --git a/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html b/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html index ea023d3520..65c8c2f1d8 100644 --- a/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html +++ b/wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_form.html @@ -10,7 +10,7 @@ {% trans "Promoted search result" %}
          • - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page only %} + {% include "wagtailadmin/shared/field.html" with field=form.page only %}
          • {% include "wagtailadmin/shared/field.html" with field=form.description only %} diff --git a/wagtail/wagtailsites/templates/wagtailsites/create.html b/wagtail/wagtailsites/templates/wagtailsites/create.html index ce71534f15..8a94b372ad 100644 --- a/wagtail/wagtailsites/templates/wagtailsites/create.html +++ b/wagtail/wagtailsites/templates/wagtailsites/create.html @@ -15,11 +15,7 @@
              {% include "wagtailadmin/shared/field_as_li.html" with field=form.hostname %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.port %} - -
            • - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page only %} -
            • - + {% include "wagtailadmin/shared/field_as_li.html" with field=form.root_page %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_default_site %}
            • diff --git a/wagtail/wagtailsites/templates/wagtailsites/edit.html b/wagtail/wagtailsites/templates/wagtailsites/edit.html index aa15635866..c1b2c31e29 100644 --- a/wagtail/wagtailsites/templates/wagtailsites/edit.html +++ b/wagtail/wagtailsites/templates/wagtailsites/edit.html @@ -16,11 +16,7 @@
                {% include "wagtailadmin/shared/field_as_li.html" with field=form.hostname %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.port %} - -
              • - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.root_page page=form.instance.root_page only %} -
              • - + {% include "wagtailadmin/shared/field_as_li.html" with field=form.root_page %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_default_site %}
              • diff --git a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html index 1e6a5c3897..f6f56414df 100644 --- a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html +++ b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html @@ -1,7 +1,7 @@ {% load i18n %} - {% include "wagtailadmin/edit_handlers/page_chooser_panel.html" with field=form.page page=form.instance.page only %} + {% include "wagtailadmin/edit_handlers/field_panel_field.html" with field=form.page only %} {% include "wagtailadmin/edit_handlers/field_panel_field.html" with field=form.permission_type only %} From 41577759a1151fedf4227f121f3f5ee40233027e Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 18:58:17 +0000 Subject: [PATCH 28/61] Move the document chooser HTML markup from document_chooser_panel.html entirely within the AdminDocumentChooser widget's render() method --- .../templates/wagtailstyleguide/base.html | 2 -- wagtail/wagtaildocs/edit_handlers.py | 1 - .../edit_handlers/document_chooser_panel.html | 9 ++------- .../wagtaildocs/widgets/document_chooser.html | 6 ++++++ wagtail/wagtaildocs/widgets.py | 15 +++++++++++++++ 5 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 wagtail/wagtaildocs/templates/wagtaildocs/widgets/document_chooser.html diff --git a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html index c0288caca7..b16bc445c4 100644 --- a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html +++ b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html @@ -349,8 +349,6 @@ {% include "wagtailimages/images/_file_field.html" %} {% elif field.name == 'image_chooser' %}
              • {% include "wagtailimages/edit_handlers/image_chooser_panel.html" with field=field only %}
              • - {% elif field.name == 'document_chooser' %} -
              • {% include "wagtaildocs/edit_handlers/document_chooser_panel.html" with field=field only %}
              • {% else %} {% include "wagtailadmin/shared/field_as_li.html" %} {% endif %} diff --git a/wagtail/wagtaildocs/edit_handlers.py b/wagtail/wagtaildocs/edit_handlers.py index 70f5628476..53b752f1cd 100644 --- a/wagtail/wagtaildocs/edit_handlers.py +++ b/wagtail/wagtaildocs/edit_handlers.py @@ -5,7 +5,6 @@ from .widgets import AdminDocumentChooser class BaseDocumentChooserPanel(BaseChooserPanel): - field_template = "wagtaildocs/edit_handlers/document_chooser_panel.html" object_type_name = "document" @classmethod diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html b/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html index 59dc2ed2a6..4ea2a3d7a7 100644 --- a/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html +++ b/wagtail/wagtaildocs/templates/wagtaildocs/edit_handlers/document_chooser_panel.html @@ -1,7 +1,2 @@ -{% extends "wagtailadmin/edit_handlers/chooser_panel.html" %} -{% load i18n %} -{% block chooser_class %}document-chooser{% endblock %} - -{% block chosen_state_view %} - {{ document.title }} -{% endblock %} +{# Document chooser is now implemented as an entirely standard form widget - document_chooser_panel.html is redundant #} +{% include "wagtailadmin/shared/field.html" %} diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/widgets/document_chooser.html b/wagtail/wagtaildocs/templates/wagtaildocs/widgets/document_chooser.html new file mode 100644 index 0000000000..ac023728ad --- /dev/null +++ b/wagtail/wagtaildocs/templates/wagtaildocs/widgets/document_chooser.html @@ -0,0 +1,6 @@ +{% extends "wagtailadmin/widgets/chooser.html" %} +{% block chooser_class %}document-chooser{% endblock %} + +{% block chosen_state_view %} + {{ document.title }} +{% endblock %} diff --git a/wagtail/wagtaildocs/widgets.py b/wagtail/wagtaildocs/widgets.py index e5d490f516..73267b5392 100644 --- a/wagtail/wagtaildocs/widgets.py +++ b/wagtail/wagtaildocs/widgets.py @@ -2,14 +2,29 @@ from __future__ import absolute_import, unicode_literals import json +from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ from wagtail.wagtailadmin.widgets import AdminChooser +from wagtail.wagtaildocs.models import Document class AdminDocumentChooser(AdminChooser): choose_one_text = _('Choose a document') choose_another_text = _('Choose another document') + def render_html(self, name, value, attrs): + original_field_html = super(AdminDocumentChooser, self).render_html(name, value, attrs) + + instance = self.get_instance(Document, value) + + return render_to_string("wagtaildocs/widgets/document_chooser.html", { + 'widget': self, + 'original_field_html': original_field_html, + 'attrs': attrs, + 'value': value, + 'document': instance, + }) + def render_js_init(self, id_, name, value): return "createDocumentChooser({0});".format(json.dumps(id_)) From 435e4571b325f273560e8eafb26673da8c76f099 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 19:08:12 +0000 Subject: [PATCH 29/61] Move the image chooser HTML markup from image_chooser_panel.html entirely within the AdminImageChooser widget's render() method --- .../templates/wagtailstyleguide/base.html | 2 -- wagtail/wagtailimages/edit_handlers.py | 1 - .../edit_handlers/image_chooser_panel.html | 17 ++--------------- .../wagtailimages/widgets/image_chooser.html | 14 ++++++++++++++ wagtail/wagtailimages/widgets.py | 19 +++++++++++++++++++ 5 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 wagtail/wagtailimages/templates/wagtailimages/widgets/image_chooser.html diff --git a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html index b16bc445c4..1124aae97c 100644 --- a/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html +++ b/wagtail/contrib/wagtailstyleguide/templates/wagtailstyleguide/base.html @@ -347,8 +347,6 @@ {% for field in example_form %} {% if field.name == 'file' %} {% include "wagtailimages/images/_file_field.html" %} - {% elif field.name == 'image_chooser' %} -
              • {% include "wagtailimages/edit_handlers/image_chooser_panel.html" with field=field only %}
              • {% else %} {% include "wagtailadmin/shared/field_as_li.html" %} {% endif %} diff --git a/wagtail/wagtailimages/edit_handlers.py b/wagtail/wagtailimages/edit_handlers.py index 687d3b64ad..8cdba8cbae 100644 --- a/wagtail/wagtailimages/edit_handlers.py +++ b/wagtail/wagtailimages/edit_handlers.py @@ -5,7 +5,6 @@ from .widgets import AdminImageChooser class BaseImageChooserPanel(BaseChooserPanel): - field_template = "wagtailimages/edit_handlers/image_chooser_panel.html" object_type_name = "image" @classmethod diff --git a/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html b/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html index 38df1be800..dc3ecf1bfc 100644 --- a/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html +++ b/wagtail/wagtailimages/templates/wagtailimages/edit_handlers/image_chooser_panel.html @@ -1,15 +1,2 @@ -{% extends "wagtailadmin/edit_handlers/chooser_panel.html" %} -{% load wagtailimages_tags %} -{% load i18n %} - -{% block chooser_class %}image-chooser{% endblock %} - -{% block chosen_state_view %} -
                - {% if image %} - {% image image max-130x130 %} - {% else %} - - {% endif %} -
                -{% endblock %} +{# Image chooser is now implemented as an entirely standard form widget - image_chooser_panel.html is redundant #} +{% include "wagtailadmin/shared/field.html" %} diff --git a/wagtail/wagtailimages/templates/wagtailimages/widgets/image_chooser.html b/wagtail/wagtailimages/templates/wagtailimages/widgets/image_chooser.html new file mode 100644 index 0000000000..428b12247b --- /dev/null +++ b/wagtail/wagtailimages/templates/wagtailimages/widgets/image_chooser.html @@ -0,0 +1,14 @@ +{% extends "wagtailadmin/widgets/chooser.html" %} +{% load wagtailimages_tags %} + +{% block chooser_class %}image-chooser{% endblock %} + +{% block chosen_state_view %} +
                + {% if image %} + {% image image max-130x130 %} + {% else %} + + {% endif %} +
                +{% endblock %} diff --git a/wagtail/wagtailimages/widgets.py b/wagtail/wagtailimages/widgets.py index 4bce835051..e628ed4e91 100644 --- a/wagtail/wagtailimages/widgets.py +++ b/wagtail/wagtailimages/widgets.py @@ -2,9 +2,11 @@ from __future__ import absolute_import, unicode_literals import json +from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ from wagtail.wagtailadmin.widgets import AdminChooser +from wagtail.wagtailimages.models import get_image_model class AdminImageChooser(AdminChooser): @@ -12,5 +14,22 @@ class AdminImageChooser(AdminChooser): choose_another_text = _('Choose another image') clear_choice_text = _('Clear image') + def __init__(self, **kwargs): + super(AdminImageChooser, self).__init__(**kwargs) + self.image_model = get_image_model() + + def render_html(self, name, value, attrs): + original_field_html = super(AdminImageChooser, self).render_html(name, value, attrs) + + instance = self.get_instance(self.image_model, value) + + return render_to_string("wagtailimages/widgets/image_chooser.html", { + 'widget': self, + 'original_field_html': original_field_html, + 'attrs': attrs, + 'value': value, + 'image': instance, + }) + def render_js_init(self, id_, name, value): return "createImageChooser({0});".format(json.dumps(id_)) From 63dafbe4b77ede7e58e3dd6526b395ea94eac4bc Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 19:18:58 +0000 Subject: [PATCH 30/61] Move the snippet chooser HTML markup from snippet_chooser_panel.html entirely within the AdminSnippetChooser widget's render() method --- wagtail/wagtailsnippets/edit_handlers.py | 1 - .../edit_handlers/snippet_chooser_panel.html | 10 ++-------- .../wagtailsnippets/widgets/snippet_chooser.html | 7 +++++++ wagtail/wagtailsnippets/widgets.py | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 wagtail/wagtailsnippets/templates/wagtailsnippets/widgets/snippet_chooser.html diff --git a/wagtail/wagtailsnippets/edit_handlers.py b/wagtail/wagtailsnippets/edit_handlers.py index 3490f6a6f2..0c3f26564d 100644 --- a/wagtail/wagtailsnippets/edit_handlers.py +++ b/wagtail/wagtailsnippets/edit_handlers.py @@ -10,7 +10,6 @@ from .widgets import AdminSnippetChooser class BaseSnippetChooserPanel(BaseChooserPanel): - field_template = "wagtailsnippets/edit_handlers/snippet_chooser_panel.html" object_type_name = 'item' _content_type = None diff --git a/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html b/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html index 0249e930ae..83babb1ab7 100644 --- a/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html +++ b/wagtail/wagtailsnippets/templates/wagtailsnippets/edit_handlers/snippet_chooser_panel.html @@ -1,8 +1,2 @@ -{% extends "wagtailadmin/edit_handlers/chooser_panel.html" %} -{% load i18n %} - -{% block chooser_class %}snippet-chooser{% endblock %} - -{% block chosen_state_view %} - {{ item }} -{% endblock %} +{# Snippet chooser is now implemented as an entirely standard form widget - snippet_chooser_panel.html is redundant #} +{% include "wagtailadmin/shared/field.html" %} diff --git a/wagtail/wagtailsnippets/templates/wagtailsnippets/widgets/snippet_chooser.html b/wagtail/wagtailsnippets/templates/wagtailsnippets/widgets/snippet_chooser.html new file mode 100644 index 0000000000..b46f3dbdc2 --- /dev/null +++ b/wagtail/wagtailsnippets/templates/wagtailsnippets/widgets/snippet_chooser.html @@ -0,0 +1,7 @@ +{% extends "wagtailadmin/widgets/chooser.html" %} + +{% block chooser_class %}snippet-chooser{% endblock %} + +{% block chosen_state_view %} + {{ item }} +{% endblock %} diff --git a/wagtail/wagtailsnippets/widgets.py b/wagtail/wagtailsnippets/widgets.py index dcf73dafaf..611efc40fe 100644 --- a/wagtail/wagtailsnippets/widgets.py +++ b/wagtail/wagtailsnippets/widgets.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals import json +from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ from wagtail.wagtailadmin.widgets import AdminChooser @@ -20,6 +21,20 @@ class AdminSnippetChooser(AdminChooser): if content_type is not None: self.target_content_type = content_type + def render_html(self, name, value, attrs): + original_field_html = super(AdminSnippetChooser, self).render_html(name, value, attrs) + + model_class = self.target_content_type.model_class() + instance = self.get_instance(model_class, value) + + return render_to_string("wagtailsnippets/widgets/snippet_chooser.html", { + 'widget': self, + 'original_field_html': original_field_html, + 'attrs': attrs, + 'value': value, + 'item': instance, + }) + def render_js_init(self, id_, name, value): content_type = self.target_content_type From 13e1811c544b8694408b0b40740e4ade935eae4a Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 19:34:18 +0000 Subject: [PATCH 31/61] mark chooser_panel.html as deprecated --- .../templates/wagtailadmin/edit_handlers/chooser_panel.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html index a3073f0377..5413952d10 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/chooser_panel.html @@ -1,6 +1,12 @@ {% extends "wagtailadmin/shared/field.html" %} {% load i18n %} {% comment %} + ------ + DEPRECATED - provided for backwards compatibility with custom (third-party) chooser panels + created prior to Wagtail 0.9. New choosers should subclass wagtail.wagtailadmin.widgets.AdminChooser, + with a template that extends wagtailadmin/widgets/chooser.html. + ------ + Either the chosen or unchosen div will be shown, depending on the presence of the 'blank' class on the container. From e3dc4a593602b2e76014910350f7d4a69c228e1a Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 19:56:51 +0000 Subject: [PATCH 32/61] cast an empty string value of AdminChooser to None, as needed by required=True validation --- wagtail/wagtailadmin/widgets.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wagtail/wagtailadmin/widgets.py b/wagtail/wagtailadmin/widgets.py index e53bfb5c1b..ae127f2bb5 100644 --- a/wagtail/wagtailadmin/widgets.py +++ b/wagtail/wagtailadmin/widgets.py @@ -52,6 +52,14 @@ class AdminChooser(WidgetWithScript, widgets.Input): except model_class.DoesNotExist: return None + def value_from_datadict(self, data, files, name): + # treat the empty string as None + result = super(AdminChooser, self).value_from_datadict(data, files, name) + if result == '': + return None + else: + return result + def __init__(self, **kwargs): # allow choose_one_text / choose_another_text to be overridden per-instance if 'choose_one_text' in kwargs: From 9a3893798e635c270550b7e55af6f5fdc334b60b Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 9 Feb 2015 21:25:31 +0000 Subject: [PATCH 33/61] py3 fix --- wagtail/utils/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagtail/utils/widgets.py b/wagtail/utils/widgets.py index cc52ba1c94..6c232bb644 100644 --- a/wagtail/utils/widgets.py +++ b/wagtail/utils/widgets.py @@ -14,7 +14,7 @@ class WidgetWithScript(Widget): # so let's make sure it fails early in the process try: id_ = attrs['id'] - except KeyError, TypeError: + except (KeyError, TypeError): raise TypeError("WidgetWithScript cannot be rendered without an 'id' attribute") widget_html = self.render_html(name, value, attrs) From 0dd16132876045cc86fb45c618ef522fe360b020 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Tue, 10 Feb 2015 10:01:43 +0000 Subject: [PATCH 34/61] Project template Vagrantfile now listens on port 8000 --- docs/getting_started/creating_your_project.rst | 6 +++--- docs/getting_started/installation.rst | 4 ++-- wagtail/project_template/Vagrantfile | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/getting_started/creating_your_project.rst b/docs/getting_started/creating_your_project.rst index 18aaa89be6..76559e5578 100644 --- a/docs/getting_started/creating_your_project.rst +++ b/docs/getting_started/creating_your_project.rst @@ -126,9 +126,9 @@ To setup the Vagrant box, run the following commands djrun -If you now visit http://localhost:8111 you should see a very basic "Welcome to your new Wagtail site!" page. +If you now visit http://localhost:8000 you should see a very basic "Welcome to your new Wagtail site!" page. -You can browse the Wagtail admin interface at: http://localhost:8111/admin +You can browse the Wagtail admin interface at: http://localhost:8000/admin You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/ @@ -145,4 +145,4 @@ You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/ ``djrun`` - This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8111`` (note that the port number gets changed by Vagrant) + This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8000`` (note that the port number gets changed by Vagrant) diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index f946eca8f1..1f0fc031cf 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -29,7 +29,7 @@ Then, within the SSH session:: ./manage.py runserver 0.0.0.0:8000 -This will make the demo site available on your host machine at the URL http://localhost:8111/ - you can access the Wagtail admin interface at http://localhost:8111/admin/ . Further instructions can be found at :ref:`editor_manual`. +This will make the demo site available on your host machine at the URL http://localhost:8000/ - you can access the Wagtail admin interface at http://localhost:8000/admin/ . Further instructions can be found at :ref:`editor_manual`. Once you’ve experimented with the demo site and are ready to build your own site, it's time to install Wagtail on your host machine. Even if you intend to do all further Wagtail work within Vagrant, installing the Wagtail package on your host machine will provide the ``wagtail start`` command that sets up the initial file structure for your project. @@ -78,7 +78,7 @@ Your site is now accessible at http://localhost:8000, with the admin backend ava ./manage.py createsuperuser ./manage.py runserver 0.0.0.0:8000 -Your site is now accessible at http://localhost:8111, with the admin backend available at http://localhost:8111/admin/ . +Your site is now accessible at http://localhost:8000, with the admin backend available at http://localhost:8000/admin/ . Optional extras =============== diff --git a/wagtail/project_template/Vagrantfile b/wagtail/project_template/Vagrantfile index 81f62e993e..ffd017f241 100644 --- a/wagtail/project_template/Vagrantfile +++ b/wagtail/project_template/Vagrantfile @@ -8,7 +8,7 @@ Vagrant::Config.run do |config| # Forward a port from the guest to the host, which allows for outside # computers to access the VM, whereas host only networking does not. - config.vm.forward_port 8000, 8111 + config.vm.forward_port 8000, 8000 # Share an additional folder to the guest VM. The first argument is # an identifier, the second is the path on the guest to mount the From 75c07af32a4a8eae45a9ee02a0e7c28a8958dec7 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Tue, 10 Feb 2015 15:06:38 +0000 Subject: [PATCH 35/61] Additional 0.9 deprecation notes --- docs/releases/0.9.rst | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index 981cd60d11..0101e07601 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -28,7 +28,7 @@ Minor features * Removed the need to add permission check on admin views (now automated) * Reversing `django.contrib.auth.admin.login` will no longer lead to Wagtails login view (making it easier to have front end views) * Added cache-control headers to all admin views. This allows Varnish/Squid/CDN to run on vanilla settings in front of a Wagtail site - * Added validation to prevent pages being crated with only whitespace characters in their title fields + * Added validation to prevent pages being created with only whitespace characters in their title fields * Page model fields without a FieldPanel are no longer displayed in the form * No longer need to specify the base model on InlinePanel definitions @@ -47,18 +47,51 @@ This release drops support for Django 1.6, Python 2.6/3.2 and Elasticsearch 0.90 If you are upgrading from Elasticsearch 0.90.x, you may also need to update the ``elasticsearch`` pip package to a version greater than ``1.0`` as well. +InlinePanel definitions no longer need to specify the base model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In previous versions of Wagtail, inline child blocks on a page or snippet were defined using a declaration like:: + + InlinePanel(HomePage, 'carousel_items', label="Carousel items") + +It is no longer necessary to pass the base model as a parameter, so this declaration should be changed to:: + + InlinePanel('carousel_items', label="Carousel items") + +The old format is now deprecated; all existing InlinePanel declarations should be updated to the new format. + Login/Password reset views renamed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It was previously possible to reverse the Wagtail login using django.contrib.auth.views.login. -This is no longer possible. Update any references to `wagtailadmin_login`. +This is no longer possible. Update any references to ``wagtailadmin_login``. -Password reset view name has changed from `password_reset` to `wagtailadmin_password_reset`. +Password reset view name has changed from ``password_reset`` to ``wagtailadmin_password_reset``. -You no longer need `LOGIN_URL` and `LOGIN_REDIRECT_URL` to point to Wagtail admin. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You no longer need ``LOGIN_URL`` and ``LOGIN_REDIRECT_URL`` to point to Wagtail admin. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Javascript includes in admin backend have been moved ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To improve compatibility with third-party form widgets, pages within the Wagtail admin backend now output their Javascript includes in the HTML header, rather than at the end of the page. If your project extends the admin backend (through the ``register_admin_menu_item`` hook, for example) you will need to ensure that all associated Javascript code runs correctly from the new location. In particular, any code that accesses HTML elements will need to be contained in an 'onload' handler (e.g. jQuery's ``$(document).ready()``). + +EditHandler internal API has changed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While it is not an official Wagtail API, it has been possible for Wagtail site implementers to define their own ``EditHandler`` subclasses for use in panel definitions, to customise the behaviour of the page / snippet editing forms. If you have made use of this facility, you will need to update your custom EditHandlers, as this mechanism has been refactored (to allow EditHandler classes to keep a persistent reference to their corresponding model). If you have only used Wagtail's built-in panel types (``FieldPanel``, ``InlinePanel``, ``PageChooserPanel`` and so on), you are unaffected by this change. + +Previously, functions like ``FieldPanel`` acted as 'factory' functions, where a call such as ``FieldPanel('title')`` constructed and returned an ``EditHandler`` subclass tailored to work on a 'title' field. These functions now return an object with a ``bind_to_model`` method instead; the EditHandler subclass can be obtained by calling this with the model class as a parameter. As a guide to updating your custom EditHandler code, you may wish to refer to `the relevant change to the Wagtail codebase `_. + +chooser_panel templates are obsolete +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you have added your own custom admin views to the Wagtail admin (e.g. through the ``register_admin_urls`` hook), you may have used one of the following template includes to incorporate a chooser element for pages, documents, images or snippets into your forms: + +- ``wagtailadmin/edit_handlers/chooser_panel.html`` +- ``wagtailadmin/edit_handlers/page_chooser_panel.html`` +- ``wagtaildocs/edit_handlers/document_chooser_panel.html`` +- ``wagtailimages/edit_handlers/image_chooser_panel.html`` +- ``wagtailsnippets/edit_handlers/snippet_chooser_panel.html`` + +All of these templates are now deprecated. Wagtail now provides a set of Django form widgets for this purpose - ``AdminPageChooser``, ``AdminDocumentChooser``, ``AdminImageChooser`` and ``AdminSnippetChooser`` - which can be used in place of the ``HiddenInput`` widget that these form fields were previously using. The field can then be rendered using the regular ``wagtailadmin/shared/field.html`` or ``wagtailadmin/shared/field_as_li.html`` template. From 85aee81808d2f4e9cce606e20e394a4408aa8e56 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 11 Feb 2015 12:56:17 +0000 Subject: [PATCH 36/61] Fixed system checks import --- wagtail/wagtailcore/models.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/wagtail/wagtailcore/models.py b/wagtail/wagtailcore/models.py index 250a6798db..1a4291e195 100644 --- a/wagtail/wagtailcore/models.py +++ b/wagtail/wagtailcore/models.py @@ -26,11 +26,7 @@ from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import ValidationError, ImproperlyConfigured, ObjectDoesNotExist from django.utils.functional import cached_property from django.utils.encoding import python_2_unicode_compatible - -try: - from django.core import checks -except ImportError: - pass +from django.core import checks from treebeard.mp_tree import MP_Node From 56e398fd6464d9af66c16b74fa34f7199b91e29d Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 11 Feb 2015 12:57:56 +0000 Subject: [PATCH 37/61] Changed a unittest.skipto unittest.expectedFailure --- wagtail/wagtailusers/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagtail/wagtailusers/tests.py b/wagtail/wagtailusers/tests.py index 43e52a73e7..510e1423b3 100644 --- a/wagtail/wagtailusers/tests.py +++ b/wagtail/wagtailusers/tests.py @@ -215,7 +215,7 @@ class TestGroupCreateView(TestCase, WagtailTestUtils): new_group = Group.objects.get(name='test group') self.assertEqual(new_group.page_permissions.all().count(), 2) - @unittest.skip("currently failing on Django 1.7") + @unittest.expectedFailure def test_duplicate_page_permissions_error(self): # Try to submit duplicate page permission entries response = self.post({ From f36836bc48ec7f77ba5e516fa8ec167877510a5f Mon Sep 17 00:00:00 2001 From: Dan Braghis Date: Thu, 12 Feb 2015 11:39:17 +0000 Subject: [PATCH 38/61] Change FileWrapper import location --- wagtail/wagtaildocs/views/serve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagtail/wagtaildocs/views/serve.py b/wagtail/wagtaildocs/views/serve.py index ff89c4543e..5d53544a15 100644 --- a/wagtail/wagtaildocs/views/serve.py +++ b/wagtail/wagtaildocs/views/serve.py @@ -1,6 +1,6 @@ from django.shortcuts import get_object_or_404 -from django.core.servers.basehttp import FileWrapper from django.http import HttpResponse +from wsgiref.util import FileWrapper from wagtail.wagtaildocs.models import Document, document_served From 918f286eeac567ec460d786a6cfd3dd4d95185a6 Mon Sep 17 00:00:00 2001 From: Dan Braghis Date: Thu, 12 Feb 2015 11:39:31 +0000 Subject: [PATCH 39/61] Use StreamingHttpResponse to server documents --- wagtail/wagtaildocs/views/serve.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtaildocs/views/serve.py b/wagtail/wagtaildocs/views/serve.py index 5d53544a15..c10a369897 100644 --- a/wagtail/wagtaildocs/views/serve.py +++ b/wagtail/wagtaildocs/views/serve.py @@ -1,6 +1,6 @@ from django.shortcuts import get_object_or_404 -from django.http import HttpResponse from wsgiref.util import FileWrapper +from django.http import StreamingHttpResponse from wagtail.wagtaildocs.models import Document, document_served @@ -8,7 +8,7 @@ from wagtail.wagtaildocs.models import Document, document_served def serve(request, document_id, document_filename): doc = get_object_or_404(Document, id=document_id) wrapper = FileWrapper(doc.file) - response = HttpResponse(wrapper, content_type='application/octet-stream') + response = StreamingHttpResponse(wrapper, content_type='application/octet-stream') # TODO: strip out weird characters like semicolons from the filename # (there doesn't seem to be an official way of escaping them) From 29caba921e7c06f77f1bd0fb266c099a144dbca3 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Thu, 12 Feb 2015 12:23:58 +0000 Subject: [PATCH 40/61] Added tests for docs serve view --- wagtail/wagtaildocs/tests.py | 47 +++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/wagtail/wagtaildocs/tests.py b/wagtail/wagtaildocs/tests.py index 117d3bfed2..d98b93393a 100644 --- a/wagtail/wagtaildocs/tests.py +++ b/wagtail/wagtaildocs/tests.py @@ -1,5 +1,6 @@ from six import b import unittest +import mock from django.test import TestCase from django.contrib.auth import get_user_model @@ -17,9 +18,6 @@ from wagtail.wagtaildocs.models import Document from wagtail.wagtaildocs import models -# TODO: Test serve view - - class TestDocumentPermissions(TestCase): def setUp(self): # Create some user accounts for testing permissions @@ -519,3 +517,46 @@ class TestIssue613(TestCase, WagtailTestUtils): # Check self.assertEqual(len(results), 1) self.assertEqual(results[0].id, document.id) + + +class TestServeView(TestCase): + def setUp(self): + self.document = models.Document(title="Test document") + self.document.file.save('example.doc', ContentFile("A boring example document")) + + def get(self): + return self.client.get(reverse('wagtaildocs_serve', args=(self.document.id, 'example.doc'))) + + def test_response_code(self): + self.assertEqual(self.get().status_code, 200) + + @unittest.expectedFailure # Filename has a random string appended to it + def test_content_disposition_header(self): + self.assertEqual(self.get()['Content-Disposition'], 'attachment; filename=example.doc') + + def test_content_length_header(self): + self.assertEqual(self.get()['Content-Length'], '25') + + def test_is_streaming_response(self): + self.assertTrue(self.get().streaming) + + def test_content(self): + self.assertEqual(b"".join(self.get().streaming_content), b"A boring example document") + + def test_document_served_fired(self): + mock_handler = mock.MagicMock() + models.document_served.connect(mock_handler) + + self.get() + + self.assertEqual(mock_handler.call_count, 1) + self.assertEqual(mock_handler.mock_calls[0][2]['sender'], self.document) + + def test_with_nonexistant_document(self): + response = self.client.get(reverse('wagtaildocs_serve', args=(1000, 'blahblahblah', ))) + self.assertEqual(response.status_code, 404) + + @unittest.expectedFailure + def test_with_incorrect_filename(self): + response = self.client.get(reverse('wagtaildocs_serve', args=(self.document.id, 'incorrectfilename'))) + self.assertEqual(response.status_code, 404) From 76ef1eb41af508887b8226f02fe4787d8f67db14 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Thu, 12 Feb 2015 12:45:38 +0000 Subject: [PATCH 41/61] Fixed spelling mistake --- wagtail/wagtaildocs/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagtail/wagtaildocs/tests.py b/wagtail/wagtaildocs/tests.py index d98b93393a..e0060e49b9 100644 --- a/wagtail/wagtaildocs/tests.py +++ b/wagtail/wagtaildocs/tests.py @@ -552,7 +552,7 @@ class TestServeView(TestCase): self.assertEqual(mock_handler.call_count, 1) self.assertEqual(mock_handler.mock_calls[0][2]['sender'], self.document) - def test_with_nonexistant_document(self): + def test_with_nonexistent_document(self): response = self.client.get(reverse('wagtaildocs_serve', args=(1000, 'blahblahblah', ))) self.assertEqual(response.status_code, 404) From 6fef8f441dd95c51fd1e45b405feff8b072bc8ab Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Thu, 12 Feb 2015 13:53:05 +0000 Subject: [PATCH 42/61] Changelog and release notes for #990 --- CHANGELOG.txt | 1 + docs/releases/0.8.5.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c60f672d26..45d6a09d23 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -35,6 +35,7 @@ Changelog * Fix: Punctuation characters are no longer stripped when performing search queries * Fix: When adding tags where there were none before, it is now possible to save a single tag with multiple words in it * Fix: richtext template tag no longer raises TypeError if None is passed into it (Alejandro Varas) +* Fix: Serving documents now uses a streaming HTTP response and will no longer break Djangos cache middleware 0.8.4 (04.12.2014) ~~~~~~~~~~~~~~~~~~ diff --git a/docs/releases/0.8.5.rst b/docs/releases/0.8.5.rst index 482d660a03..f5877583cc 100644 --- a/docs/releases/0.8.5.rst +++ b/docs/releases/0.8.5.rst @@ -21,3 +21,4 @@ Bug fixes * Punctuation characters are no longer stripped when performing search queries * When adding tags where there were none before, it is now possible to save a single tag with multiple words in it * ``richtext`` template tag no longer raises ``TypeError`` if ``None`` is passed into it + * Serving documents now uses a streaming HTTP response and will no longer break Djangos cache middleware From 8fe8c5bc134fd78817b9450ce6e525b39461ceb9 Mon Sep 17 00:00:00 2001 From: Dan Braghis Date: Thu, 12 Feb 2015 14:46:31 +0000 Subject: [PATCH 43/61] Add changelog/release notes for #978 --- CHANGELOG.txt | 1 + docs/releases/0.9.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 45d6a09d23..81e1235714 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -22,6 +22,7 @@ Changelog * Added validation to prevent pages being crated with only whitespace characters in their title fields (Frank Wiles) * Page model fields without a FieldPanel are no longer displayed in the form * No longer need to specify the base model on InlinePanel definitions + * The project template Vagrantfile now listens on port 8000 0.8.5 (xx.xx.20xx) diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index 0101e07601..e265150aea 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -31,6 +31,7 @@ Minor features * Added validation to prevent pages being created with only whitespace characters in their title fields * Page model fields without a FieldPanel are no longer displayed in the form * No longer need to specify the base model on InlinePanel definitions + * The project template Vagrantfile now listens on port 8000 Bug fixes From d9b78580a8fbcf670485cba0518663bf279c6e1f Mon Sep 17 00:00:00 2001 From: John Franey Date: Thu, 12 Feb 2015 12:22:44 -0500 Subject: [PATCH 44/61] Update form_builder.rst Update import statement to include all classes used in the example --- docs/core_components/form_builder.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/core_components/form_builder.rst b/docs/core_components/form_builder.rst index a98284d35b..7682bbba62 100644 --- a/docs/core_components/form_builder.rst +++ b/docs/core_components/form_builder.rst @@ -23,7 +23,11 @@ Within the models.py of one of your apps, create a model that extends wagtailfor .. code:: python - + + from modelcluster.fields import ParentalKey + from wagtail.wagtailadmin.edit_handlers import (FieldPanel, InlinePanel, + MultiFieldPanel) + from wagtail.wagtailcore.fields import RichTextField from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField class FormField(AbstractFormField): From 9072274a0199732834c0c6ec88688961dfa9eac1 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 11 Feb 2015 16:12:37 +0000 Subject: [PATCH 45/61] Improved front page --- docs/index.rst | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index c2236810e3..d8187fe4bd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,19 +1,31 @@ Welcome to Wagtail's documentation ================================== -Wagtail is a modern, flexible CMS, built on Django. +Wagtail is an open source CMS written in `Python `_ and built on the `Django web framework `_. -It supports Django 1.7.0+ on Python 2.7, 3.3 and 3.4. +Below are some useful links to help you get started with Wagtail. -.. toctree:: - :maxdepth: 3 - :titlesonly: - getting_started/index - core_components/index - contrib_components/index - howto/index - reference/index - support - editor_manual/index - releases/index +* **First steps** + + :doc:`Installation ` + + :doc:`Starting a project ` + + +* **Creating your Wagtail site** + + :doc:`core_components/pages/creating_pages` + + :doc:`Writing templates ` + + :doc:`core_components/images/index` + + :doc:`core_components/search/index` + + :doc:`howto/third_party_tutorials` + + +* **Using Wagtail** + + :doc:`Editors guide ` From 5d6aa0c6cac830637a55e61e55d4fc0079d163c8 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 11 Feb 2015 16:15:52 +0000 Subject: [PATCH 46/61] Started restructuring getting started docs --- .../getting_started/creating_your_project.rst | 132 ++---------------- docs/getting_started/installation.rst | 73 +--------- docs/getting_started/the_template.rst | 81 +++++++++++ docs/getting_started/using_vagrant.rst | 37 +++++ 4 files changed, 139 insertions(+), 184 deletions(-) create mode 100644 docs/getting_started/the_template.rst create mode 100644 docs/getting_started/using_vagrant.rst diff --git a/docs/getting_started/creating_your_project.rst b/docs/getting_started/creating_your_project.rst index 76559e5578..6264ef3fd7 100644 --- a/docs/getting_started/creating_your_project.rst +++ b/docs/getting_started/creating_your_project.rst @@ -11,7 +11,7 @@ The ``wagtail start`` command The easiest way to start a new project with wagtail is to use the ``wagtail start`` command. This command is installed into your environment when you install Wagtail (see: :doc:`installation`). -The command works the same way as ``django-admin.py startproject`` except that the produced project is pre-configured for Wagtail. It also contains some useful extras which we will look at in the next section. +The command works the same way as ``django-admin.py startproject`` except that the produced project is pre-configured for Wagtail. It also contains some useful extras which are documented :doc:`here `. To create a project, cd into a directory where you would like to create your project and run the following command: @@ -20,129 +20,25 @@ To create a project, cd into a directory where you would like to create your pro wagtail start mysite -The project -=========== +Running it +========== -Lets look at what ``wagtail start`` created:: +TODO - mysite/ - core/ - static/ - templates/ - base.html - 404.html - 500.html - mysite/ - settings/ - base.py - dev.py - production.py - manage.py - vagrant/ - provision.sh - Vagrantfile - readme.rst - requirements.txt - - -The "core" app ----------------- - -Location: ``/mysite/core/`` - -This app is here to help get you started quicker by providing a ``HomePage`` model with migrations to create one when you first setup your app. + cd mysite + pip install -r requirements.txt + python manage.py migrate + python manage.py createsuperuser + python manage.py runserver -Default templates and static files ----------------------------------- - -Location: ``/mysite/core/templates/`` and ``/mysite/core/static/`` - -The templates directory contains ``base.html``, ``404.html`` and ``500.html``. These files are very commonly needed on Wagtail sites to they have been added into the template. - -The static directory contains an empty javascript and sass file. Wagtail uses ``django-compressor`` for compiling and compressing static files. For more information, see: `Django Compressor Documentation `_ +Your site is now accessible at http://localhost:8000, with the admin backend available at http://localhost:8000/admin/ . -Vagrant configuration ---------------------- +Using Vagrant +------------- -Location: ``/Vagrantfile`` and ``/vagrant/`` - -If you have Vagrant installed, these files let you easily setup a development environment with PostgreSQL and Elasticsearch inside a virtual machine. - -See below section `With Vagrant`_ for info on how to use Vagrant in development - -If you do not want to use Vagrant, you can just delete these files. +TODO -Django settings ---------------- - -Location: ``/mysite/mysite/settings/`` - -The Django settings files are split up into ``base.py``, ``dev.py``, ``production.py`` and ``local.py``. - -.. glossary:: - - ``base.py`` - - This file is for global settings that will be used in both development and production. Aim to keep most of your configuration in this file. - - ``dev.py`` - - This file is for settings that will only be used by developers. For example: ``DEBUG = True`` - - ``production.py`` - - This file is for settings that will only run on a production server. For example: ``DEBUG = False`` - - ``local.py`` - - This file is used for settings local to a particular machine. This file should never be tracked by a version control system. - - .. tip:: - - On production servers, we recommend that you only store secrets in local.py (such as API keys and passwords). This can save you headaches in the future if you are ever trying to debug why a server is behaving badly. If you are using multiple servers which need different settings then we recommend that you create a different ``production.py`` file for each one. - - -Getting it running -================== - - -With Vagrant ------------- - -This is the easiest way to get the project running. Vagrant runs your project locally in a virtual machine so you can use PostgreSQL and Elasticsearch in development without having to install them on your host machine. If you haven't yet installed Vagrant, see: `Installing Vagrant `_. - - -To setup the Vagrant box, run the following commands - - .. code-block:: bash - - vagrant up # This may take some time on first run - vagrant ssh - # within the ssh session - dj createsuperuser - djrun - - -If you now visit http://localhost:8000 you should see a very basic "Welcome to your new Wagtail site!" page. - -You can browse the Wagtail admin interface at: http://localhost:8000/admin - -You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/ - - -.. topic:: The ``dj`` and ``djrun`` aliases - - When using Vagrant, the Wagtail template provides two aliases: ``dj`` and ``djrun`` which can be used in the ``vagrant ssh`` session. - - .. glossary:: - - ``dj`` - - This is short for ``python manage.py`` so you can use it to reduce typing. For example: ``python manage.py syncdb`` becomes ``dj syncdb``. - - ``djrun`` - - This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8000`` (note that the port number gets changed by Vagrant) +:doc:`getting_started/using_vagrant` diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index 1f0fc031cf..823f298182 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -2,6 +2,7 @@ Installation ============ + Before you start ================ @@ -10,75 +11,13 @@ A basic Wagtail setup can be installed on your machine with only a few prerequis Whether you just want to try out the demo site, or you're ready to dive in and create a Wagtail site with all bells and whistles enabled, we strongly recommend the Vagrant approach. Nevertheless, if you're the sort of person who balks at the idea of downloading a whole operating system just to run a web app, we've got you covered too. Start from `A basic Wagtail installation`_ below. -The demo site (a.k.a. the no-installation route) -================================================ - -We provide a demo site containing a set of standard templates and page types - if you're new to Wagtail, this is the best way to try it out and familiarise yourself with how Wagtail works from the point of view of an editor. - -If you're happy to use Vagrant, and you just want to set up the Wagtail demo site, or any other pre-existing Wagtail site that ships with Vagrant support, you don't need to install Wagtail at all. Install `Vagrant `__ and `VirtualBox `__, and run:: - - git clone https://github.com/torchbox/wagtaildemo.git - cd wagtaildemo - vagrant up - vagrant ssh +Install Python +============== -Then, within the SSH session:: +Install Wagtail +=============== - ./manage.py createsuperuser - ./manage.py runserver 0.0.0.0:8000 - - -This will make the demo site available on your host machine at the URL http://localhost:8000/ - you can access the Wagtail admin interface at http://localhost:8000/admin/ . Further instructions can be found at :ref:`editor_manual`. - -Once you’ve experimented with the demo site and are ready to build your own site, it's time to install Wagtail on your host machine. Even if you intend to do all further Wagtail work within Vagrant, installing the Wagtail package on your host machine will provide the ``wagtail start`` command that sets up the initial file structure for your project. - - -A basic Wagtail installation -============================ - -This provides everything you need to create a new Wagtail project from scratch, containing no page definitions or templates other than a basic homepage as a starting point for building your site. (For a gentler introduction to Wagtail, you may wish to try out the demo site first!) - -You will need Python's `pip `__ package manager. We also recommend `virtualenvwrapper `_ so that you can manage multiple independent Python environments for different projects - although this is not strictly necessary if you intend to do all your development under Vagrant. - -Wagtail is based on the Django web framework and various other Python libraries. Most of these are pure Python and will install automatically using ``pip``, but there are a few native-code components that require further attention: - - * libsass-python (for compiling SASS stylesheets) - requires a C++ compiler and the Python development headers. - * Pillow (for image processing) - additionally requires libjpeg and zlib. - -On Debian or Ubuntu, these can be installed with the command:: - - sudo apt-get install python-dev python-pip g++ libjpeg62-dev zlib1g-dev - -With these dependencies installed, Wagtail can then be installed with the command:: - - pip install wagtail - -(or if you're not using virtualenvwrapper: ``sudo pip install wagtail``.) - -You will now be able to run the following command to set up an initial file structure for your Wagtail project (replace ``myprojectname`` with a name of your choice):: - - wagtail start myprojectname - -**Without Vagrant:** Run the following steps to complete setup of your project (the ``createsuperuser`` step will prompt you to set up a superuser account):: - - cd myprojectname - pip install -r requirements.txt - python manage.py migrate - python manage.py createsuperuser - python manage.py runserver - -Your site is now accessible at http://localhost:8000, with the admin backend available at http://localhost:8000/admin/ . - -**With Vagrant:** Run the following steps to bring up the virtual machine and complete setup of your project (the ``createsuperuser`` step will prompt you to set up a superuser account):: - - cd myprojectname - vagrant up - vagrant ssh - ./manage.py createsuperuser - ./manage.py runserver 0.0.0.0:8000 - -Your site is now accessible at http://localhost:8000, with the admin backend available at http://localhost:8000/admin/ . Optional extras =============== @@ -104,6 +43,7 @@ This assumes that your PostgreSQL instance is configured to allow you to connect ElasticSearch ------------- + Wagtail integrates with ElasticSearch to provide full-text searching of your content, both within the Wagtail interface and on your site's front-end. If ElasticSearch is not available, Wagtail will fall back to much more basic search functionality using database queries. ElasticSearch is pre-installed as part of the Vagrant virtual machine image; non-Vagrant users can use the `debian.sh `__ or `ubuntu.sh `__ installation scripts as a guide. To enable ElasticSearch for your project, uncomment the ``elasticsearch`` line from your project's requirements.txt, and in ``myprojectname/settings/base.py``, uncomment the WAGTAILSEARCH_BACKENDS section. Then run:: @@ -153,6 +93,7 @@ to your deployment preferences. The canonical version is at `github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh `_. + Docker ------ diff --git a/docs/getting_started/the_template.rst b/docs/getting_started/the_template.rst new file mode 100644 index 0000000000..34e29d9af0 --- /dev/null +++ b/docs/getting_started/the_template.rst @@ -0,0 +1,81 @@ +The project template +==================== + + mysite/ + core/ + static/ + templates/ + base.html + 404.html + 500.html + mysite/ + settings/ + base.py + dev.py + production.py + manage.py + vagrant/ + provision.sh + Vagrantfile + readme.rst + requirements.txt + + +The "core" app +---------------- + +Location: ``/mysite/core/`` + +This app is here to help get you started quicker by providing a ``HomePage`` model with migrations to create one when you first setup your app. + + +Default templates and static files +---------------------------------- + +Location: ``/mysite/core/templates/`` and ``/mysite/core/static/`` + +The templates directory contains ``base.html``, ``404.html`` and ``500.html``. These files are very commonly needed on Wagtail sites to they have been added into the template. + +The static directory contains an empty javascript and sass file. Wagtail uses ``django-compressor`` for compiling and compressing static files. For more information, see: `Django Compressor Documentation `_ + + +Vagrant configuration +--------------------- + +Location: ``/Vagrantfile`` and ``/vagrant/`` + +If you have Vagrant installed, these files let you easily setup a development environment with PostgreSQL and Elasticsearch inside a virtual machine. + +See below section `With Vagrant`_ for info on how to use Vagrant in development + +If you do not want to use Vagrant, you can just delete these files. + + +Django settings +--------------- + +Location: ``/mysite/mysite/settings/`` + +The Django settings files are split up into ``base.py``, ``dev.py``, ``production.py`` and ``local.py``. + +.. glossary:: + + ``base.py`` + + This file is for global settings that will be used in both development and production. Aim to keep most of your configuration in this file. + + ``dev.py`` + + This file is for settings that will only be used by developers. For example: ``DEBUG = True`` + + ``production.py`` + + This file is for settings that will only run on a production server. For example: ``DEBUG = False`` + + ``local.py`` + + This file is used for settings local to a particular machine. This file should never be tracked by a version control system. + + .. tip:: + + On production servers, we recommend that you only store secrets in local.py (such as API keys and passwords). This can save you headaches in the future if you are ever trying to debug why a server is behaving badly. If you are using multiple servers which need different settings then we recommend that you create a different ``production.py`` file for each one. diff --git a/docs/getting_started/using_vagrant.rst b/docs/getting_started/using_vagrant.rst new file mode 100644 index 0000000000..d04c755d96 --- /dev/null +++ b/docs/getting_started/using_vagrant.rst @@ -0,0 +1,37 @@ +Using Vagrant +============= + +This is the easiest way to get the project running. Vagrant runs your project locally in a virtual machine so you can use PostgreSQL and Elasticsearch in development without having to install them on your host machine. If you haven't yet installed Vagrant, see: `Installing Vagrant `_. + + +To setup the Vagrant box, run the following commands + + .. code-block:: bash + + vagrant up # This may take some time on first run + vagrant ssh + # within the ssh session + dj createsuperuser + djrun + + +If you now visit http://localhost:8111 you should see a very basic "Welcome to your new Wagtail site!" page. + +You can browse the Wagtail admin interface at: http://localhost:8111/admin + +You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/ + + +.. topic:: The ``dj`` and ``djrun`` aliases + + When using Vagrant, the Wagtail template provides two aliases: ``dj`` and ``djrun`` which can be used in the ``vagrant ssh`` session. + + .. glossary:: + + ``dj`` + + This is short for ``python manage.py`` so you can use it to reduce typing. For example: ``python manage.py syncdb`` becomes ``dj syncdb``. + + ``djrun`` + + This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8111`` (note that the port number gets changed by Vagrant) From 3cdedf12f2d9743f32392ee32d69fd078ae7a2f3 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 11 Feb 2015 17:30:03 +0000 Subject: [PATCH 47/61] Docs updates --- .../getting_started/creating_your_project.rst | 86 ++++++++++++++----- docs/getting_started/index.rst | 1 + docs/getting_started/installation.rst | 5 ++ docs/index.rst | 22 ++++- docs/reference/index.rst | 1 + .../project_template.rst} | 4 +- 6 files changed, 93 insertions(+), 26 deletions(-) rename docs/{getting_started/the_template.rst => reference/project_template.rst} (96%) diff --git a/docs/getting_started/creating_your_project.rst b/docs/getting_started/creating_your_project.rst index 6264ef3fd7..322218223d 100644 --- a/docs/getting_started/creating_your_project.rst +++ b/docs/getting_started/creating_your_project.rst @@ -1,38 +1,79 @@ -===================== -Creating your project -===================== +=========================== +Starting your first project +=========================== -.. contents:: Contents - :local: +Once you've installed Wagtail, you are ready start your first project. -The ``wagtail start`` command -============================= - -The easiest way to start a new project with wagtail is to use the ``wagtail start`` command. This command is installed into your environment when you install Wagtail (see: :doc:`installation`). - -The command works the same way as ``django-admin.py startproject`` except that the produced project is pre-configured for Wagtail. It also contains some useful extras which are documented :doc:`here `. - -To create a project, cd into a directory where you would like to create your project and run the following command: +Wagtail provides a command to get you started called ``wagtail start``. Open up a command line shell in your project folder and type: .. code-block:: bash wagtail start mysite +This should create a new folder called ``mysite``. Its contents are similar to what ``django-admin.py startproject`` creates but ``wagtail start`` comes with some useful extras that are documented :doc:`here <../reference/project_template>`. + + Running it ========== -TODO - - cd mysite - pip install -r requirements.txt - python manage.py migrate - python manage.py createsuperuser - python manage.py runserver +Firstly, open up a command line shell in your new projects directory. -Your site is now accessible at http://localhost:8000, with the admin backend available at http://localhost:8000/admin/ . +* **1. Create a virtual environment** + + This is only required when you first run your project. This creates a folder to install extra Python modules into. + + **Linux/Mac OSX:** :code:`pyvenv venv` + + **Windows:** :code:`c:\Python34\python -m venv myenv` + + + https://docs.python.org/3/library/venv.html + + + **Python 2.7** + + ``pyvenv`` is only included with Python 3.3 onwards. To get virtual environments on Python 2, use the ``virtualenv`` package: + + .. code-block:: bash + + pip install virtualenv + virtualenv venv + + +* **2. Activate the virtual environment** + + **Linux/Mac OSX:** :code:`source venv/bin/activate` + + **Windows:** :code:`venv/Scripts/activate.bat` + + https://docs.python.org/3/library/venv.html + + +* **3. Install PIP requirements** + + :code:`pip install -r requirements.txt` + + +* **4. Create the database** + + By default, this would create an SQLite database file within the project directory. + + :code:`python manage.py migrate` + + +* **5. Create an admin user** + + :code:`python manage.py createsuperuser` + + +* **6. Run the development server** + + :code:`python manage.py runserver` + + Your site is now accessible at ``http://localhost:8000``, with the admin backend available at ``http://localhost:8000/admin/``. Using Vagrant @@ -40,5 +81,4 @@ Using Vagrant TODO - -:doc:`getting_started/using_vagrant` +:doc:`using_vagrant` diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst index c614276e8f..239df37e10 100644 --- a/docs/getting_started/index.rst +++ b/docs/getting_started/index.rst @@ -7,3 +7,4 @@ Getting started installation creating_your_project + using_vagrant diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index 823f298182..0628f13adf 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -14,10 +14,15 @@ Whether you just want to try out the demo site, or you're ready to dive in and c Install Python ============== +We recommend installing Python 3.4, but Wagtail also works with Python 2.7 and 3.3. + + Install Wagtail =============== +``pip install wagtail`` + Optional extras =============== diff --git a/docs/index.rst b/docs/index.rst index d8187fe4bd..05fe57ce00 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,9 +8,9 @@ Below are some useful links to help you get started with Wagtail. * **First steps** - :doc:`Installation ` + :doc:`getting_started/installation` - :doc:`Starting a project ` + :doc:`getting_started/creating_your_project` * **Creating your Wagtail site** @@ -29,3 +29,21 @@ Below are some useful links to help you get started with Wagtail. * **Using Wagtail** :doc:`Editors guide ` + + +Index +----- + + +.. toctree:: + :maxdepth: 2 + :titlesonly: + + getting_started/index + core_components/index + contrib_components/index + howto/index + reference/index + support + editor_manual/index + releases/index diff --git a/docs/reference/index.rst b/docs/reference/index.rst index c144fc6b19..568600b52c 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -6,3 +6,4 @@ Reference :maxdepth: 2 management_commands + project_template diff --git a/docs/getting_started/the_template.rst b/docs/reference/project_template.rst similarity index 96% rename from docs/getting_started/the_template.rst rename to docs/reference/project_template.rst index 34e29d9af0..8b5baadbec 100644 --- a/docs/getting_started/the_template.rst +++ b/docs/reference/project_template.rst @@ -1,6 +1,8 @@ The project template ==================== +.. code-block:: text + mysite/ core/ static/ @@ -46,7 +48,7 @@ Location: ``/Vagrantfile`` and ``/vagrant/`` If you have Vagrant installed, these files let you easily setup a development environment with PostgreSQL and Elasticsearch inside a virtual machine. -See below section `With Vagrant`_ for info on how to use Vagrant in development +See :doc:`../getting_started/using_vagrant` for info on how to use Vagrant in development If you do not want to use Vagrant, you can just delete these files. From 495c834ff08bd8bc6429045ffb2d6b11d8f2eec0 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 11 Feb 2015 17:34:37 +0000 Subject: [PATCH 48/61] Added "Trying wagtail" page --- docs/getting_started/index.rst | 1 + docs/getting_started/installation.rst | 50 --------------------- docs/getting_started/trying_wagtail.rst | 59 +++++++++++++++++++++++++ docs/index.rst | 2 + 4 files changed, 62 insertions(+), 50 deletions(-) create mode 100644 docs/getting_started/trying_wagtail.rst diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst index 239df37e10..8b72c02069 100644 --- a/docs/getting_started/index.rst +++ b/docs/getting_started/index.rst @@ -5,6 +5,7 @@ Getting started .. toctree:: :maxdepth: 2 + trying_wagtail installation creating_your_project using_vagrant diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index 0628f13adf..9fd94f43e3 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -60,53 +60,3 @@ To enable ElasticSearch for your project, uncomment the ``elasticsearch`` line f Image feature detection ----------------------- Wagtail can use the OpenCV computer vision library to detect faces and other features in images, and use this information to select the most appropriate centre point when cropping the image. OpenCV is pre-installed as part of the Vagrant virtual machine image, and Vagrant users can enable this by setting ``WAGTAILIMAGES_FEATURE_DETECTION_ENABLED`` to True in ``myprojectname/settings/base.py``. For installation outside of Vagrant, see :ref:`image_feature_detection`. - - -Alternative installation methods -================================ - -Ubuntu ------- - -If you have a fresh instance of Ubuntu 13.04 or later, you can install Wagtail, -along with a demonstration site containing a set of standard templates and page -types, in one step. As the root user:: - - curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/ubuntu.sh; bash ubuntu.sh - -This script installs all the dependencies for a production-ready Wagtail site, -including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We -recommend you check through the script before running it, and adapt it according -to your deployment preferences. The canonical version is at -`github.com/torchbox/wagtail/blob/master/scripts/install/ubuntu.sh -`_. - - -Debian ------- - -If you have a fresh instance of Debian 7, you can install Wagtail, along with a -demonstration site containing a set of standard templates and page types, in one -step. As the root user:: - - curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/debian.sh; bash debian.sh - -This script installs all the dependencies for a production-ready Wagtail site, -including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We -recommend you check through the script before running it, and adapt it according -to your deployment preferences. The canonical version is at -`github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh -`_. - - -Docker ------- - -`@oyvindsk `_ has built a Dockerfile for the Wagtail demo. Simply run:: - - docker run -p 8000:8000 -d oyvindsk/wagtail-demo - -then access the site at http://your-ip:8000 and the admin -interface at http://your-ip:8000/admin using admin / test. - -See https://index.docker.io/u/oyvindsk/wagtail-demo/ for more details. diff --git a/docs/getting_started/trying_wagtail.rst b/docs/getting_started/trying_wagtail.rst new file mode 100644 index 0000000000..93d5ed0779 --- /dev/null +++ b/docs/getting_started/trying_wagtail.rst @@ -0,0 +1,59 @@ +============== +Trying Wagtail +============== + + +Wagtail demo +============ + + + +One line install +================ + + +Ubuntu +------ + +If you have a fresh instance of Ubuntu 13.04 or later, you can install Wagtail, +along with a demonstration site containing a set of standard templates and page +types, in one step. As the root user:: + + curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/ubuntu.sh; bash ubuntu.sh + +This script installs all the dependencies for a production-ready Wagtail site, +including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We +recommend you check through the script before running it, and adapt it according +to your deployment preferences. The canonical version is at +`github.com/torchbox/wagtail/blob/master/scripts/install/ubuntu.sh +`_. + + +Debian +------ + +If you have a fresh instance of Debian 7, you can install Wagtail, along with a +demonstration site containing a set of standard templates and page types, in one +step. As the root user:: + + curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/debian.sh; bash debian.sh + +This script installs all the dependencies for a production-ready Wagtail site, +including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We +recommend you check through the script before running it, and adapt it according +to your deployment preferences. The canonical version is at +`github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh +`_. + + +Docker +====== + +`@oyvindsk `_ has built a Dockerfile for the Wagtail demo. Simply run:: + + docker run -p 8000:8000 -d oyvindsk/wagtail-demo + +then access the site at http://your-ip:8000 and the admin +interface at http://your-ip:8000/admin using admin / test. + +See https://index.docker.io/u/oyvindsk/wagtail-demo/ for more details. diff --git a/docs/index.rst b/docs/index.rst index 05fe57ce00..1f99d42eaf 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,6 +8,8 @@ Below are some useful links to help you get started with Wagtail. * **First steps** + :doc:`getting_started/trying_wagtail` + :doc:`getting_started/installation` :doc:`getting_started/creating_your_project` From 88753e4370d1c721b3f433a02e6d34b923893c59 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 11 Feb 2015 17:55:35 +0000 Subject: [PATCH 49/61] Installation docs --- .../getting_started/creating_your_project.rst | 3 +- docs/getting_started/installation.rst | 34 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/docs/getting_started/creating_your_project.rst b/docs/getting_started/creating_your_project.rst index 322218223d..6dd60700ef 100644 --- a/docs/getting_started/creating_your_project.rst +++ b/docs/getting_started/creating_your_project.rst @@ -2,8 +2,7 @@ Starting your first project =========================== -Once you've installed Wagtail, you are ready start your first project. - +Once you've installed Wagtail, you are ready start your first project. Wagtail projects are ordinary Django projects with a few extra apps installed. Wagtail provides a command to get you started called ``wagtail start``. Open up a command line shell in your project folder and type: diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index 9fd94f43e3..3714f5bc33 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -14,14 +14,44 @@ Whether you just want to try out the demo site, or you're ready to dive in and c Install Python ============== -We recommend installing Python 3.4, but Wagtail also works with Python 2.7 and 3.3. +If you haven't got Python installed yet, we recommend installing Python 3.4. You can find the download for it here: https://www.python.org/downloads/ +pip +--- + +Python 3.4 has this built in. If you are using Python 2.7 or 3.3, you will have to install PIP separately + +See: https://pip.pypa.io/en/latest/installing.html + + +Virtual environments +-------------------- + +Python 3.3 and 3.4 has this built in. If you are using Python 2.7 you will have to install the ``virtualenv`` package from pip: + +.. code-block:: bash + + pip install virtualenv + Install Wagtail =============== -``pip install wagtail`` +Wagtail is available as a pip-installable package. To get the latest stable version: + +.. code-block:: bash + + pip install wagtail + + +To check that Wagtail can be seen by Python. Type ``python`` in your shell then try to import ``wagtail`` from the prompt: + +.. code-block:: python + + >>> import wagtail + >>> print(wagtail.get_version()) + 0.9 Optional extras From f52203ec39c6e70494faf725891d0ffce6cf228b Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Thu, 12 Feb 2015 09:01:37 +0000 Subject: [PATCH 50/61] Added wagtaildemo section back --- .../getting_started/creating_your_project.rst | 2 -- docs/getting_started/installation.rst | 2 -- docs/getting_started/trying_wagtail.rst | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/getting_started/creating_your_project.rst b/docs/getting_started/creating_your_project.rst index 6dd60700ef..83cb54014f 100644 --- a/docs/getting_started/creating_your_project.rst +++ b/docs/getting_started/creating_your_project.rst @@ -78,6 +78,4 @@ Firstly, open up a command line shell in your new projects directory. Using Vagrant ------------- -TODO - :doc:`using_vagrant` diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index 3714f5bc33..a3bc9f4648 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -50,8 +50,6 @@ To check that Wagtail can be seen by Python. Type ``python`` in your shell then .. code-block:: python >>> import wagtail - >>> print(wagtail.get_version()) - 0.9 Optional extras diff --git a/docs/getting_started/trying_wagtail.rst b/docs/getting_started/trying_wagtail.rst index 93d5ed0779..a277936f7b 100644 --- a/docs/getting_started/trying_wagtail.rst +++ b/docs/getting_started/trying_wagtail.rst @@ -6,6 +6,25 @@ Trying Wagtail Wagtail demo ============ +We provide a demo site containing a set of standard templates and page types - if you're new to Wagtail, this is the best way to try it out and familiarise yourself with how Wagtail works from the point of view of an editor. + +If you're happy to use Vagrant, and you just want to set up the Wagtail demo site, or any other pre-existing Wagtail site that ships with Vagrant support, you don't need to install Wagtail at all. Install `Vagrant `__ and `VirtualBox `__, and run:: + + git clone https://github.com/torchbox/wagtaildemo.git + cd wagtaildemo + vagrant up + vagrant ssh + + +Then, within the SSH session:: + + ./manage.py createsuperuser + ./manage.py runserver 0.0.0.0:8000 + + +This will make the demo site available on your host machine at the URL http://localhost:8111/ - you can access the Wagtail admin interface at http://localhost:8111/admin/ . Further instructions can be found at :ref:`editor_manual`. + +Once you’ve experimented with the demo site and are ready to build your own site, it's time to install Wagtail on your host machine. Even if you intend to do all further Wagtail work within Vagrant, installing the Wagtail package on your host machine will provide the ``wagtail start`` command that sets up the initial file structure for your project. One line install From e6da637256201a4a04e65fb00127373eb19f5995 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 16 Feb 2015 10:28:39 +0000 Subject: [PATCH 51/61] Changed ports to 8000 --- docs/getting_started/trying_wagtail.rst | 2 +- docs/getting_started/using_vagrant.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting_started/trying_wagtail.rst b/docs/getting_started/trying_wagtail.rst index a277936f7b..ac65413121 100644 --- a/docs/getting_started/trying_wagtail.rst +++ b/docs/getting_started/trying_wagtail.rst @@ -22,7 +22,7 @@ Then, within the SSH session:: ./manage.py runserver 0.0.0.0:8000 -This will make the demo site available on your host machine at the URL http://localhost:8111/ - you can access the Wagtail admin interface at http://localhost:8111/admin/ . Further instructions can be found at :ref:`editor_manual`. +This will make the demo site available on your host machine at the URL http://localhost:8000/ - you can access the Wagtail admin interface at http://localhost:8000/admin/ . Further instructions can be found at :ref:`editor_manual`. Once you’ve experimented with the demo site and are ready to build your own site, it's time to install Wagtail on your host machine. Even if you intend to do all further Wagtail work within Vagrant, installing the Wagtail package on your host machine will provide the ``wagtail start`` command that sets up the initial file structure for your project. diff --git a/docs/getting_started/using_vagrant.rst b/docs/getting_started/using_vagrant.rst index d04c755d96..760d0644b2 100644 --- a/docs/getting_started/using_vagrant.rst +++ b/docs/getting_started/using_vagrant.rst @@ -15,9 +15,9 @@ To setup the Vagrant box, run the following commands djrun -If you now visit http://localhost:8111 you should see a very basic "Welcome to your new Wagtail site!" page. +If you now visit http://localhost:8000 you should see a very basic "Welcome to your new Wagtail site!" page. -You can browse the Wagtail admin interface at: http://localhost:8111/admin +You can browse the Wagtail admin interface at: http://localhost:8000/admin You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/ @@ -34,4 +34,4 @@ You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/ ``djrun`` - This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8111`` (note that the port number gets changed by Vagrant) + This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8000`` (note that the port number gets changed by Vagrant) From b73404214009151b4a7d4c817c5024190bf37a6c Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 13:39:47 +0000 Subject: [PATCH 52/61] Unit test for #917 --- .../wagtailadmin/tests/test_page_chooser.py | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/wagtail/wagtailadmin/tests/test_page_chooser.py b/wagtail/wagtailadmin/tests/test_page_chooser.py index 475e4f7b19..834acde8cf 100644 --- a/wagtail/wagtailadmin/tests/test_page_chooser.py +++ b/wagtail/wagtailadmin/tests/test_page_chooser.py @@ -101,9 +101,24 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils): self.assertEqual(self.get({'prompt_for_link_text': 'foo'}).status_code, 200) def test_create_link(self): - request = self.post({'url': 'http://www.example.com'}) - self.assertContains(request, "'url': 'http://www.example.com/',") - self.assertContains(request, "'title': 'http://www.example.com/'") + response = self.post({'url': 'http://www.example.com'}) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "'onload'") # indicates success / post back to calling page + self.assertContains(response, "'url': 'http://www.example.com/',") + self.assertContains(response, "'title': 'http://www.example.com/'") + + def test_invalid_url(self): + response = self.post({'url': 'ntp://www.example.com'}) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "'html'") # indicates failure / show error message + self.assertContains(response, "Enter a valid URL.") + + def test_allow_local_url(self): + response = self.post({'url': '/admin/'}) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "'onload'") # indicates success / post back to calling page + self.assertContains(response, "'url': '/admin/',") + self.assertContains(response, "'title': '/admin/'") class TestChooserEmailLink(TestCase, WagtailTestUtils): From c92102370203379be089c752b52af425e4ce3b16 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 13:49:01 +0000 Subject: [PATCH 53/61] release note for #917 --- CHANGELOG.txt | 1 + docs/releases/0.9.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 81e1235714..8cdf5ca0dd 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -23,6 +23,7 @@ Changelog * Page model fields without a FieldPanel are no longer displayed in the form * No longer need to specify the base model on InlinePanel definitions * The project template Vagrantfile now listens on port 8000 + * The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site (Eric Drechsel) 0.8.5 (xx.xx.20xx) diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index e265150aea..d0893095a8 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -32,6 +32,7 @@ Minor features * Page model fields without a FieldPanel are no longer displayed in the form * No longer need to specify the base model on InlinePanel definitions * The project template Vagrantfile now listens on port 8000 + * The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site Bug fixes From 77e99e951dfab77f942f9c87010a303f7d8d0ebf Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 13:51:14 +0000 Subject: [PATCH 54/61] fix italic vs code formatting mismatches --- docs/releases/0.9.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index d0893095a8..2482d718db 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -23,10 +23,10 @@ Minor features * Dropped Python 2.6 and 3.2 support * Dropped Elasticsearch 0.90.x support * Search view accepts "page" GET parameter in line with pagination - * Removed the dependency on `LOGIN_URL` and `LOGIN_REDIRECT_URL` settings + * Removed the dependency on ``LOGIN_URL`` and ``LOGIN_REDIRECT_URL`` settings * Password reset view names namespaced to wagtailadmin * Removed the need to add permission check on admin views (now automated) - * Reversing `django.contrib.auth.admin.login` will no longer lead to Wagtails login view (making it easier to have front end views) + * Reversing ``django.contrib.auth.admin.login`` will no longer lead to Wagtails login view (making it easier to have front end views) * Added cache-control headers to all admin views. This allows Varnish/Squid/CDN to run on vanilla settings in front of a Wagtail site * Added validation to prevent pages being created with only whitespace characters in their title fields * Page model fields without a FieldPanel are no longer displayed in the form From a62022d898a71a4f2032d2f9a91a0ebe9f149cda Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 15:03:49 +0000 Subject: [PATCH 55/61] allow non-digit chars (e.g. '-') in user IDs in URLs; fixes #565 --- wagtail/wagtailusers/tests.py | 11 +++++++++++ wagtail/wagtailusers/urls/users.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/wagtail/wagtailusers/tests.py b/wagtail/wagtailusers/tests.py index 510e1423b3..ca2719d547 100644 --- a/wagtail/wagtailusers/tests.py +++ b/wagtail/wagtailusers/tests.py @@ -16,6 +16,8 @@ from wagtail.wagtailcore.models import Page, GroupPagePermission class TestUserIndexView(TestCase, WagtailTestUtils): def setUp(self): + # create a user that should be visible in the listing + self.test_user = get_user_model().objects.create_user(username='testuser', email='testuser@email.com', password='password') self.login() def get(self, params={}): @@ -25,6 +27,15 @@ class TestUserIndexView(TestCase, WagtailTestUtils): response = self.get() self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'wagtailusers/users/index.html') + self.assertContains(response, 'testuser') + + def test_allows_negative_ids(self): + # see https://github.com/torchbox/wagtail/issues/565 + get_user_model().objects.create_user('guardian', 'guardian@example.com', 'gu@rd14n', id=-1) + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'testuser') + self.assertContains(response, 'guardian') def test_search(self): response = self.get({'q': "Hello"}) diff --git a/wagtail/wagtailusers/urls/users.py b/wagtail/wagtailusers/urls/users.py index 78487fc5ae..8ddd0a83de 100644 --- a/wagtail/wagtailusers/urls/users.py +++ b/wagtail/wagtailusers/urls/users.py @@ -4,5 +4,5 @@ from wagtail.wagtailusers.views import users urlpatterns = [ url(r'^$', users.index, name='wagtailusers_users_index'), url(r'^new/$', users.create, name='wagtailusers_users_create'), - url(r'^(\d+)/$', users.edit, name='wagtailusers_users_edit'), + url(r'^([^\/]+)/$', users.edit, name='wagtailusers_users_edit'), ] From 42a48b0085a103d5a9640d1d800a4d466afbf873 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 15:08:22 +0000 Subject: [PATCH 56/61] release note for 4068385 --- CHANGELOG.txt | 1 + docs/releases/0.8.5.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8cdf5ca0dd..3c9f5510d8 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -38,6 +38,7 @@ Changelog * Fix: When adding tags where there were none before, it is now possible to save a single tag with multiple words in it * Fix: richtext template tag no longer raises TypeError if None is passed into it (Alejandro Varas) * Fix: Serving documents now uses a streaming HTTP response and will no longer break Djangos cache middleware +* Fix: User admin area no longer fails in the presence of negative user IDs (as used by django-guardian's default settings) 0.8.4 (04.12.2014) ~~~~~~~~~~~~~~~~~~ diff --git a/docs/releases/0.8.5.rst b/docs/releases/0.8.5.rst index f5877583cc..db3a45c8cc 100644 --- a/docs/releases/0.8.5.rst +++ b/docs/releases/0.8.5.rst @@ -22,3 +22,4 @@ Bug fixes * When adding tags where there were none before, it is now possible to save a single tag with multiple words in it * ``richtext`` template tag no longer raises ``TypeError`` if ``None`` is passed into it * Serving documents now uses a streaming HTTP response and will no longer break Djangos cache middleware + * Fix: User admin area no longer fails in the presence of negative user IDs (as used by django-guardian's default settings) \ No newline at end of file From 77340cfe9580ec8510f4af9333cf1aba2d09e70b Mon Sep 17 00:00:00 2001 From: Dan Braghis Date: Thu, 12 Feb 2015 22:22:22 +0000 Subject: [PATCH 57/61] Add tests for the password reset emails --- .../wagtailadmin/tests/test_password_reset.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 wagtail/wagtailadmin/tests/test_password_reset.py diff --git a/wagtail/wagtailadmin/tests/test_password_reset.py b/wagtail/wagtailadmin/tests/test_password_reset.py new file mode 100644 index 0000000000..e0a1dd1b4a --- /dev/null +++ b/wagtail/wagtailadmin/tests/test_password_reset.py @@ -0,0 +1,33 @@ +from django.test import TestCase, override_settings +from django.core import mail + +from wagtail.tests.utils import WagtailTestUtils +from wagtail.wagtailcore.models import Site + + +class TestUserPasswordReset(TestCase, WagtailTestUtils): + fixtures = ['test.json'] + + # need to clear urlresolver caches before/after tests, because we override ROOT_URLCONF + # in some tests here + def setUp(self): + from django.core.urlresolvers import clear_url_caches + clear_url_caches() + + def tearDown(self): + from django.core.urlresolvers import clear_url_caches + clear_url_caches() + + @override_settings(ROOT_URLCONF="wagtail.wagtailadmin.urls") + def test_email_found_default_url(self): + response = self.client.post('/password_reset/', {'email': 'siteeditor@example.com'}) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + self.assertIn("testserver", mail.outbox[0].body) + + @override_settings(ROOT_URLCONF="wagtail.wagtailadmin.urls", BASE_URL='http://mysite.com') + def test_email_found_base_url(self): + response = self.client.post('/password_reset/', {'email': 'siteeditor@example.com'}) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + self.assertIn("mysite.com", mail.outbox[0].body) From 82cca64b2a9a25395b864ca2949050658952147e Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 18:31:17 +0000 Subject: [PATCH 58/61] Use BASE_URL in password reset email if available - fixes #841 --- .../templates/wagtailadmin/account/password_reset/email.txt | 4 ++-- wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/email.txt b/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/email.txt index b9b64d35e0..892a4b93d9 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/email.txt +++ b/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/email.txt @@ -1,3 +1,3 @@ -{% load i18n %} +{% load i18n wagtailadmin_tags %}{% base_url_setting as base_url %} {% trans "Please follow the link below to reset your password" %} -{{ protocol }}://{{ domain }}{% url 'wagtailadmin_password_reset_confirm' uidb64=uid token=token %} \ No newline at end of file +{% if base_url %}{{ base_url }}{% else %}{{ protocol }}://{{ domain }}{% endif %}{% url 'wagtailadmin_password_reset_confirm' uidb64=uid token=token %} \ No newline at end of file diff --git a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py index cb049d0e88..3b9302fce4 100644 --- a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py +++ b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py @@ -134,6 +134,11 @@ def usage_count_enabled(): return getattr(settings, 'WAGTAIL_USAGE_COUNT_ENABLED', False) +@register.assignment_tag +def base_url_setting(): + return getattr(settings, 'BASE_URL', None) + + class EscapeScriptNode(template.Node): TAG_NAME = 'escapescript' SCRIPT_RE = re.compile(r'<(-*)/script>') From 610ae217e6479cff12eb1a3c4e5c536d2affe207 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Tue, 17 Feb 2015 12:48:34 +0000 Subject: [PATCH 59/61] Removed Rect.get_key --- wagtail/wagtailimages/rect.py | 10 ---------- wagtail/wagtailimages/tests/tests.py | 4 ---- 2 files changed, 14 deletions(-) diff --git a/wagtail/wagtailimages/rect.py b/wagtail/wagtailimages/rect.py index cd56f4b0d3..a398df59a0 100644 --- a/wagtail/wagtailimages/rect.py +++ b/wagtail/wagtailimages/rect.py @@ -57,13 +57,3 @@ class Rect(object): x + width / 2, y + height / 2, ) - - - # DELETEME - def get_key(self): - return "%(x)d-%(y)d-%(width)dx%(height)d" % { - 'x': int(self.centroid_x), - 'y': int(self.centroid_y), - 'width': int(self.width), - 'height': int(self.height), - } diff --git a/wagtail/wagtailimages/tests/tests.py b/wagtail/wagtailimages/tests/tests.py index 6df1dba56b..2701ab1457 100644 --- a/wagtail/wagtailimages/tests/tests.py +++ b/wagtail/wagtailimages/tests/tests.py @@ -237,7 +237,3 @@ class TestRect(TestCase): def test_from_point(self): rect = Rect.from_point(100, 200, 50, 20) self.assertEqual(rect, Rect(75, 190, 125, 210)) - - def test_get_key(self): - rect = Rect(100, 150, 200, 250) - self.assertEqual(rect.get_key(), '150-200-100x100') From 1aa9bae6e8fed765d67f8563c98c15bd216a951a Mon Sep 17 00:00:00 2001 From: Dan Braghis Date: Tue, 17 Feb 2015 14:18:00 +0000 Subject: [PATCH 60/61] Add changelog and release notes for #997 --- CHANGELOG.txt | 2 +- docs/releases/0.9.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3c9f5510d8..708cb07637 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -24,7 +24,7 @@ Changelog * No longer need to specify the base model on InlinePanel definitions * The project template Vagrantfile now listens on port 8000 * The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site (Eric Drechsel) - + * Password reset emails now use the ``BASE_URL`` setting for the reset URL 0.8.5 (xx.xx.20xx) ~~~~~~~~~~~~~~~~~~ diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index 2482d718db..b7be93f673 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -33,6 +33,7 @@ Minor features * No longer need to specify the base model on InlinePanel definitions * The project template Vagrantfile now listens on port 8000 * The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site + * Password reset emails now use the ``BASE_URL`` setting for the reset URL Bug fixes From 7fabf23fae713d4954e490700a9d0e25de5dc6c2 Mon Sep 17 00:00:00 2001 From: Dan Braghis Date: Tue, 17 Feb 2015 14:41:02 +0000 Subject: [PATCH 61/61] Move changelog entry for 997 to 0.8.5 instead of 0.9 --- CHANGELOG.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 708cb07637..59ec712728 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -24,7 +24,6 @@ Changelog * No longer need to specify the base model on InlinePanel definitions * The project template Vagrantfile now listens on port 8000 * The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site (Eric Drechsel) - * Password reset emails now use the ``BASE_URL`` setting for the reset URL 0.8.5 (xx.xx.20xx) ~~~~~~~~~~~~~~~~~~ @@ -39,6 +38,7 @@ Changelog * Fix: richtext template tag no longer raises TypeError if None is passed into it (Alejandro Varas) * Fix: Serving documents now uses a streaming HTTP response and will no longer break Djangos cache middleware * Fix: User admin area no longer fails in the presence of negative user IDs (as used by django-guardian's default settings) +* Fix: Password reset emails now use the ``BASE_URL`` setting for the reset URL 0.8.4 (04.12.2014) ~~~~~~~~~~~~~~~~~~