-
-
Notifications
You must be signed in to change notification settings - Fork 19
Description
Summary
The srcset() method in ImageScaling hardcodes scale URL construction inline:
f'{self.context.absolute_url()}/@@images/{scale["uid"]}.{extension} {scale["width"]}w'This makes it impossible for custom scaling backends (e.g. external image services like Thumbor, Imgix, Cloudinary) to generate direct URLs in srcset without copying the entire srcset() method — which is fragile and hard to keep in sync with upstream changes (like #197).
Proposed change
Extract the URL-building into an overridable method:
class ImageScaling:
def _scale_url(self, scale, fieldname):
"""Build the URL for a single scale entry.
Override this in subclasses to generate URLs for external
image services instead of @@images/{uid} paths.
"""
extension = scale["mimetype"].split("/")[-1].lower()
return f'{self.context.absolute_url()}/@@images/{scale["uid"]}.{extension}'
def srcset(self, fieldname, ...):
# ... existing logic ...
for width, height in self.available_sizes.values():
if width <= original_width:
scale = storage.pre_scale(...)
url = self._scale_url(scale, fieldname)
srcset_urls.append(f'{url} {scale["width"]}w')This would allow custom backends to override just _scale_url():
class ThumborImageScaling(ImageScaling):
def _scale_url(self, scale, fieldname):
# Generate a direct Thumbor URL instead of @@images/{uid}
blob_ids = get_blob_ids(getattr(self.context, fieldname))
if blob_ids:
return thumbor_url(
server_url=cfg.server_url,
zoid=blob_ids[0], tid=blob_ids[1],
width=scale["width"], height=scale["height"],
...
)
return super()._scale_url(scale, fieldname)Motivation
We're building plone.pgthumbor, which replaces ZODB-stored image scales with Thumbor URL redirects. Currently @@images/{uid} URLs in srcset cause a 302 redirect per loaded image. While functional, direct URLs in srcset would eliminate the redirect hop entirely.
The same hook would benefit any external image processing integration.