File uploader for the REDAXO media pool based on FilePond: chunked upload for large files, metadata dialog with meta info fields, built-in image editor, AI alt texts via AI Platform, YForm field type, frontend use and MediaPlace integration.
German documentation: README.de.md · Alternative: uppy
- Features
- Requirements and installation
- Upgrading from 2.x
- Settings
- In the backend
- YForm field type
- In modules
- In the frontend
- Image editor
- AI alt texts
- Alt text checker
- Metadata
- Data attributes
- Security
- PHP API and classes
- JavaScript
- Styling
- Maintenance
- Credits
- Chunked upload: large files in parts (default 5 MB), with progress and cancel; leftovers of cancelled uploads are removed automatically.
- Metadata dialog: title, alt text, copyright and all other media pool meta info fields, also multilingual (MetaInfo Lang Fields). Required fields and decorative images.
- Image editor: crop with free or fixed aspect ratio, rotate in 90° steps, flip – before uploading.
- Image optimization: resize in the browser or on the server (ImageMagick or GD), EXIF orientation, colour profiles are kept.
- AI alt texts via an image understanding profile of the AI Platform addon, single and multilingual.
- Alt text checker in the media pool: find missing alt texts, edit them inline, generate them with AI.
- YForm field type
filepond, including automatic deletion of files that are no longer used, and thefilepond2emailaction. - Media pool: own upload page, optionally replacing the media pool upload page, replace files on the detail page, upload provider for MediaPlace.
- Frontend: for YCom users or guests (API token in the session), with signed target category and field limits.
- REDAXO 5.17.1 or later, PHP 8.4 or later
- Addons:
mediapool,metainfo,yform(4.0 or later) - Optional:
ai_platform(AI alt texts),mediaplace,ycom,metainfo_lang_fields
Install via the REDAXO installer. Installation creates the meta info fields med_alt (alternative text) and med_copyright if they are missing, and generates an API token.
3.0.0 contains changes that can affect your own extensions:
- Namespace
FriendsOfRedaxo\FilePondUploader. The old class names (filepond_helper,rex_api_filepond_*,filepond_alt_text_checker,filepond_ai_alt_generator,FriendsOfRedaxo\FilePond\FilePondMediaCleanup, …) keep working as aliases. - AI only via AI Platform. The built-in connections for Gemini, Cloudflare and Open WebUI are removed, together with their settings. Create a profile of type "image understanding" in AI Platform and select it in the FilePond settings.
- Custom widgets need security attributes: every request needs a CSRF token, frontend uploads additionally need a signed category. Output
Helper::widgetSecurityAttributes()in custom widgets (see In the frontend). Backend pages get the token automatically. - Removed: Info Center widget, "Bulk Resize", the API functions
load,restore,cancel-uploadandsave_metadata, the session switchesfilepond_no_metaandfilepond_title_required(usedata-filepond-skip-metaanddata-filepond-title-requiredinstead). - Settings are split into tabs. Existing values are kept; the update removes keys that are no longer used.
All changes are listed in the CHANGELOG.
FilePond Uploader → Settings (admins only):
| Tab | Contents |
|---|---|
| Upload | number and size, delayed upload, default category, language, required fields, chunked upload, allowed file types |
| Images | maximum pixel size, quality, EXIF orientation, resize in the browser or on the server, image editor |
| Metadata | always show or skip the dialog, additional required fields, hidden fields |
| Media pool | delete unused files from YForm fields, replace the media pool upload, replace files, multiupload subpage, alt text checker, YCom media protection |
| AI | AI Platform profile, where to offer AI, target field, languages, prompt, result cache |
| System | API token, debug log, clean up temporary files |
- FilePond Uploader → Upload: upload into a selectable category (only categories the user has permissions for).
- Media pool: FilePond can replace the media pool's upload page or appear as an additional "Multiupload" subpage.
- Replace file: on a media file's detail page the file can be exchanged; file name and metadata are kept.
- Media widgets: opened from
REX_MEDIA/REX_MEDIALIST, uploaded files can be taken over directly. - MediaPlace: choose "FilePond" as upload provider in the MediaPlace settings; upload button, drag & drop and paste then use the FilePond dialog (including chunked upload, image editor, AI suggestion). Permission for non-admins:
filepond_uploader[mediaplace_upload].
Permissions: filepond_uploader[upload] (upload page), filepond_uploader[alt_checker], filepond_uploader[mediaplace_upload], filepond_uploader[ycom_media_auth]. Uploads are only allowed into media categories the user has permissions for.
$yform->setValueField('filepond', [
'name' => 'images',
'label' => 'Gallery',
'category' => 1,
'allowed_types' => 'image/*,application/pdf',
'allowed_filesize' => 10,
'allowed_max_files' => 5,
'required' => 1,
'empty_value' => 'Please select at least one file.',
'delayed_upload' => 0,
]);Pipe notation: filepond|name|label|category|allowed_types|allowed_filesize|allowed_max_files|required|notice|empty_value|skip_meta|chunk_enabled|chunk_size|delayed_upload|title_required|alt_required|max_pixel|image_quality|client_resize|ai_enabled|ai_target_field
Empty options fall back to the global settings. The file names are stored comma-separated.
delayed_upload |
Behaviour |
|---|---|
0 |
upload right after selecting |
1 |
upload via a separate button |
2 |
upload when the form is submitted, then the form is sent |
Rejected files (type, size) block submitting with a notice at the field until they are removed.
Types and size are also checked on the server: the field signs its limits, and the upload endpoint rejects files outside them.
Delete unused files: with "automatic deletion" enabled, files removed from the field are deleted from the media pool when the record is saved – unless they are used elsewhere.
Send files by e-mail: the action attaches the files of a field to the YForm e-mail.
$yform->setActionField('filepond2email', ['images']);
// Pipe: action|filepond2email|imagesInput:
<?php use FriendsOfRedaxo\FilePondUploader\Helper; ?>
<input type="hidden" name="REX_INPUT_VALUE[1]" value="REX_VALUE[1]"
data-widget="filepond"
data-filepond-cat="1"
<?= Helper::configAttributes(['types' => 'image/*', 'maxfiles' => 5]) ?>
>Helper::configAttributes() returns all data-filepond-* attributes from the settings; single values can be overridden. In the backend, scripts, styles and the CSRF token are loaded automatically.
Output:
<?php
foreach (array_filter(explode(',', 'REX_VALUE[1]')) as $filename) {
$media = rex_media::get($filename);
if (null !== $media) {
echo '<img src="' . $media->getUrl() . '" alt="' . rex_escape((string) $media->getValue('med_alt')) . '">';
}
}Frontend uploads are allowed for logged-in YCom users or – for guests – when the API token is stored in the session. The token is never written to the HTML.
<?php
use FriendsOfRedaxo\FilePondUploader\Config;
use FriendsOfRedaxo\FilePondUploader\Helper;
rex_login::startSession();
rex_set_session('filepond_token', Config::string('api_token')); // only needed for guests
$categoryId = 3;
$types = 'image/*,application/pdf';
$maxSizeMb = 10;
echo Helper::getStyles();
?>
<form method="post">
<input type="hidden" name="files" value=""
data-widget="filepond"
data-filepond-cat="<?= $categoryId ?>"
<?= Helper::configAttributes(['types' => $types, 'maxsize' => $maxSizeMb]) ?>
<?= Helper::widgetSecurityAttributes($categoryId, $types, $maxSizeMb) ?>
>
</form>
<?= Helper::getScripts() ?>widgetSecurityAttributes() outputs the CSRF token and a signature over category, types and size. The values must match data-filepond-cat, types and maxsize; the server only accepts signed values. A complete example is in demo/frontend_demo.php.
The signature is valid for about 24 hours and only in the session the page was rendered in. Every page render creates a new one. Do not keep pages with an upload widget in a page cache for more than a few hours; after expiry or a session change (e.g. login) a reload helps. An optional fourth parameter binds the signature to a context; 'ycom' (or 'ycom:…') then allows uploads only for logged-in YCom users:
<?= Helper::widgetSecurityAttributes($categoryId, $types, $maxSizeMb, 'ycom:avatar') ?>Custom upload scripts (instead of filepond_widget.js) send policy_expires and policy_context from the attributes data-filepond-policy-expires and data-filepond-policy-context in addition to category_sig, policy_types and policy_maxsize.
In frontend YForm forms the filepond field type (template bootstrap) sets all attributes itself; add getStyles()/getScripts() and – for guests – the session token as above. AI suggestions are not available in the frontend.
On submit, the field in the frontend only accepts files that are already stored in the record or were uploaded in the same session; other file names are dropped. The server enforces the maximum number of files (allowed_max_files). In the backend, files from media categories the user has permissions for are accepted as well.
Metadata from frontend uploads is only stored for title, alt text, copyright, description and the required fields from the settings (never for hidden fields). Further fields can be allowed via the extension point FILEPOND_FRONTEND_METADATA_FIELDS:
rex_extension::register('FILEPOND_FRONTEND_METADATA_FIELDS', static function (rex_extension_point $ep) {
return [...$ep->getSubject(), 'med_photographer'];
});Upload requests go to the current page URL, where REDAXO handles rex-api-call.
For JPEG, PNG and WebP: crop (free, original, 1:1, 4:3, 3:2, 16:9 and portrait formats), rotate by 90°, flip horizontally and vertically, reset. Works with mouse, touch and keyboard (arrow keys move, Shift + arrow keys resize, Enter applies, Escape cancels).
- In the metadata dialog via "Edit image" below the preview – in all upload modes.
- With delayed upload also directly on the file item (via
filepond-plugin-image-edit); preview and upload apply the crop.
Disable it under Settings → Images → Image editor, or per widget with data-filepond-image-editor="false".
- Install AI Platform and create a profile of type image understanding (for example a local Ollama model or a cloud provider).
- Settings → AI: enable AI alt texts and select the profile (without a selection, AI Platform's default profile is used).
- Choose where AI is offered: metadata dialog, media detail page, alt text checker.
For multilingual alt fields one click generates all languages. Languages the model handles poorly can be blocked; they receive the text of the fallback language. Results are cached per image and profile; "regenerate" bypasses the cache.
Custom prompt with placeholders:
| Placeholder | Replaced with |
|---|---|
{language} |
language name, e.g. "English" |
{lang} |
language code, e.g. en |
{filename} |
original file name |
Without a custom prompt the selected prompt profile is used (accessible, neutral, SEO). AI features are only available to backend users.
Media pool → Alt text checker (admins and permission filepond_uploader[alt_checker]):
- statistics on images with and without alt text
- enter alt texts directly in the list, also multilingual; Enter saves, "Save all" saves all changes
- mark images as decorative (counted as done)
- filter by file name and category, large preview
- AI suggestions per image or for all visible images
Requires the meta info field med_alt.
The dialog shows the media pool's meta info fields, ordered title, med_title_lang, med_alt, med_copyright, med_description, then all others. Multilingual fields (MetaInfo Lang Fields) get language tabs.
title: optionally required (setting ordata-filepond-title-required)med_title_lang: always requiredmed_alt: required for images by default, alternatively "decorative image"
Further required and hidden fields can be set under Settings → Metadata.
| Attribute | Meaning | Default |
|---|---|---|
data-widget="filepond" |
turns an <input type="hidden"> into an upload field |
– |
data-filepond-cat |
target category | 0 |
data-filepond-types |
allowed types, MIME or extension, e.g. image/*,.pdf |
setting |
data-filepond-maxfiles |
maximum number of files | setting |
data-filepond-maxsize |
maximum size in MB | setting |
data-filepond-lang |
de_de or en_gb |
user language |
data-filepond-skip-meta |
skip the metadata dialog | false |
data-filepond-title-required |
title is required | setting |
data-filepond-alt-required |
alt text is required for images | setting |
data-filepond-chunk-enabled |
chunked upload | setting |
data-filepond-chunk-size |
chunk size in bytes (values up to 1024 are treated as MB) | 5 MB |
data-filepond-delayed-upload |
delayed upload | false |
data-filepond-delayed-type |
1 button, 2 on submit |
1 |
data-filepond-client-resize |
resize in the browser | setting |
data-filepond-max-pixel |
maximum edge length | setting |
data-filepond-image-quality |
JPEG/WebP quality 10–100 | setting |
data-filepond-image-editor |
image editor | setting |
data-filepond-ai-enabled |
AI suggestion in the dialog (backend only) | setting |
data-filepond-ai-target-field |
target field of the AI suggestion | med_alt |
data-filepond-media-url |
URL of the media folder | /media/ |
The security attributes (data-filepond-csrf, data-filepond-cat-sig, data-filepond-policy-*) are generated by Helper::widgetSecurityAttributes().
- Every request needs the addon's CSRF token (backend automatically, frontend via
widgetSecurityAttributes()). - Backend: uploads only into categories with permissions; deleting only own uploads or with category permission.
- Frontend: only YCom users or a session with the API token; category, types and size are signed and checked on the server; only the session's own uploads can be deleted.
- The file type is checked by content (not by extension or browser information), plus the media pool rules for allowed extensions.
- Chunks and metadata of an upload belong to the session that prepared it. Size, chunk count and field limits are checked as each chunk arrives; at most 20 uploads per session can be open at the same time.
- Without field limits, the allowed file types from the settings apply, also for external clients.
- Uploads are refused when free disk space runs low: at least twice the maximum file size or the value of the setting
min_free_disk_mbmust remain free (only viarex_config::set('filepond_uploader', 'min_free_disk_mb', 2048)). Leftovers of cancelled uploads are removed after 2 hours. - Signatures use their own key (not the API token), are valid for about 24 hours and only in the session that rendered them.
- The alt text checker only shows and edits images from media categories the user has permissions for. AI suggestions require the permission
filepond_uploader[upload]orfilepond_uploader[alt_checker](admins always) and permissions for the file's category; each user can make 100 requests per 10 minutes (ai_rate_limit). - Images above 50 megapixels are not processed by the server-side image optimisation with GD (left unchanged).
- External clients without a session authenticate with the
api_tokenparameter (Settings → System). Treat the token like a password.
use FriendsOfRedaxo\FilePondUploader\Helper;
Helper::getStyles(); // frontend: <link> tags, backend: via rex_view
Helper::getScripts(); // frontend: <script> tags, backend: via rex_view
Helper::configAttributes([...]); // data-filepond-* from the settings
Helper::widgetSecurityAttributes($categoryId, $types, $maxSizeMb, $context = '');| Class | Purpose | Alias up to 2.x |
|---|---|---|
FriendsOfRedaxo\FilePondUploader\Helper |
assets and widget attributes | filepond_helper |
…\Config |
read settings | – |
…\MediaCleanup |
usage check, deleting unused files | FriendsOfRedaxo\FilePond\FilePondMediaCleanup |
…\AltTextChecker |
alt text statistics | filepond_alt_text_checker |
…\Ai\AltTextGenerator |
AI alt texts via AI Platform | filepond_ai_alt_generator |
…\Api\Upload |
API filepond_uploader |
rex_api_filepond_uploader |
…\Api\AutoMetainfo, …\Api\AiGenerate, …\Api\AltChecker, …\Api\YcomAuth |
further APIs | rex_api_filepond_* |
The APIs are registered as described in the REDAXO documentation (rex-api-call=filepond_uploader etc.).
Extension point FILEPOND_FRONTEND_METADATA_FIELDS: list of metadata fields frontend uploads may set (see In the frontend).
Extension point MEDIA_IS_IN_USE: files used in a FilePond YForm field count as in use and cannot be deleted in the media pool.
// After every successful upload, on the input element
document.querySelector('#my-field').addEventListener('filepond:uploaded', (event) => {
console.log(event.detail.filename);
});
// FilePond instance of a field
const pond = document.querySelector('#my-field').pondInstance;
pond.on('processfile', (error, file) => { /* … */ });Widgets are initialized when the page loads, in the backend additionally on rex:ready. For widgets added later: document.dispatchEvent(new Event('filepond:init')).
Colours use CSS variables in assets/filepond_widget.css (--fp-primary, --fp-border, --fp-background, …) and follow the backend's dark mode. Override them in your project CSS:
:root {
--fp-primary: #0b6e4f;
--fp-primary-hover: #095c42;
}
.filepond-upload-btn { border-radius: 0; }Leftovers of cancelled uploads (chunks, metadata) are deleted automatically after six hours. Under Settings → System they can be cleaned up immediately; there you can also regenerate the API token and enable a debug log (in addition to REDAXO's debug mode).
- Friends Of REDAXO – github.com/FriendsOfREDAXO
- KLXM Crossmedia GmbH – klxm.de
- Thomas Skerbis – github.com/skerbis
- FilePond by PQINA, MIT licence
Licence: MIT. Please report bugs and requests as an issue.
