Implement get_model / get_instance on link/embed handlers

This commit is contained in:
Matt Westcott 2018-04-26 19:26:10 +01:00
parent 375ae00518
commit 986abd10ea
5 changed files with 84 additions and 14 deletions

View file

@ -1,3 +1,4 @@
from django.db.models import Model
from django.utils.safestring import mark_safe
from wagtail.core.rich_text.feature_registry import FeatureRegistry
@ -50,3 +51,41 @@ class RichText:
def __bool__(self):
return bool(self.source)
__nonzero__ = __bool__
class EntityHandler:
"""
An 'entity' is a placeholder tag within the saved rich text, which needs to be rewritten
into real HTML at the point of rendering. Typically (but not necessarily) the entity will
be a reference to a model to be fetched to have its data output into the rich text content
(so that we aren't storing potentially changeable data within the saved rich text).
An EntityHandler defines how this rewriting is performed.
Currently Wagtail supports two kinds of entity: links (represented as <a linktype="...">...</a>)
and embeds (represented as <embed embedtype="..." />).
"""
@staticmethod
def get_model():
return NotImplementedError
@classmethod
def get_instance(cls, attrs: dict) -> Model:
model = cls.get_model()
return model._default_manager.get(id=attrs['id'])
@staticmethod
def expand_db_attributes(attrs: dict) -> str:
"""
Given a dict of attributes from the entity tag
stored in the database, returns the real HTML representation.
"""
raise NotImplementedError
class LinkHandler(EntityHandler):
pass
class EmbedHandler(EntityHandler):
pass

View file

@ -1,13 +1,22 @@
from django.utils.html import escape
from wagtail.core.models import Page
from wagtail.core.rich_text import LinkHandler
class PageLinkHandler:
class PageLinkHandler(LinkHandler):
@staticmethod
def expand_db_attributes(attrs):
def get_model():
return Page
@classmethod
def get_instance(cls, attrs):
return super().get_instance(attrs).specific
@classmethod
def expand_db_attributes(cls, attrs):
try:
page = Page.objects.get(id=attrs['id'])
page = cls.get_instance(attrs)
return '<a href="%s">' % escape(page.specific.url)
except Page.DoesNotExist:
return "<a>"

View file

@ -1,16 +1,21 @@
from django.core.exceptions import ObjectDoesNotExist
from django.utils.html import escape
from wagtail.core.rich_text import LinkHandler
from wagtail.documents.models import get_document_model
# Front-end conversion
class DocumentLinkHandler:
class DocumentLinkHandler(LinkHandler):
@staticmethod
def expand_db_attributes(attrs):
Document = get_document_model()
def get_model():
return get_document_model()
@classmethod
def expand_db_attributes(cls, attrs):
try:
doc = Document.objects.get(id=attrs['id'])
doc = cls.get_instance(attrs)
return '<a href="%s">' % escape(doc.url)
except (Document.DoesNotExist, KeyError):
except (ObjectDoesNotExist, KeyError):
return "<a>"

View file

@ -1,9 +1,20 @@
from wagtail.core.rich_text import EmbedHandler
from wagtail.embeds import format
from wagtail.embeds.embeds import get_embed
from wagtail.embeds.models import Embed
# Front-end conversion
class MediaEmbedHandler:
class MediaEmbedHandler(EmbedHandler):
@staticmethod
def get_model():
return Embed
@staticmethod
def get_instance(attrs):
return get_embed(attrs['url'])
@staticmethod
def expand_db_attributes(attrs):
"""

View file

@ -1,20 +1,26 @@
from django.core.exceptions import ObjectDoesNotExist
from wagtail.core.rich_text import EmbedHandler
from wagtail.images import get_image_model
from wagtail.images.formats import get_image_format
# Front-end conversion
class ImageEmbedHandler:
class ImageEmbedHandler(EmbedHandler):
@staticmethod
def expand_db_attributes(attrs):
def get_model():
return get_image_model()
@classmethod
def expand_db_attributes(cls, attrs):
"""
Given a dict of attributes from the <embed> tag, return the real HTML
representation for use on the front-end.
"""
Image = get_image_model()
try:
image = Image.objects.get(id=attrs['id'])
except Image.DoesNotExist:
image = cls.get_instance(attrs)
except ObjectDoesNotExist:
return "<img>"
image_format = get_image_format(attrs['format'])