Merged in hotfix/MS-932-WagtailCustomization (pull request #147)
Hotfix/MS-932 WagtailCustomization
This commit is contained in:
commit
000192ba36
|
|
@ -1,6 +1,6 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from wagtail.admin.panels import FieldPanel
|
from wagtail.admin.panels import FieldPanel, TitleFieldPanel
|
||||||
from wagtail.fields import RichTextField, StreamField
|
from wagtail.fields import RichTextField, StreamField
|
||||||
from wagtail.images.blocks import ImageChooserBlock
|
from wagtail.images.blocks import ImageChooserBlock
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ class BasicKnowledge(StrictHierarchyPage):
|
||||||
)
|
)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel("title", classname="full title"),
|
TitleFieldPanel("title", classname="full title"),
|
||||||
FieldPanel("new_type"),
|
FieldPanel("new_type"),
|
||||||
FieldPanel("intro"),
|
FieldPanel("intro"),
|
||||||
FieldPanel("contents"),
|
FieldPanel("contents"),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList
|
from wagtail.admin.panels import TabbedInterface, ObjectList, TitleFieldPanel
|
||||||
|
|
||||||
from core.wagtail_utils import StrictHierarchyPage, get_default_settings
|
from core.wagtail_utils import StrictHierarchyPage, get_default_settings
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ class Book(StrictHierarchyPage):
|
||||||
verbose_name_plural = 'Bücher'
|
verbose_name_plural = 'Bücher'
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel('title', classname="full title")
|
TitleFieldPanel('title', classname="full title")
|
||||||
]
|
]
|
||||||
|
|
||||||
edit_handler = TabbedInterface([
|
edit_handler = TabbedInterface([
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList
|
from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList, TitleFieldPanel
|
||||||
|
|
||||||
from core.wagtail_utils import StrictHierarchyPage, get_default_settings
|
from core.wagtail_utils import StrictHierarchyPage, get_default_settings
|
||||||
from users.models import SchoolClass
|
from users.models import SchoolClass
|
||||||
|
|
@ -18,7 +18,7 @@ class Chapter(StrictHierarchyPage, GraphqlNodeMixin):
|
||||||
description = models.TextField(blank=True)
|
description = models.TextField(blank=True)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel("title", classname="full title"),
|
TitleFieldPanel("title", classname="full title"),
|
||||||
FieldPanel("description", classname="full description"),
|
FieldPanel("description", classname="full description"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from wagtail.admin.panels import (
|
||||||
FieldPanel,
|
FieldPanel,
|
||||||
TabbedInterface,
|
TabbedInterface,
|
||||||
ObjectList,
|
ObjectList,
|
||||||
|
TitleFieldPanel,
|
||||||
)
|
)
|
||||||
from wagtail.blocks import StreamBlock
|
from wagtail.blocks import StreamBlock
|
||||||
from wagtail.fields import StreamField
|
from wagtail.fields import StreamField
|
||||||
|
|
@ -140,7 +141,7 @@ class ContentBlock(StrictHierarchyPage, GraphqlNodeMixin):
|
||||||
type = models.CharField(max_length=100, choices=TYPE_CHOICES, default=NORMAL)
|
type = models.CharField(max_length=100, choices=TYPE_CHOICES, default=NORMAL)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel("title", classname="full title"),
|
TitleFieldPanel("title", classname="full title"),
|
||||||
FieldPanel("type"),
|
FieldPanel("type"),
|
||||||
FieldPanel("contents"),
|
FieldPanel("contents"),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
from django import forms
|
from core.constants import DEFAULT_RICH_TEXT_FEATURES
|
||||||
|
from core.wagtail_utils import StrictHierarchyPage, get_default_settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from wagtail.admin.forms import WagtailAdminPageForm
|
|
||||||
from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList
|
|
||||||
from wagtail.fields import RichTextField
|
|
||||||
|
|
||||||
from core.constants import DEFAULT_RICH_TEXT_FEATURES
|
|
||||||
from core.wagtail_utils import StrictHierarchyPage, get_default_settings
|
|
||||||
from users.models import SchoolClass
|
from users.models import SchoolClass
|
||||||
|
from wagtail.admin.panels import (
|
||||||
|
FieldPanel,
|
||||||
|
ObjectList,
|
||||||
|
TabbedInterface,
|
||||||
|
TitleFieldPanel,
|
||||||
|
)
|
||||||
|
from wagtail.fields import RichTextField
|
||||||
|
|
||||||
EXACT = "exact"
|
EXACT = "exact"
|
||||||
|
|
||||||
|
|
@ -51,20 +53,23 @@ class ModuleCategory(models.Model):
|
||||||
return f"{self.name}"
|
return f"{self.name}"
|
||||||
|
|
||||||
|
|
||||||
class ModulePageForm(WagtailAdminPageForm):
|
# Commented out since that check is not necessary if a slug is chosen that is already in use
|
||||||
def clean(self):
|
# a new one will be generated
|
||||||
cleaned_data = super().clean()
|
# TODO: remove after pullrequest is merged
|
||||||
if "slug" in self.cleaned_data:
|
# class ModulePageForm(WagtailAdminPageForm):
|
||||||
page_slug = cleaned_data["slug"]
|
# def clean(self):
|
||||||
if not Module._slug_is_available(page_slug, self.instance):
|
# cleaned_data = super().clean()
|
||||||
self.add_error(
|
# if "slug" in self.cleaned_data and "id" in self.cleaned_data:
|
||||||
"slug",
|
# page_slug = cleaned_data["slug"]
|
||||||
forms.ValidationError(
|
# if not Module._slug_is_available(page_slug, self.parent_page, self.instance):
|
||||||
_("The slug '%(page_slug)s' is already in use")
|
# self.add_error(
|
||||||
% {"page_slug": page_slug}
|
# "slug",
|
||||||
),
|
# forms.ValidationError(
|
||||||
)
|
# _("The slug '%(page_slug)s' is already in use")
|
||||||
return cleaned_data
|
# % {"page_slug": page_slug}
|
||||||
|
# ),
|
||||||
|
# )
|
||||||
|
# return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
class Module(StrictHierarchyPage):
|
class Module(StrictHierarchyPage):
|
||||||
|
|
@ -97,7 +102,7 @@ class Module(StrictHierarchyPage):
|
||||||
solutions_enabled_for = models.ManyToManyField(SchoolClass)
|
solutions_enabled_for = models.ManyToManyField(SchoolClass)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel("title", classname="full title"),
|
TitleFieldPanel("title", classname="full title"),
|
||||||
FieldPanel("meta_title", classname="full title"),
|
FieldPanel("meta_title", classname="full title"),
|
||||||
FieldPanel("level"),
|
FieldPanel("level"),
|
||||||
FieldPanel("category"),
|
FieldPanel("category"),
|
||||||
|
|
@ -106,7 +111,8 @@ class Module(StrictHierarchyPage):
|
||||||
FieldPanel("teaser"),
|
FieldPanel("teaser"),
|
||||||
FieldPanel("intro"),
|
FieldPanel("intro"),
|
||||||
]
|
]
|
||||||
base_form_class = ModulePageForm
|
# TODO remove after pullrequest is merged
|
||||||
|
# base_form_class = ModulePageForm
|
||||||
|
|
||||||
edit_handler = TabbedInterface(
|
edit_handler = TabbedInterface(
|
||||||
[ObjectList(content_panels, heading="Content"), get_default_settings()]
|
[ObjectList(content_panels, heading="Content"), get_default_settings()]
|
||||||
|
|
@ -181,11 +187,44 @@ class Module(StrictHierarchyPage):
|
||||||
return f"{self.meta_title} - {self.title}"
|
return f"{self.meta_title} - {self.title}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _slug_is_available(slug, page):
|
def _slug_is_available(slug, parent_page, page=None):
|
||||||
# modeled after `Page._slug_is_available`
|
"""
|
||||||
modules = Module.objects.filter(slug=slug).not_page(page)
|
|
||||||
|
|
||||||
return not modules.exists()
|
# modeled after `Page._slug_is_available`
|
||||||
|
|
||||||
|
Determine whether the given slug is available for use on a child page of
|
||||||
|
parent_page. If 'page' is passed, the slug is intended for use on that page
|
||||||
|
(and so it will be excluded from the duplicate check).
|
||||||
|
"""
|
||||||
|
if parent_page is None:
|
||||||
|
# the root page's slug can be whatever it likes...
|
||||||
|
return True
|
||||||
|
|
||||||
|
modules = Module.objects.all()
|
||||||
|
if page:
|
||||||
|
modules = modules.not_page(page)
|
||||||
|
|
||||||
|
return not modules.filter(slug=slug).exists()
|
||||||
|
|
||||||
|
def _get_autogenerated_slug(self, base_slug):
|
||||||
|
# modeled after `Page._get_autogenerated_slug`
|
||||||
|
candidate_slug = base_slug
|
||||||
|
suffix = 1
|
||||||
|
parent_page = self.get_parent()
|
||||||
|
|
||||||
|
while not self._slug_is_available(candidate_slug, parent_page, self):
|
||||||
|
# try with incrementing suffix until we find a slug which is available
|
||||||
|
suffix += 1
|
||||||
|
candidate_slug = "%s-%d" % (base_slug, suffix)
|
||||||
|
return candidate_slug
|
||||||
|
|
||||||
|
def full_clean(self, *args, **kwargs):
|
||||||
|
super().full_clean(*args, **kwargs)
|
||||||
|
|
||||||
|
# Always create a slug if it is not available
|
||||||
|
# todo: do we really want to do this? this will silently change a slug if the users sets one that already exists, which probably isn't what they expect
|
||||||
|
if not self._slug_is_available(self.slug, self.get_parent(), self):
|
||||||
|
self.slug = self._get_autogenerated_slug(self.slug)
|
||||||
|
|
||||||
|
|
||||||
class RecentModule(models.Model):
|
class RecentModule(models.Model):
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList
|
from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList, TitleFieldPanel
|
||||||
from wagtail.fields import RichTextField
|
from wagtail.fields import RichTextField
|
||||||
|
|
||||||
from core.constants import DEFAULT_RICH_TEXT_FEATURES
|
from core.constants import DEFAULT_RICH_TEXT_FEATURES
|
||||||
|
|
@ -22,7 +22,7 @@ class Topic(StrictHierarchyPage):
|
||||||
instructions = models.CharField(max_length=255, blank=True, null=True, default=None)
|
instructions = models.CharField(max_length=255, blank=True, null=True, default=None)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel('title', classname="full title"),
|
TitleFieldPanel('title', classname="full title"),
|
||||||
FieldPanel('order'),
|
FieldPanel('order'),
|
||||||
FieldPanel('teaser'),
|
FieldPanel('teaser'),
|
||||||
FieldPanel('vimeo_id'),
|
FieldPanel('vimeo_id'),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
from books.factories import ModuleFactory
|
||||||
|
from books.models import Chapter
|
||||||
|
from core.tests.base_test import SkillboxTestCase
|
||||||
|
from django.test.client import Client
|
||||||
|
|
||||||
|
|
||||||
|
class TestChapterCreation(SkillboxTestCase):
|
||||||
|
"""Test created for Issue MS-932"""
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.createDefault()
|
||||||
|
self.module = ModuleFactory(slug="my-module")
|
||||||
|
self.Client = Client()
|
||||||
|
self.client.login(username="admin", password="test")
|
||||||
|
|
||||||
|
def test_create_chapter_creates_slug_automatically(self):
|
||||||
|
new_chapter = Chapter(title="New Chapter")
|
||||||
|
self.module.add_child(instance=new_chapter)
|
||||||
|
new_chapter.save()
|
||||||
|
self.assertEqual("new-chapter", new_chapter.slug)
|
||||||
|
|
||||||
|
def test_create_chapter_creates_slug_automatically_if_existing(self):
|
||||||
|
new_chapter = Chapter(title="New Chapter")
|
||||||
|
self.module.add_child(instance=new_chapter)
|
||||||
|
new_chapter.save()
|
||||||
|
self.assertEqual("new-chapter", new_chapter.slug)
|
||||||
|
new_chapter2 = Chapter(title="New Chapter")
|
||||||
|
self.module.add_child(instance=new_chapter2)
|
||||||
|
new_chapter2.save()
|
||||||
|
self.assertEqual("new-chapter-2", new_chapter2.slug)
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
from django.test import TestCase, RequestFactory
|
||||||
|
from unittest import skip
|
||||||
|
from graphene.test import Client
|
||||||
|
from graphql_relay import to_global_id
|
||||||
|
|
||||||
|
from api.schema import schema
|
||||||
|
from api.utils import get_object
|
||||||
|
from books.models import ContentBlock, Chapter
|
||||||
|
from books.factories import ModuleFactory, ModuleLevelFactory, TopicFactory
|
||||||
|
from core.factories import UserFactory
|
||||||
|
from users.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestModuleCreation(TestCase):
|
||||||
|
"""
|
||||||
|
Since the modules url in the frontend is not /topic/module but /module the slug has to be unique.
|
||||||
|
This test checks if the slug is generated correctly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_create_new_module_generates_slug(self):
|
||||||
|
topic = TopicFactory(title="Berufslehre")
|
||||||
|
module = ModuleFactory(title="Modul 1", parent=topic)
|
||||||
|
self.assertEqual("modul-1", module.slug)
|
||||||
|
|
||||||
|
def test_create_new_module_different_topic(self):
|
||||||
|
topic = TopicFactory(title="Berufslehre")
|
||||||
|
module = ModuleFactory(title="Modul 1", parent=topic)
|
||||||
|
|
||||||
|
topic2 = TopicFactory(title="Geld und Macht")
|
||||||
|
module2 = ModuleFactory(title="Modul 1", parent=topic2)
|
||||||
|
self.assertEqual("modul-1", module.slug)
|
||||||
|
self.assertEqual("modul-1-2", module2.slug, )
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
{# This template is overwritten to create a custom cms ui for the model "chapter" to improve navigation experience.#}
|
|
||||||
{# See MS-538#}
|
|
||||||
|
|
||||||
{% load i18n %}
|
|
||||||
{% load l10n %}
|
|
||||||
{% load wagtailadmin_tags %}
|
|
||||||
<table class="listing {% if full_width %}full-width{% endif %} {% block table_classname %}{% endblock %}">
|
|
||||||
{% if show_ordering_column or show_bulk_actions %}
|
|
||||||
<col width="10px"/>
|
|
||||||
{% endif %}
|
|
||||||
<col/>
|
|
||||||
{% if show_parent %}
|
|
||||||
<col/>
|
|
||||||
{% endif %}
|
|
||||||
<col width="12%"/>
|
|
||||||
<col width="12%"/>
|
|
||||||
<col width="12%"/>
|
|
||||||
<col width="10%"/>
|
|
||||||
<thead>
|
|
||||||
{% block pre_parent_page_headers %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% if parent_page %}
|
|
||||||
{% page_permissions parent_page as parent_page_perms %}
|
|
||||||
<tr class="index {% if not parent_page.live %} unpublished{% endif %}
|
|
||||||
{% block parent_page_row_classname %}{% endblock %}">
|
|
||||||
<td class="title"{% if show_ordering_column or show_bulk_actions %} colspan="2"{% endif %}>
|
|
||||||
{% block parent_page_title %}
|
|
||||||
{% endblock %}
|
|
||||||
</td>
|
|
||||||
<td class="updated" valign="bottom">{% if parent_page.latest_revision_created_at %}
|
|
||||||
<div class="human-readable-date"
|
|
||||||
title="{{ parent_page.latest_revision_created_at|date:"DATETIME_FORMAT" }}">
|
|
||||||
{% blocktrans with time_period=parent_page.latest_revision_created_at|timesince %}{{ time_period }}
|
|
||||||
ago{% endblocktrans %}</div>{% endif %}</td>
|
|
||||||
<td class="type" valign="bottom">
|
|
||||||
{% if not parent_page.is_root %}
|
|
||||||
{{ parent_page.content_type.model_class.get_verbose_name }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td class="status" valign="bottom">
|
|
||||||
{% if not parent_page.is_root %}
|
|
||||||
{% include "wagtailadmin/shared/page_status_tag.html" with page=parent_page %}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% block post_parent_page_headers %}
|
|
||||||
{% endblock %}
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% if pages %}
|
|
||||||
{% trans "Select page" as checkbox_aria_label %}
|
|
||||||
{% for page in pages %}
|
|
||||||
{% page_permissions page as page_perms %}
|
|
||||||
<tr {% if ordering == "ord" %}id="page_{{ page.id|unlocalize }}"
|
|
||||||
data-page-title="{{ page.get_admin_display_title }}"{% endif %}
|
|
||||||
class="{% if not page.live %}unpublished{% endif %} {% block page_row_classname %}{% endblock %}">
|
|
||||||
{% if show_ordering_column %}
|
|
||||||
<td class="ord">{% if orderable and ordering == "ord" %}
|
|
||||||
<div class="handle icon icon-grip text-replace">{% trans 'Drag' %}</div>{% endif %}</td>
|
|
||||||
{% elif show_bulk_actions %}
|
|
||||||
{% include "wagtailadmin/bulk_actions/listing_checkbox_cell.html" with obj_type="page" obj=page aria_labelledby_prefix="page_" aria_labelledby=page.pk|unlocalize aria_labelledby_suffix="_title" %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<td id="page_{{ page.pk|unlocalize }}_title" class="title" valign="top" data-listing-page-title>
|
|
||||||
|
|
||||||
{% block page_title %}
|
|
||||||
{% endblock %}
|
|
||||||
{% if page.content_type.model == 'chapter' %}
|
|
||||||
<div style="margin-top:10px; padding-left: 30px">
|
|
||||||
<ul>
|
|
||||||
{% for c in page.get_children %}
|
|
||||||
{% if not c.specific.user_created and not c.specific.contentblocksnapshot %}
|
|
||||||
<li>
|
|
||||||
{% if page_perms.can_edit %}
|
|
||||||
<a href="{% url 'wagtailadmin_pages:edit' c.id %}"
|
|
||||||
title="{% trans 'Edit this page' %}"> {{ c.get_admin_display_title }}
|
|
||||||
</a>
|
|
||||||
{% else %}
|
|
||||||
{{ c.get_admin_display_title }}
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
{% if show_parent %}
|
|
||||||
<td class="parent" valign="top">
|
|
||||||
{% block page_parent_page_title %}
|
|
||||||
{% with page.get_parent as parent %}
|
|
||||||
{% if parent %}
|
|
||||||
<a href="{% url 'wagtailadmin_explore' parent.id %}">{{ parent.specific_deferred.get_admin_display_title }}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endblock %}
|
|
||||||
</td>
|
|
||||||
{% endif %}
|
|
||||||
<td class="updated" valign="top">{% if page.latest_revision_created_at %}
|
|
||||||
<div class="human-readable-date"
|
|
||||||
title="{{ page.latest_revision_created_at|date:"DATETIME_FORMAT" }}">
|
|
||||||
{% blocktrans with time_period=page.latest_revision_created_at|timesince %}{{ time_period }}
|
|
||||||
ago{% endblocktrans %}</div>{% endif %}</td>
|
|
||||||
<td class="type" valign="top">{{ page.content_type.model_class.get_verbose_name }}</td>
|
|
||||||
<td class="status" valign="top">
|
|
||||||
{% include "wagtailadmin/shared/page_status_tag.html" with page=page %}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
|
|
||||||
{% block page_navigation %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
{% block no_results %}{% endblock %}
|
|
||||||
{% endif %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
{% load i18n wagtailadmin_tags %}
|
||||||
|
|
||||||
|
{# The title field for a page in the page listing, when in 'explore' mode #}
|
||||||
|
|
||||||
|
<div class="title-wrapper">
|
||||||
|
{% if page.is_site_root %}
|
||||||
|
{% if perms.wagtailcore.add_site or perms.wagtailcore.change_site or perms.wagtailcore.delete_site %}
|
||||||
|
<a href="{% url 'wagtailsites:index' %}" title="{% trans 'Sites menu' %}">{% icon name="site" classname="initial"
|
||||||
|
%}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if page_perms.can_edit %}
|
||||||
|
<a href="{% url 'wagtailadmin_pages:edit' page.id %}" title="{% trans 'Edit this page' %}">
|
||||||
|
{% if not page.is_site_root and not page.is_leaf %}{% icon name="folder" classname="initial" %}{% endif %}
|
||||||
|
{{ page.get_admin_display_title }}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{% if not page.is_site_root and not page.is_leaf %}{% icon name="folder" classname="initial" %}{% endif %}
|
||||||
|
{{ page.get_admin_display_title }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if show_locale_labels %}
|
||||||
|
{% status page.locale.get_display_name classname="w-status--label" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% include "wagtailadmin/pages/listing/_privacy_indicator.html" with page=page %}
|
||||||
|
{% include "wagtailadmin/pages/listing/_locked_indicator.html" with page=page %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="actions">
|
||||||
|
{% page_listing_buttons page request.user next_url=actions_next_url %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Here starts the customization part. -->
|
||||||
|
<!--Commit: 3c5c9422353964aa25cdd04b296859f71c4c1a34-->
|
||||||
|
{% if page.content_type.model == 'chapter' %}
|
||||||
|
<div style="margin-top:10px; padding-left: 30px">
|
||||||
|
<ul>
|
||||||
|
{% for c in page.get_children %}
|
||||||
|
{% if not c.specific.user_created and not c.specific.contentblocksnapshot %}
|
||||||
|
<li>
|
||||||
|
{% if page_perms.can_edit %}
|
||||||
|
<a href="{% url 'wagtailadmin_pages:edit' c.id %}"
|
||||||
|
title="{% trans 'Edit this page' %}"> {{ c.get_admin_display_title }}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{{ c.get_admin_display_title }}
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
@ -2,6 +2,7 @@ from django.contrib import admin
|
||||||
from wagtail.admin.panels import CommentPanel
|
from wagtail.admin.panels import CommentPanel
|
||||||
from wagtail.admin.panels import FieldPanel, ObjectList
|
from wagtail.admin.panels import FieldPanel, ObjectList
|
||||||
from wagtail.models import Page
|
from wagtail.models import Page
|
||||||
|
from wagtail.admin.widgets.slug import SlugInput
|
||||||
|
|
||||||
|
|
||||||
class StrictHierarchyPage(Page):
|
class StrictHierarchyPage(Page):
|
||||||
|
|
@ -41,4 +42,4 @@ def wagtail_parent_filter(parent_cls, child_cls):
|
||||||
|
|
||||||
|
|
||||||
def get_default_settings():
|
def get_default_settings():
|
||||||
return ObjectList([FieldPanel("slug"), CommentPanel()], heading="Settings")
|
return ObjectList([FieldPanel("slug", widget=SlugInput), CommentPanel()], heading="Settings")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue