Files
neuf-www/dnscms/dnscms/wagtail_hooks.py
T

67 lines
2.4 KiB
Python

from django.templatetags.static import static
from django.utils.html import format_html
from grapple.registry import registry as grapple_registry
from wagtail import hooks
from wagtail.models import Page
from wagtail.search.backends import get_search_backend
from dnscms.rich_text import register_button_link_feature
@hooks.register("register_rich_text_features")
def enable_additional_rich_text_features(features):
features.default_features.extend(["h5", "h6", "blockquote"])
@hooks.register("register_rich_text_features")
def register_button_link(features):
register_button_link_feature(features)
@hooks.register("register_schema_query")
def override_search_resolver(query_mixins):
"""
Override Grapple's `search` resolver. Two fixes vs. the upstream version:
1. Restrict pages to live + public so drafts and access-restricted pages
don't leak via the public API.
2. Run a single search across all `Page` subclasses (instead of iterating
per-model) so results are ranked by relevance across types rather than
grouped by content type. Specific instances are fetched in a second
bulk query and reordered to match the search ranking.
Documents and images are intentionally not searched. The upstream resolver
includes them, but the frontend search page only renders Page types and
discards everything else, so iterating those indexes is wasted work.
"""
if not grapple_registry.class_models:
return
class SearchOverrideMixin:
def resolve_search(self, info, **kwargs):
query = kwargs.get("query")
if not query:
return None
s = get_search_backend()
ranked = list(s.search(query, Page.objects.live().public()))
if not ranked:
return []
ids = [p.id for p in ranked]
specific_map = {p.id: p for p in Page.objects.filter(id__in=ids).specific()}
return [specific_map[i] for i in ids if i in specific_map]
query_mixins.insert(0, SearchOverrideMixin)
@hooks.register("construct_page_action_menu")
def make_publish_default_action(menu_items, request, context):
for index, item in enumerate(menu_items):
if item.name == "action-publish":
menu_items.pop(index)
menu_items.insert(0, item)
break
@hooks.register("insert_editor_js")
def editor_js():
return format_html('<script src="{}"></script>', static("js/page-editor.js"))