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

signature

HMAC-SHA1 hash or unsafe

Cryptographic signature computed by libthumbor.CryptoURL using the shared security key.

operations

Thumbor operations string

Dimensions, fit-in, smart cropping, and filters encoded by libthumbor.

zoid_hex

Hexadecimal integer

ZODB OID of the Blob object (not the content object). Extracted from NamedBlobImage._blob._p_oid.

tid_hex

Hexadecimal integer

ZODB transaction ID (serial) of the blob. Extracted from NamedBlobImage._blob._p_serial after activation.

content_zoid_hex

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

left, top

integer

Top-left corner of the crop box in pixel coordinates on the source.

right, bottom

integer

Bottom-right corner of the crop box in pixel coordinates on the source.

When crop coordinates are present:

  • fit_in is forced to True regardless of the scale mode.

  • smart is forced to False (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

fit_in

smart

Behavior

scale (default)

True

per smart_cropping setting

Fits image within the requested dimensions without cropping. Aspect ratio is preserved. Smart cropping is applied if enabled.

cover

False

per smart_cropping setting

Resizes and crops to fill the exact requested dimensions. Smart cropping selects the crop region when enabled.

contain

True

False

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.