From 81dd38021cdd73f322efb9f7a05f2d2c653cabd9 Mon Sep 17 00:00:00 2001 From: Shane Date: Mon, 24 Aug 2026 10:02:06 +0200 Subject: [PATCH] apps/exports: Create multiple rows with one imageUrl per row, so that image links are clickable --- CHANGELOG.md | 1 + adhocracy4/exports/mixins/base.py | 3 +++ adhocracy4/exports/mixins/general.py | 28 ++++++++++++++++++++++++++-- adhocracy4/exports/views.py | 5 ++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc1460506f..ce030ab796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project (not yet) adheres to [Semantic Versioning](https://semver.org/spec/ - emails: add `get_from_email()` hook on `EmailBase` so projects can customize the sender address without overriding `dispatch()`. - exports: add ItemExportWithImageMixin to include images in exports +- exports: export each image on its own row to keep image links clickable ### Fixed diff --git a/adhocracy4/exports/mixins/base.py b/adhocracy4/exports/mixins/base.py index 0cdf5b731f..6fa93108c9 100644 --- a/adhocracy4/exports/mixins/base.py +++ b/adhocracy4/exports/mixins/base.py @@ -5,6 +5,9 @@ class VirtualFieldMixin: def get_virtual_fields(self, virtual): return virtual + def get_extra_rows(self, item, names): + return [] + class ExportModelFieldsMixin(VirtualFieldMixin): """ diff --git a/adhocracy4/exports/mixins/general.py b/adhocracy4/exports/mixins/general.py index 4c9f279387..451347704d 100644 --- a/adhocracy4/exports/mixins/general.py +++ b/adhocracy4/exports/mixins/general.py @@ -118,7 +118,7 @@ def get_virtual_fields(self, virtual): virtual["images"] = _("Images") return super().get_virtual_fields(virtual) - def get_images_data(self, item): + def get_images(self, item): images = [] if item.image: @@ -130,4 +130,28 @@ def get_images_data(self, item): for url in re.findall(pattern, description): images.append(self.request.build_absolute_uri(url)) - return "; ".join(images) if images else "" + return images + + def get_images_data(self, item): + images = self.get_images(item) + return images[0] if images else "" + + def get_extra_rows(self, item, names): + images = self.get_images(item) + if len(images) <= 1: + return [] + + images_index = names.index("images") + reference_number_index = ( + names.index("reference_number") if "reference_number" in names else None + ) + extra_rows = [] + for url in images[1:]: + extra_row = [""] * len(names) + extra_row[images_index] = url + if reference_number_index is not None: + extra_row[reference_number_index] = self.get_field_data( + item, "reference_number" + ) + extra_rows.append(extra_row) + return extra_rows diff --git a/adhocracy4/exports/views.py b/adhocracy4/exports/views.py index 7368c99ff4..0cec785a5d 100644 --- a/adhocracy4/exports/views.py +++ b/adhocracy4/exports/views.py @@ -72,7 +72,10 @@ def export_rows(self): names, _ = self.get_fields() for item in self.get_object_list(): - yield [self.get_field_data(item, name) for name in names] + row = [self.get_field_data(item, name) for name in names] + yield row + for extra_row in self.get_extra_rows(item, names): + yield extra_row def get_field_data(self, item, name): # Use custom getters if they are defined