diff --git a/wagtail_localize/models.py b/wagtail_localize/models.py index 5aa196ea..656e4059 100644 --- a/wagtail_localize/models.py +++ b/wagtail_localize/models.py @@ -3,6 +3,7 @@ import polib +from django.apps import apps from django.conf import settings from django.contrib.admin.utils import quote from django.contrib.contenttypes.models import ContentType @@ -36,6 +37,7 @@ get_serializable_data_for_fields, model_from_serializable_data, ) +from wagtail import VERSION as WAGTAIL_VERSION from wagtail import blocks from wagtail.blocks.list_block import ListValue from wagtail.coreutils import find_available_slug @@ -1559,6 +1561,14 @@ def get_field_path_from_streamfield_block(value, path_components): block_def = value.stream_block.child_blocks[block_type] block_value = block.value + if WAGTAIL_VERSION >= (6, 3) and apps.is_installed( + "wagtail.images" + ): + from wagtail.images.blocks import ImageBlock + + if isinstance(block_def, ImageBlock): + return [block_type] + path_components[1:] + if isinstance( block_def, (blocks.StructBlock, blocks.StreamBlock, blocks.ListBlock), diff --git a/wagtail_localize/segments/extract.py b/wagtail_localize/segments/extract.py index 313219b8..e68daa59 100644 --- a/wagtail_localize/segments/extract.py +++ b/wagtail_localize/segments/extract.py @@ -2,6 +2,7 @@ from django.core.exceptions import ImproperlyConfigured from django.db import models from modelcluster.fields import ParentalKey +from wagtail import VERSION as WAGTAIL_VERSION from wagtail import blocks from wagtail.fields import RichTextField, StreamField from wagtail.models import Page, TranslatableMixin @@ -52,6 +53,14 @@ def handle_block(self, block_type, block_value, raw_value=None): else: return [] + if WAGTAIL_VERSION >= (6, 3) and apps.is_installed("wagtail.images"): + from wagtail.images.blocks import ImageBlock + + if isinstance(block_type, ImageBlock): + return self.handle_image_block( + block_type, block_value, raw_value=raw_value + ) + if hasattr(block_type, "get_translatable_segments"): return block_type.get_translatable_segments(block_value) @@ -181,6 +190,28 @@ def handle_list_block(self, list_block, raw_value=None): ) return segments + def handle_image_block(self, block, image_block_value, raw_value=None): + segments = [] + + for field_name, block_type in block.child_blocks.items(): + try: + block_raw_value = raw_value["value"].get(field_name) + block_value = ( + image_block_value if field_name == "image" else block_raw_value + ) + except (KeyError, TypeError): + # e.g. raw_value is None, or is that from chooser + block_raw_value = None + block_value = None + segments.extend( + segment.wrap(field_name) + for segment in self.handle_block( + block_type, block_value, raw_value=block_raw_value + ) + ) + + return segments + def handle_stream_block(self, stream_block): segments = [] diff --git a/wagtail_localize/segments/ingest.py b/wagtail_localize/segments/ingest.py index 23008532..580ca44d 100644 --- a/wagtail_localize/segments/ingest.py +++ b/wagtail_localize/segments/ingest.py @@ -2,6 +2,7 @@ from django.apps import apps from django.db import models +from wagtail import VERSION as WAGTAIL_VERSION from wagtail import blocks from wagtail.fields import RichTextField, StreamField from wagtail.rich_text import RichText @@ -129,6 +130,12 @@ def handle_block(self, block_type, block_value, segments): if isinstance(segment, OverridableSegmentValue): return EmbedValue(segment.data) + if WAGTAIL_VERSION >= (6, 3) and apps.is_installed("wagtail.images"): + from wagtail.images.blocks import ImageBlock + + if isinstance(block_type, ImageBlock): + return self.handle_image_block(block_type, block_value, segments) + if hasattr(block_type, "restore_translated_segments"): return block_type.restore_translated_segments(block_value, segments) @@ -211,6 +218,24 @@ def handle_list_block(self, list_block, segments): return list_block + def handle_image_block(self, block, image_block, segments): + segments_by_field = defaultdict(list) + + for segment in segments: + field_name, segment = segment.unwrap() + segments_by_field[field_name].append(segment) + + field_map = {"alt_text": "contextual_alt_text", "decorative": "decorative"} + for field_name, segments in segments_by_field.items(): + if segments: + block_type = block.child_blocks[field_name] + value = self.handle_block( + block_type, getattr(image_block, field_map[field_name]), segments + ) + setattr(image_block, field_map[field_name], value) + + return image_block + def get_stream_block_child_data(self, stream_block, block_uuid): for stream_child in stream_block: if stream_child.id == block_uuid: