201 lines
7.1 KiB
Python
201 lines
7.1 KiB
Python
from django.db.models import ProtectedError
|
|
from django.shortcuts import redirect
|
|
from wagtail.admin import messages
|
|
import wagtail.admin.rich_text.editors.draftail.features as draftail_features
|
|
from wagtail.admin.rich_text.converters.html_to_contentstate import (
|
|
InlineStyleElementHandler,
|
|
)
|
|
from wagtail import hooks
|
|
from wagtail.admin.utils import get_valid_next_url_from_request
|
|
|
|
from basicknowledge.models import BasicKnowledge
|
|
from books.models import ContentBlockSnapshot
|
|
from books.models.chapter import Chapter
|
|
from books.models.contentblock import ContentBlock
|
|
from core.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
# 1. Use the register_rich_text_features hook.
|
|
@hooks.register("register_rich_text_features")
|
|
def register_brand_feature(features):
|
|
"""
|
|
Registering the feature, which uses the `BRAND` Draft.js inline style type,
|
|
and is stored as HTML with a `<span class="brand">` tag.
|
|
"""
|
|
feature_name = "brand"
|
|
type_ = "BRAND"
|
|
|
|
# 2. Configure how Draftail handles the feature in its toolbar.
|
|
control = {
|
|
"type": type_,
|
|
"label": "Grün",
|
|
"description": "Grün",
|
|
"style": {"color": "#17A887", "font-weight": "600"},
|
|
}
|
|
|
|
# 3. Call register_editor_plugin to register the configuration for Draftail.
|
|
features.register_editor_plugin(
|
|
"draftail", feature_name, draftail_features.InlineStyleFeature(control)
|
|
)
|
|
|
|
# 4.configure the content transform from the DB to the editor and back.
|
|
db_conversion = {
|
|
"from_database_format": {
|
|
'span[class="brand"]': InlineStyleElementHandler(type_)
|
|
},
|
|
"to_database_format": {"style_map": {type_: 'span class="brand""'}},
|
|
}
|
|
|
|
# 5. Call register_converter_rule to register the content transformation conversion.
|
|
features.register_converter_rule("contentstate", feature_name, db_conversion)
|
|
|
|
# 6. (optional) Add the feature to the default features list to make it available
|
|
# on rich text fields that do not specify an explicit 'features' list
|
|
features.default_features.append(feature_name)
|
|
|
|
|
|
@hooks.register("register_rich_text_features")
|
|
def register_secondary_feature(features):
|
|
"""
|
|
Registering the feature, which uses the `SECONDARY` Draft.js inline style type,
|
|
and is stored as HTML with a `<span class="secondary">` tag.
|
|
"""
|
|
feature_name = "secondary"
|
|
type_ = "SECONDARY"
|
|
|
|
# 2. Configure how Draftail handles the feature in its toolbar.
|
|
control = {
|
|
"type": type_,
|
|
"label": "Blau",
|
|
"description": "Blau",
|
|
"style": {"color": "#078CC6", "font-weight": "600"},
|
|
}
|
|
|
|
# 3. Call register_editor_plugin to register the configuration for Draftail.
|
|
features.register_editor_plugin(
|
|
"draftail", feature_name, draftail_features.InlineStyleFeature(control)
|
|
)
|
|
|
|
# 4.configure the content transform from the DB to the editor and back.
|
|
db_conversion = {
|
|
"from_database_format": {
|
|
'span[class="secondary"]': InlineStyleElementHandler(type_)
|
|
},
|
|
"to_database_format": {"style_map": {type_: 'span class="secondary"'}},
|
|
}
|
|
|
|
# 5. Call register_converter_rule to register the content transformation conversion.
|
|
features.register_converter_rule("contentstate", feature_name, db_conversion)
|
|
|
|
# 6. (optional) Add the feature to the default features list to make it available
|
|
# on rich text fields that do not specify an explicit 'features' list
|
|
features.default_features.append(feature_name)
|
|
|
|
|
|
@hooks.register("construct_explorer_page_queryset")
|
|
def remove_page_types_from_menu(parent_page, pages, request):
|
|
return (
|
|
pages.not_type(ContentBlockSnapshot)
|
|
.not_type(BasicKnowledge)
|
|
.exclude(contentblock__user_created=True)
|
|
)
|
|
|
|
|
|
@hooks.register("after_copy_page")
|
|
def after_copy_hook(request, page, new_page):
|
|
# todo: find every ContentBlock further down in the tree, see if there are any Surveys or Assignments and copy them and reassign them
|
|
if type(page.specific) == ContentBlock:
|
|
# logger.debug("It's a content block")
|
|
content_block: ContentBlock = new_page.specific
|
|
# logger.debug(f"duplicatin {content_block.title, content_block.pk}")
|
|
content_block.duplicate_attached_entities()
|
|
|
|
else:
|
|
# logger.debug(f"It's something else {type(page.specific)}, {ContentBlock}")
|
|
content_blocks = new_page.specific.get_content_blocks()
|
|
for content_block in content_blocks:
|
|
content_block.duplicate_attached_entities()
|
|
|
|
|
|
@hooks.register("after_move_page")
|
|
def after_move_hook(request, page):
|
|
logger.debug(f"after moving the page {page.title}")
|
|
if type(page.specific) == ContentBlock:
|
|
logger.debug("it's a content block")
|
|
page.specific.reassign_entities()
|
|
if type(page.specific) == Chapter:
|
|
logger.debug("it's a chapter")
|
|
content_blocks = page.specific.get_content_blocks()
|
|
logger.debug(page.id)
|
|
logger.debug(page.specific.get_content_blocks())
|
|
logger.debug(page.get_children())
|
|
for content_block in content_blocks:
|
|
content_block.reassign_entities()
|
|
|
|
|
|
@hooks.register("after_edit_page")
|
|
def after_edit_hook(request, page):
|
|
logger.debug(f"After edit page {page.title}, {type(page).__name__}")
|
|
|
|
|
|
@hooks.register("after_create_page")
|
|
def after_create_hook(request, page):
|
|
# reassign assignment and survey module
|
|
if type(page.specific) == ContentBlock:
|
|
content_block = page.specific
|
|
content_block.reassign_entities()
|
|
|
|
|
|
@hooks.register("before_delete_page")
|
|
def on_page_delete(request, page):
|
|
if request.method != "POST":
|
|
return
|
|
|
|
try:
|
|
next_url = get_valid_next_url_from_request(request)
|
|
parent_id = page.get_parent().id
|
|
page.delete()
|
|
|
|
messages.success(
|
|
request, ("Page '{0}' deleted.").format(page.get_admin_display_title())
|
|
)
|
|
|
|
for fn in hooks.get_hooks("after_delete_page"):
|
|
result = fn(request, page)
|
|
if hasattr(result, "status_code"):
|
|
return result
|
|
|
|
if next_url:
|
|
return redirect(next_url)
|
|
return redirect("wagtailadmin_explore", parent_id)
|
|
|
|
except ProtectedError as exc:
|
|
protected_objects = {}
|
|
for obj in exc.protected_objects:
|
|
model_name = obj._meta.verbose_name_plural
|
|
if model_name in protected_objects:
|
|
protected_objects[model_name].append(str(obj))
|
|
else:
|
|
protected_objects[model_name] = [str(obj)]
|
|
|
|
dependency_summary = []
|
|
for model_name, items in protected_objects.items():
|
|
if len(items) == 1:
|
|
items_summary = ("{0} ({1})").format(model_name, items[0])
|
|
else:
|
|
items_summary = ("{0} ({1} and {2} more...)").format(
|
|
model_name, items[0], len(items) - 1
|
|
)
|
|
|
|
dependency_summary.append(items_summary)
|
|
|
|
messages.error(
|
|
request,
|
|
("Page '{0}' cannot be deleted while it's used by {1}").format(
|
|
page.get_admin_display_title(), ", ".join(dependency_summary)
|
|
),
|
|
)
|
|
return redirect("wagtailadmin_pages:delete", page.id)
|