-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
draft: improved article body output #26
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Extends https://github.com/wagtail/wagtail/blob/main/wagtail/images/rich_text/__init__.py#L8 | ||
from django.utils.html import escape | ||
from wagtail.images.formats import get_image_format | ||
from wagtail.images.rich_text import ImageEmbedHandler | ||
|
||
|
||
class CustomImageEmbedHandler(ImageEmbedHandler): | ||
identifier = "image" | ||
|
||
@classmethod | ||
def expand_db_attributes_many(cls, attrs_list: list[dict]) -> list[str]: | ||
""" | ||
Given a dict of attributes from the <embed> tag, return the real HTML | ||
representation for use on the front-end. | ||
""" | ||
images = cls.get_many(attrs_list) | ||
|
||
tags = [] | ||
for attrs, image in zip(attrs_list, images): | ||
if image: | ||
image_format = get_image_format(attrs["format"]) | ||
tag = image_format.image_to_html(image, attrs.get("alt", "")) | ||
else: | ||
tag = '<img alt="">' | ||
|
||
tags.append(tag) | ||
|
||
return tags |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Ref: https://docs.wagtail.org/en/stable/advanced_topics/images/changing_rich_text_representation.html | ||
from django.utils.html import format_html | ||
from wagtail.images.formats import Format, register_image_format | ||
|
||
|
||
class InlineNewsImageFormat(Format): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This formatter is what Wagtail uses to display different image "formats" that can be selected when inserting an image in editor UI. This example does nothing useful, but outlines how we could use this to define a new format. This could for example be
|
||
def image_to_html(self, image, alt_text, extra_attributes=None): | ||
default_html = super().image_to_html(image, alt_text, extra_attributes) | ||
|
||
return format_html("<div>{}<figcaption>{}</figcaption></div>", default_html, alt_text) | ||
|
||
|
||
register_image_format( | ||
InlineNewsImageFormat("inline_news_image", "Inline news image", "image-classes object-contain", "max-3200x3200") | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
from aktuelt.constants import ContributionTypes | ||
from aktuelt.serializers import ( | ||
ContributorsSerializer, | ||
NewsBodySerializer, | ||
NewsImageSerializer, | ||
NewsPageGallerySerializer, | ||
NewsPageTagsSerializer, | ||
|
@@ -99,7 +100,7 @@ def schedule(self): | |
|
||
api_fields = [ | ||
APIField("intro"), | ||
APIField("body"), | ||
APIField("body", serializer=NewsBodySerializer()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is also the option of going with https://docs.wagtail.org/en/stable/topics/streamfield.html which seems to allow a few more advanced options. Mainly I think it could be useful if we wanted to transition to JSON array output rather than html and leave more of the body rendering logic to frontend (and remove the need for extending/hacking into wagtail frontend related code). |
||
# TODO: Replace with prettier (main model based?) serializer pattern? | ||
APIField("contributors", serializer=ContributorsSerializer(source="news_page_contributors")), | ||
APIField("tags", serializer=NewsPageTagsSerializer()), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
from rest_framework.fields import Field | ||
from wagtail.images.api.fields import ImageRenditionField | ||
from wagtail.rich_text import expand_db_html | ||
|
||
|
||
class NewsBodySerializer(Field): | ||
def to_representation(self, value): | ||
return expand_db_html(value) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what Wagtail uses in own frontend when rendering this type of data, mainly via a |
||
|
||
|
||
class NewsImageSerializer(Field): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# https://docs.wagtail.org/en/stable/extending/rich_text_internals.html#rewrite-handlers | ||
from wagtail import hooks | ||
|
||
from aktuelt.handlers import CustomImageEmbedHandler | ||
|
||
|
||
# Higher order to make sure it runs after image handler hook in images app | ||
@hooks.register("register_rich_text_features", order=10) | ||
def register_embed_handler(features): | ||
features.register_embed_type(CustomImageEmbedHandler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A handler is how Wagtail converts internal xml/html-like format into frontend html. The current example works but should ideally be expanded to include srcset of all relevant sizes based on output of https://github.com/gathering/tgno-backend/blob/main/aktuelt/serializers.py#L11 (which is used for other news article images)