Write a custom crop provider¶
plone.pgthumbor uses a pluggable ICropProvider adapter to look up crop
coordinates before generating Thumbor URLs.
You can register your own
adapter to provide crop coordinates from any source – a custom annotation,
an external service, or computed values.
Define the adapter¶
Create a class that implements ICropProvider.
The adapter receives the
content object as context.
from plone.pgthumbor.interfaces import ICropProvider
from zope.interface import implementer
@implementer(ICropProvider)
class MyCropProvider:
def __init__(self, context):
self.context = context
def get_crop(self, fieldname, scale_name):
"""Return (left, top, right, bottom) or None."""
# Your logic here.
# Return pixel coordinates as a 4-tuple of integers,
# or None if no crop should be applied.
return None
Parameters¶
Parameter |
Type |
Description |
|---|---|---|
|
|
Name of the image field (for example, |
|
|
Name of the Plone image scale (for example, |
Return value¶
Return a 4-tuple (left, top, right, bottom) of integer pixel coordinates,
or None if no crop should be applied for this field/scale combination.
The coordinates define a bounding box on the original (unscaled) image. Thumbor crops the source image to this box before resizing to the target dimensions.
Register the adapter¶
Create a ZCML file to register your adapter:
<configure xmlns="http://namespaces.zope.org/zope">
<adapter
factory=".cropping.MyCropProvider"
provides="plone.pgthumbor.interfaces.ICropProvider"
for="*"
/>
</configure>
The for="*" registration makes the adapter available for all content
types.
You can restrict it to specific interfaces if needed:
<adapter
factory=".cropping.MyCropProvider"
provides="plone.pgthumbor.interfaces.ICropProvider"
for="my.package.interfaces.IMyContentType"
/>
Conditional registration¶
If your crop provider depends on a third-party package, use ZCML conditions to register it only when that package is installed:
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:zcml="http://namespaces.zope.org/zcml">
<adapter
zcml:condition="installed some.addon"
factory=".cropping.MyCropProvider"
provides="plone.pgthumbor.interfaces.ICropProvider"
for="*"
/>
</configure>
How crops affect URL generation¶
When get_crop() returns coordinates:
The crop box is included in the Thumbor URL as
{left}x{top}:{right}x{bottom}.fit_inis forced toTrue(the cropped region is fit into the target dimensions).smartcropping is forced toFalse(explicit crop overrides smart detection).
When get_crop() returns None, Thumbor URL generation proceeds as
usual based on the scale mode and smart cropping settings.
Adapter lookup order¶
Only one ICropProvider adapter is active at a time.
The ZCA adapter
registry uses standard precedence rules: a more specific for interface
wins over for="*".
If you need to override the built-in
plone.app.imagecropping adapter, register yours for a more specific
interface or use overrides.zcml.