Thumb3x: modern image processing for MODX 3
This component was written to fill a gap in the MODX 3 ecosystem, which has almost no modern and reliable tools for working with images. Most existing solutions have not been updated for more than 10 years and do not use the advantages of the new version of the system.
Key features
Modern formats: on-the-fly conversion to WebP and AVIF.
Advanced engine: built on the high-performance Glide 3.2 library.
MODX 3 integration: full support for Media Sources.
Flexible processing: filters, effects, watermarks and precise positioning.
Fenom support: convenient snippet calls with parameters passed as arrays.
Cache management: generated files are logged in the database with a handy table in the manager.
Standard MODX call
<img src="[[!Thumb3x? &input=`path/to/image.jpg` &options=`w=300&h=200`]]" alt="">
Fenom call
{'!Thumb3x' | snippet : [
'input' => 'path/to/image.jpg',
'options' => [
'w' => 300,
'h' => 200
]
]}
Main snippet parameters
| Parameter | Alias | Description | Example |
|---|---|---|---|
input |
i |
(Required) Path to the source image. | &input=`image.jpg` |
sourceId |
ID of the Media Source of the source image. Defaults to the value from the system settings. | &sourceId=`2` |
|
quality |
q |
(Overridden by &options) Default quality. |
&quality=`75` |
Important: any parameters (
q,fm, etc.) given inside the&optionsstring always take the highest priority.
Processing parameters reference (&options)
Official Glide documentation
Thumb3x uses the Glide library for all image operations, so you can use any parameter the library itself supports.
The most complete and up-to-date list of parameters is always on the official site: https://glide.thephpleague.com/
Size and orientation
| Parameter | Key | Description | Example |
|---|---|---|---|
| Width | w | Width of the resulting image in pixels. | w=300 |
| Height | h | Height of the resulting image in pixels. | h=200 |
| Fit | fit | How to fit the image. Main values: contain, max, stretch, crop. | fit=crop |
| Crop | crop | Exact cropping: width,height,x,y. | crop=200,150,20,50 |
| DPR | dpr | Multiplier for Retina displays. dpr=2 returns an image twice the size. | dpr=2 |
| Orientation | or | Rotates the image. Values: auto, 0, 90, 180, 270. | or=90 |
| Flip | flip | Flips the image. Values: v (vertical), h (horizontal), both. | flip=h |
Adjustments and effects
| Parameter | Key | Description | Example |
|---|---|---|---|
| Brightness | bri | Brightness adjustment (-100 to +100). | bri=20 |
| Contrast | con | Contrast adjustment (-100 to +100). | con=-30 |
| Gamma | gam | Gamma correction (0.1 to 9.99). | gam=2.2 |
| Sharpen | sharp | Sharpening (0 to 100). | sharp=10 |
| Blur | blur | Gaussian blur (0 to 100). | blur=15 |
| Pixelate | pixel | Pixelation effect (0 to 1000). | pixel=10 |
| Filter | filt | Applies a filter: greyscale or sepia. | filt=greyscale |
Background and border
| Parameter | Key | Description | Example |
|---|---|---|---|
| Background | bg | Background colour. Format: RRGGBB. | bg=CCCCCC |
| Border | border | Adds a border. Format: width,colour,method. Method: overlay or shrink. | border=5,000000,overlay |
Watermarks
| Parameter | Key | Description | Example |
|---|---|---|---|
| Path | mark | (Required) Watermark file name. | mark=logo.png |
| Width | markw | Watermark width (px or %). | markw=15w |
| Height | markh | Watermark height (px or %). | markh=50 |
| Offset X | markx | Horizontal offset (negative values — from the right edge). | markx=-20 |
| Offset Y | marky | Vertical offset (negative values — from the bottom edge). | marky=-20 |
| Padding | markpad | Padding on all sides. | markpad=10 |
| Position | markpos | Position: top-left, center, bottom-right, etc. | markpos=top-left |
| Opacity | markalpha | Watermark opacity (0-100). | markalpha=50 |
Output format
| Parameter | Key | Description | Values | Example |
|---|---|---|---|---|
| Format | fm | Format of the resulting image. | jpg, png, gif, webp, avif | fm=webp |
| Quality | q | Quality for jpg, webp, avif. | 0 to 100 | q=80 |
Detailed call examples
Example 1: watermark (standard MODX call)
Task: put logo.png in the bottom right corner with padding and half transparency.
<img src="[[!Thumb3x?
&input=`portfolio/image-01.jpg`
&watermark=`assets/watermark/logo.png`
&options=`w=1200&mark=logo.png&markpos=bottom-right&markpad=30&markalpha=50`
]]" alt="Watermarked portfolio image">
Example 2: Fenom call
Task: the same, using the more readable Fenom syntax with parameters passed as an array.
{* Glide parameters as an array *}
{var $params = [
'w' => 1200,
'h' => 800,
'mark' => 'logo.png',
'markpos' => 'bottom-right',
'markpad' => 20,
'markalpha' => 60
]}
{* Call the snippet *}
<img src="{'!Thumb3x' | snippet : [
'input' => 'portfolio/image-01.jpg',
'watermark' => 'assets/images/logo.png',
'options' => $params
]}" alt="Watermarked image">
Note: the main advantage of Fenom here is that all processing parameters can be collected in a neat $params array, which makes the template much cleaner and easier to read and edit.
Cache path scheme
By default Glide builds the cache file name from the path of the source image. This is handy for debugging, but it means the location of the original is visible right in the thumbnail URL:
Source: images/products/253/001.jpg
Cache: /assets/components/thumb3x/cache/images/products/253/001.jpg/572c844a39ecf673.webp
If you add a watermark, a visitor can easily work out the path to the original without it. Since version 3.1.0 the naming scheme can be changed with the thumb3x.cache_path_mode system setting.
| Value | Cache URL | Description |
|---|---|---|
source |
…/cache/images/products/253/001.jpg/572c844a39ecf673.webp |
(Default) Standard Glide behaviour and that of all versions before 3.1.0. The source path is visible in the URL. |
hashed |
…/cache/63/fc/63fca9e1cfecba76209b6eb0d77d479b83c92b92.webp |
(Recommended) The file name is a SHA1 hash spread over subfolders. The path to the original is not revealed, and cache files are evenly distributed over 65536 folders, which makes backups and FTP work with the folder much easier. |
flat |
…/cache/63fca9e1cfecba76209b6eb0d77d479b83c92b92.webp |
Same as hashed, but all files are in one folder. Suitable for small sites. |
Any other or empty value is treated as source, so a typo in the setting cannot break the site. In the hashed and flat modes the file name equals the hash field in the thumb3x_files table.
After changing the value, clear the cache completely — the “Clear all cache” button in the manager. Previously generated images will still be served from the URLs stored in the database, but they stay in the old scheme and will eventually become garbage on disk. Also note that the URLs of all new images change: if the site uses a CDN, its cache will need to be purged.
Upgrading from previous versions. The setting is created with the value source, so upgrading to 3.1.0 changes nothing on live sites: existing cache records stay valid and no images are regenerated. The new scheme is only enabled manually.
Important: this does not protect the original. The hashed and flat modes remove the original path from the cache URL, but the original itself stays available at its usual address if it is in a public folder of the site.
If you really need to block access to images without a watermark, keep the originals outside the web root: create a Media Source with a base path outside the public directory (for example {core_path}storage/images/) and set it in thumb3x.source_id. Thumb3x reads files through the file system, not over HTTP, so processing keeps working, and only the cache folder — already watermarked — is served publicly.