Skip to content

Make srcset URL building overridable in ImageScaling #199

@jensens

Description

@jensens

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions