URL format reference¶
This page documents the Thumbor URL structure generated by plone.pgthumbor
and consumed by zodb-pgjsonb-thumborblobloader.
URL structure¶
Thumbor URLs follow one of two formats depending on whether access control verification is required.
2-segment (anonymous)¶
Used for publicly accessible images (where Anonymous is in the
object’s allowedRolesAndUsers index).
{server_url}/{signature}/{operations}/{zoid_hex}/{tid_hex}
Example:
http://thumbor:8888/Ab3xY.../300x200/fit-in/smart/2a/ff
3-Segment (Authenticated)¶
Used for access-controlled images. Appends the content object’s ZOID so the Thumbor auth handler can verify Plone permissions before delivery.
{server_url}/{signature}/{operations}/{zoid_hex}/{tid_hex}/{content_zoid_hex}
Example:
http://thumbor:8888/Xk9pQ.../300x200/fit-in/2a/ff/1a
When paranoid_mode is enabled in the Plone registry, all images use the
3-segment format regardless of their access control settings.
Unsafe URLs¶
When unsafe mode is enabled (development only), the HMAC signature is
replaced with the literal string unsafe:
{server_url}/unsafe/{operations}/{zoid_hex}/{tid_hex}
Path Segments¶
Segment |
Format |
Description |
|---|---|---|
|
HMAC-SHA1 hash or |
Cryptographic signature computed by |
|
Thumbor operations string |
Dimensions, fit-in, smart cropping, and filters encoded by libthumbor. |
|
Hexadecimal integer |
ZODB OID of the |
|
Hexadecimal integer |
ZODB transaction ID (serial) of the blob. Extracted from |
|
Hexadecimal integer |
ZODB OID of the content object that owns the image. Present only in 3-segment authenticated URLs. |
HMAC-SHA1 Signing¶
URLs are signed using libthumbor.CryptoURL with the shared
security_key.
The signing covers the entire path after the server URL
(operations, image path, and all parameters). Thumbor validates the
signature before processing the request.
The key must match between Plone (PGTHUMBOR_SECURITY_KEY or the
security_key registry setting) and Thumbor (SECURITY_KEY in
thumbor.conf).
Crop coordinates¶
When an ICropProvider adapter returns crop coordinates for a given
field and scale, the crop box is included in the URL between the
signature and the dimensions:
{server_url}/{signature}/{left}x{top}:{right}x{bottom}/fit-in/{WxH}/{zoid_hex}/{tid_hex}
Example:
http://thumbor:8888/Ab3xY.../10x20:300x400/fit-in/400x300/2a/ff
Component |
Format |
Description |
|---|---|---|
|
integer |
Top-left corner of the crop box in pixel coordinates on the source. |
|
integer |
Bottom-right corner of the crop box in pixel coordinates on the source. |
When crop coordinates are present:
fit_inis forced toTrueregardless of the scale mode.smartis forced toFalse(explicit crop overrides smart detection).
The crop is applied to the original image before any resizing.
Scale mode mapping¶
Plone scale modes are mapped to Thumbor parameters by
scale_mode_to_thumbor():
Plone Mode |
|
|
Behavior |
|---|---|---|---|
|
|
per |
Fits image within the requested dimensions without cropping. Aspect ratio is preserved. Smart cropping is applied if enabled. |
|
|
per |
Resizes and crops to fill the exact requested dimensions. Smart cropping selects the crop region when enabled. |
|
|
|
Fits image within the requested dimensions. Smart cropping is always disabled. |
When an explicit crop is active, these mode defaults are overridden:
fit_in becomes True and smart becomes False for all modes.
The smart_cropping column reflects the smart_cropping boolean from
the Plone registry (IThumborSettings).
When smart_cropping is
False, the smart parameter is False for all modes.
SVG Handling¶
SVG images (image/svg+xml) bypass Thumbor entirely.
The
ThumborImageScale detects the content type and falls back to standard
Plone image scaling, which serves SVGs directly without transformation.
Blob ID Extraction¶
The get_blob_ids() function in blob.py extracts (zoid, tid) from a
NamedBlobImage or NamedBlobFile object:
Accesses named_image._blob to get the underlying ZODB Blob.
2.
Reads _p_oid for the blob’s OID.
3.
Calls _p_activate() to ensure the blob’s state is loaded (ghost
objects have _p_serial set to z64).
4.
Reads _p_serial for the committed transaction ID.
5.
Converts both 8-byte values to integers via ZODB.utils.u64.
Returns None if the blob is missing, has no OID, or has never been
committed.