Merge pull request #1022 from gasman/feature/custom-page-edit-handler

Allow specifying custom edit handlers for pages - fixes #210
This commit is contained in:
Dan Braghis 2015-02-27 14:41:45 +00:00
commit 096a24648d
4 changed files with 86 additions and 6 deletions

View file

@ -376,6 +376,40 @@ For more on ``django-modelcluster``, visit `the django-modelcluster github proje
.. _the django-modelcluster github project page: https://github.com/torchbox/django-modelcluster
.. _customising_the_tabbed_interface:
Customising the tabbed interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 0.9
As standard, Wagtail organises panels into three tabs: 'Content', 'Promote' and 'Settings'. Depending on the requirements of your site, you may wish to customise this for specific page types - for example, adding an additional tab for sidebar content. This can be done by specifying an ``edit_handler`` property on the page model. For example:
.. code-block:: python
from wagtail.wagtailadmin.edit_handlers import TabbedInterface, ObjectList
class BlogPage(Page):
# field definitions omitted
BlogPage.content_panels = [
FieldPanel('title', classname="full title"),
FieldPanel('date'),
FieldPanel('body', classname="full"),
]
BlogPage.sidebar_content_panels = [
SnippetChooserPanel('advert', Advert),
InlinePanel('related_links', label="Related links"),
]
BlogPage.edit_handler = TabbedInterface([
ObjectList(BlogPage.content_panels, heading='Content'),
ObjectList(BlogPage.sidebar_content_panels, heading='Sidebar content'),
ObjectList(BlogPage.promote_panels, heading='Promote'),
ObjectList(BlogPage.settings_panels, heading='Settings', classname="settings"),
])
.. _extending_wysiwyg:
Extending the WYSIWYG Editor (hallo.js)

View file

@ -14,7 +14,7 @@ from modelcluster.tags import ClusterTaggableManager
from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, InlinePanel, PageChooserPanel
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, InlinePanel, PageChooserPanel, TabbedInterface, ObjectList
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel
from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField
@ -393,15 +393,27 @@ class StandardIndex(Page):
parent_page_types = []
# A custom panel setup where all Promote fields are placed in the Content tab instead;
# we use this to test that the 'promote' tab is left out of the output when empty
StandardIndex.content_panels = [
FieldPanel('title', classname="full title"),
FieldPanel('seo_title'),
FieldPanel('slug'),
InlinePanel('advert_placements', label="Adverts"),
]
StandardIndex.promote_panels = []
class StandardChild(Page):
pass
# Test overriding edit_handler with a custom one
StandardChild.edit_handler = TabbedInterface([
ObjectList(StandardChild.content_panels, heading='Content'),
ObjectList(StandardChild.promote_panels, heading='Promote'),
ObjectList(StandardChild.settings_panels, heading='Settings', classname='settings'),
ObjectList([], heading='Dinosaurs'),
])
class BusinessIndex(Page):
""" Can be placed anywhere, can only have Business children """

View file

@ -158,6 +158,27 @@ class TestPageCreation(TestCase, WagtailTestUtils):
def test_create_simplepage(self):
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<a href="#content" class="active">Content</a>')
self.assertContains(response, '<a href="#promote" class="">Promote</a>')
def test_create_page_without_promote_tab(self):
"""
Test that the Promote tab is not rendered for page classes that define it as empty
"""
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'standardindex', self.root_page.id)))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<a href="#content" class="active">Content</a>')
self.assertNotContains(response, '<a href="#promote" class="">Promote</a>')
def test_create_page_with_custom_tabs(self):
"""
Test that custom edit handlers are rendered
"""
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'standardchild', self.root_page.id)))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<a href="#content" class="active">Content</a>')
self.assertContains(response, '<a href="#promote" class="">Promote</a>')
self.assertContains(response, '<a href="#dinosaurs" class="">Dinosaurs</a>')
def test_create_simplepage_bad_permissions(self):
# Remove privileges from user

View file

@ -707,11 +707,24 @@ PAGE_EDIT_HANDLERS = {}
def get_page_edit_handler(page_class):
if page_class not in PAGE_EDIT_HANDLERS:
PAGE_EDIT_HANDLERS[page_class] = TabbedInterface([
ObjectList(page_class.content_panels, heading='Content'),
ObjectList(page_class.promote_panels, heading='Promote'),
ObjectList(page_class.settings_panels, heading='Settings', classname="settings")
]).bind_to_model(page_class)
if hasattr(page_class, 'edit_handler'):
# use the edit handler specified on the page class
edit_handler = page_class.edit_handler
else:
# construct a TabbedInterface made up of content_panels, promote_panels
# and settings_panels, skipping any which are empty
tabs = []
if page_class.content_panels:
tabs.append(ObjectList(page_class.content_panels, heading='Content'))
if page_class.promote_panels:
tabs.append(ObjectList(page_class.promote_panels, heading='Promote'))
if page_class.settings_panels:
tabs.append(ObjectList(page_class.settings_panels, heading='Settings', classname="settings"))
edit_handler = TabbedInterface(tabs)
PAGE_EDIT_HANDLERS[page_class] = edit_handler.bind_to_model(page_class)
return PAGE_EDIT_HANDLERS[page_class]