Joomla Media Manager: Adapters, Uploads, Image Editing and Media Fields

This content was generated with the assistance of AI and should be verified against the official Joomla documentation before being relied on in production.

This sub-section’s Joomla bibliography lists the reference material consulted while preparing these pages.

This page describes the Joomla Media Manager as it was on 2026-10-30, the date on which its facts were checked against the Joomla! User Guide (https://guide.joomla.org/), the Joomla! Developer Manual and the source tree of the CMS. It was written against Joomla 6.2.x (PHP 8.3 or later); the screens and settings described are the same in the 5.4 security-only line unless a version is named. The running example is the Tallpine Hiking Club site: editors upload trail photographs, board members upload minutes as PDF files, and each trail report carries a GPX track as a media custom field.

The Media Manager is used by four kinds of people. Editors and authors upload, rename and insert files. Site builders decide which folders exist and which file types are allowed. Administrators protect the upload path. Developers add storage back ends and media fields to their own extensions. The sections below follow that order.

What the Media Manager is

The Media component (com_media) manages the images and other files that articles, modules and templates use. The User Guide stresses one fact that explains much of its design: media are served directly by the web server, not by Joomla code, so delivering an image costs no PHP execution. The component only helps people organise, upload, edit and insert files. The files themselves live in ordinary folders of the web root.

By default these folders are images and, since Joomla 5.3, files. The separate top-level media folder holds the JavaScript, CSS and web assets of Joomla and its extensions and is not a place for uploads; confusing the two is a common mistake. Folder names become part of public URLs, so the User Guide recommends lowercase names without spaces or punctuation and hyphens between words (for example trail-reports), and recommends planning the folder tree to mirror the category structure, because moving an image later breaks the links in articles that point to it.

The Media Manager can be opened in three ways:

  • Content → Media in the administrator menu, as a normal component screen

  • Site panel → Media on the Home Dashboard

  • the CMS Content → Media button of an article edit screen, which opens it in a modal dialog so that a picture can be selected and inserted into the text

The Vue-based interface

Since Joomla 4.0 the Media Manager is a single-page application written with Vue. The server renders almost nothing: the page loads a Vue application from the media folder, and the application talks to the server through a JSON API exposed by com_media (the api controller, which forwards each request to the ApiModel). Listing a folder, creating a folder, uploading, renaming, moving, copying, deleting and saving an edited image are all calls of that API. The interface is therefore a client of a documented set of server-side classes rather than a set of form posts, and that is what makes it possible to add storage back ends and editing tools as plugins.

The interface has these parts, all described in the User Guide:

  • a tree in the left column whose roots are the registered storage locations (labelled Local for the local file system), with the folder tree below each root; selecting a folder closes its sibling folders

  • breadcrumbs for moving back up the hierarchy; double-clicking a folder opens it

  • a toolbar with a select-all box, a search box that filters the list as you type, a magnifier that changes the thumbnail size (roughly 2, 4, 6 or 8 items per row, depending on the screen width), a list/thumbnail toggle (the list shows dimensions and file size) and an information icon that opens a side panel with the details of the selected item

  • Create New Folder and Upload buttons, drag-and-drop upload, and Delete, Rename, Edit, Move and Copy actions

  • the Options button, which opens the component options described below

Deleting a folder deletes everything inside it. To empty a folder without deleting it, use the select-all box and delete the items.

Architecture: providers, adapters and the filesystem plugin

The Media Manager separates three concerns: what a storage location is (an adapter), who offers it (a provider) and how it is shown (the Vue application). The classes live in the namespace Joomla\Component\Media\Administrator.

flowchart LR U[Editor in the Vue app] -->|JSON request| A[com_media api controller] A --> M[ApiModel] M -->|local-images:/trails| PM[ProviderManager] PM --> P[Provider plugin: FileSystem - Local] P --> AD[LocalAdapter for images or files] AD --> FS[(Web root folder)] AD --> TH[(media/cache/com_media/thumbs)] M -->|content and media-action events| PL[Plugins]

A provider implements ProviderInterface, with three methods: getID(), getDisplayName() and getAdapters(). An adapter implements AdapterInterface and represents one root. Its methods are getFile(), getFiles(), getResource(), createFolder(), createFile(), updateFile(), delete(), move(), copy(), getUrl(), getAdapterName() and search(). Providers are plugins of the filesystem group. When the Media Manager starts it dispatches the onSetupProviders event with a MediaProviderEvent, and every enabled filesystem plugin registers itself with the ProviderManager obtained from the event. The manager keys providers by their ID and finds an adapter from a name of the form provider-account, such as local-images; the part after the first hyphen is the account, so the account itself may contain hyphens. Unknown providers or accounts raise a ProviderNotFoundException or a ProviderAccountNotFoundException.

Everywhere the Media Manager refers to a file it uses the combination of the adapter and the path inside it, for example local-images:/trails/alpine/ridge.jpg. The same notation is stored by media fields (see below).

The FileSystem - Local plugin

The core provider is plg_filesystem_local, a final class Joomla\Plugin\Filesystem\Local\Extension\Local that extends CMSPlugin and implements SubscriberInterface and ProviderInterface. It subscribes to the single event onSetupProviders. Its only parameter is a repeatable directories subform, in which every row has a directory (chosen from the folders that exist in the site root) and a thumbs switch. The default value is:

[{"directory": "images"}, {"directory": "files"}]

For every row with a non-empty directory, getAdapters() creates one LocalAdapter rooted at that folder, with a fixed thumbnail size of 200 x 200 pixels, and attaches the current user to it. A row without the thumbs flag is treated as thumbs = 0. Each adapter appears as a root in the Media Manager tree. Adding a row is how a site gets an additional media root, and the User Guide’s procedure is: create a folder in the site root (for example gpx), open the FileSystem - Local plugin, press the + button, choose the folder from the list, make sure the plugin is enabled and save. The folder must not reuse the name of a core Joomla folder.

[
  {"directory": "images", "thumbs": 1},
  {"directory": "files", "thumbs": 0},
  {"directory": "gpx", "thumbs": 0}
]

The Create Thumbnails switch is the thumbs flag. The User Guide explains the effect: Joomla generates previews of at most 200 pixels in height or width in media/cache/com_media/thumbs, in a tree that mirrors the media folder. The adapter creates a thumbnail when an image is uploaded or updated and, on demand, the first time a listing finds no thumbnail. A failure to create one is silent, and the interface then falls back to the original image. Deleting a file or folder deletes its thumbnails too. Thumbnails speed up folders with many images and are pointless for documents, which are shown as icons, so the switch is per root.

The files folder introduced in 5.3

Joomla 5.3 added a second default root named files, so that documents such as PDFs are kept apart from pictures. The release announcement for 5.3 mentions it in a single line. The corresponding options are image_path (default images) and file_path (default files) in the Media options, and the local plugin lists both folders by default. Older material describes the situation of Joomla 3 and 4, where both paths pointed to the images folder in a new installation; the User Guide page on media options still says so. On a current installation, a trail photograph goes into images and a PDF of the board minutes into files. A site upgraded from an earlier release may not have the files folder or the second row of the plugin until an administrator creates them.

A custom root is also the right answer to a recurring request: documents that must not live under images, for example because a reverse proxy serves that folder from a CDN with long cache lifetimes. Remember that every root the local plugin exposes is a public web folder; the Media Manager has no private storage.

Writing a provider for another storage back end

A developer can offer a different back end, such as an object store, by writing a plugin of the filesystem group. The plugin below is a minimal provider that exposes a read-write gpx folder with a core LocalAdapter; a real object store would return its own class implementing AdapterInterface instead.

<?php

namespace Tallpine\Plugin\Filesystem\Gpx\Extension;

use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Component\Media\Administrator\Event\MediaProviderEvent;
use Joomla\Component\Media\Administrator\Provider\ProviderInterface;
use Joomla\Event\SubscriberInterface;
use Joomla\Plugin\Filesystem\Local\Adapter\LocalAdapter;

defined('_JEXEC') or die;

final class Gpx extends CMSPlugin implements SubscriberInterface, ProviderInterface
{
    public function __construct(array $config, private string $rootDirectory)
    {
        parent::__construct($config);
    }

    public static function getSubscribedEvents(): array
    {
        return ['onSetupProviders' => 'onSetupProviders'];
    }

    public function onSetupProviders(MediaProviderEvent $event): void
    {
        $event->getProviderManager()->registerProvider($this);
    }

    public function getID(): string
    {
        return $this->_name;
    }

    public function getDisplayName(): string
    {
        return 'Tallpine GPX tracks';
    }

    public function getAdapters(): array
    {
        $adapter = new LocalAdapter($this->rootDirectory . '/gpx/', 'gpx', 0, [200, 200]);

        return [$adapter->getAdapterName() => $adapter];
    }
}

The plugin needs the usual services/provider.php and manifest of a filesystem plugin (see Plugin Development and Events and Extension Types, Manifests and Packaging); the core plg_filesystem_local is the model to copy. The core plugin’s services/provider.php builds the plugin with (array) PluginHelper::getPlugin('filesystem', 'local') and JPATH_ROOT as the two constructor arguments and then calls setApplication(); the sketch above assumes the same wiring. The provider ID is the plugin name, so adapters are addressed as <plugin name>-<adapter name>.

Upload rules: extensions, MIME types and size

Uploads are the dangerous part of any CMS, and Joomla validates them in layers. The settings live in the component options (the Options button of the Media Manager, or System → Global Configuration → Media), in the component fieldset of administrator/components/com_media/config.xml.

Option Default in 6.2 Meaning

upload_maxsize

10

Maximum upload size in megabytes. In the helper, 0 means no limit.

file_path

files

Folder for non-image files (since 5.3)

image_path

images

Folder for images

restrict_uploads

1 (Yes)

Enables content inspection and the MIME and administrator checks

restrict_uploads_extensions

bmp,gif,jpg,jpeg,png,webp,avif,ico,mp3,mp4,odg,odp,ods,odt,pdf,ppt,txt,xcf,xls,csv

The allowlist of file extensions (shown as Allowed Extensions)

check_mime

1 (Yes)

Requires the detected MIME type to be in the list below

image_extensions

bmp,gif,jpg,jpeg,png,webp,avif

Extensions treated as images

audio_extensions

mp3,m4a,mp4a,ogg

Extensions treated as audio

video_extensions

mp4,mp4v,mpeg,mov,webm

Extensions treated as video

doc_extensions

doc,odg,odp,ods,odt,pdf,ppt,txt,xcf,xls,csv

Extensions treated as documents

ignore_extensions

empty

Extensions that pass the extension check and skip the MIME and administrator checks

upload_mime

image, audio, video, Office, PDF, text/plain and application/x-zip types

Allowed MIME types

The image_extensions, audio_extensions, video_extensions and doc_extensions options decide what the interface considers a media file and which filter (images, audio, video, documents) a media field offers; the allowlist restrict_uploads_extensions decides what may be uploaded at all. A new extension therefore usually has to be added in two places, and to upload_mime as well. The User Guide’s troubleshooting advice for a rejected upload is to check the allowed extensions, the legal extension types and the legal MIME types: all three must agree.

What MediaHelper::canUpload() checks

Every upload goes through MediaHelper::canUpload() (called by the local adapter in checkContent(), which first writes the data to a temporary file). It stops at the first failed step:

  1. an empty file name is rejected

  2. a name that File::makeSafe() would change is rejected, so unsafe characters never reach the disk

  3. a name without an extension is rejected

  4. every dot-separated segment of the name is compared with the blocklist of executable extensions, not only the last one, so shell.php.jpg is refused

  5. the final extension must be in restrict_uploads_extensions or ignore_extensions

  6. the size must not exceed upload_maxsize

  7. when restrict_uploads is on, the content is inspected. For an allowlisted extension the file must be a real image (detected with exif_imagetype() and getimagesize()) with a permitted MIME type. For an extension that is not on the allowlist and not ignored, the MIME type is detected with mime_content_type() or finfo and must be in upload_mime, and the user must have core.manage on com_media

  8. a file with the extension svg is run through the SVG sanitiser

A failure raises a generic forbidden error (HTTP 403) in the interface and the specific language key in the log; the exact messages include JLIB_MEDIA_ERROR_WARNFILETYPE, JLIB_MEDIA_ERROR_WARNINVALID_MIMETYPE and JLIB_MEDIA_ERROR_WARNFILETOOLARGE. The Local adapter also protects against path traversal: every path is resolved with Path::check() against the root of the adapter, search terms containing separators or .. are rejected, and a move that would change the sanitised name is refused. Copying and moving without the force flag refuse to overwrite an existing target.

The default of restrict_uploads_extensions in config.xml and the fallback default coded in MediaHelper are slightly different lists (the helper also lists m4a, mp4a, ogg, mp4v, mpeg and mov). Because the saved component options take precedence on any site whose options were ever saved, treat the options screen as the authority and review it after an upgrade.

Letting editors upload GPX files

The Tallpine custom field gpx-file needs GPX uploads. A GPX file is XML, so the detected MIME type is typically application/xml or text/xml, never an image type. The complete change is to add gpx to restrict_uploads_extensions and to doc_extensions, add the detected MIME type to upload_mime, and allow the user group to manage media (for non-allowlisted content the user needs core.manage on Media). When a GPX upload is rejected with JLIB_MEDIA_ERROR_WARNINVALID_MIMETYPE, the log shows the MIME type that was detected, which is the value to add. Adding gpx to ignore_extensions would also make it work but disables the MIME and administrator checks for that extension, which is acceptable only for a type that cannot carry active content.

# Show what the server's libmagic thinks of a sample file before changing upload_mime
file --mime-type tallpine-alpine-loop.gpx

SVG files

By default Joomla does not accept SVG. To allow it, add svg to the allowed extensions and to the image extensions, and image/svg+xml to the MIME list. Since Joomla 4.1 every SVG uploaded through the Media Manager is checked by a sanitiser, and rules are strict. SVG is XML text, so it can carry cross-site scripting through <script> elements and event attributes, HTML injection through <foreignObject>, and denial of service through misused xlink:href references. A file that is refused usually needs cleaning in an editor or an external SVG cleaner. Allow SVG only for trusted editors, and remember that the sanitiser protects files uploaded through the Media Manager, not files copied to the folder by FTP.

Permissions

Access to the Media Manager is governed by the ACL of com_media (the Permissions tab of its options): who may access the component, create folders and upload (core.create), edit (core.edit) and delete (core.delete). The custom field and media field respect these too: a media field is disabled for a user without core.create on com_media. The adapter itself performs no ACL checks, so a developer who calls an adapter directly must check permissions. See Users, Groups, Access Levels and ACL. The restrict_uploads option stays on for every public site; turning it off removes the content inspection that protects against a renamed script.

Image editing: crop, resize and rotate

The Media Manager can edit an image in place. Editing tools are plugins of the media-action group: the core ships crop, resize and rotate. Each plugin extends MediaActionPlugin, which listens to onContentPrepareForm, reacts only to the form named com_media.file, loads the plugin’s JavaScript module and CSS, and loads an XML form from plugins/media-action/<name>/form/<name>.xml. The interface then shows one tab per enabled plugin on the Edit screen of an image. Disabling a plugin in the Plugin Manager removes its tab.

The User Guide describes the three tools:

  • Crop: choose an aspect ratio or none, drag the corners, edges or the inside of the selection, or type the X and Y offsets and the width and height; press Save to apply it.

  • Resize: enter a width and the height follows, keeping the aspect ratio. The resize form also carries a quality slider (1 to 100, default 80). The User Guide warns that the quality control is currently not reliable and that a modified image may end up larger than the original.

  • Rotate: pick an angle, in steps of 90 degrees.

Saving overwrites the file: there is no undo, so edit a copy when the original matters. After a crop the interface may show stale box values even though the crop was applied. The resize plugin also has a batch fieldset in its own parameters, a maximum width and a maximum height in pixels: when set, images are scaled down automatically as they are uploaded, which is the better answer to oversized phone photographs than asking editors to resize by hand.

The save path matters for developers. Editing and uploading go through the ApiModel, which loads the content and media-action plugin groups and dispatches onContentBeforeSave, onContentAfterSave, onContentBeforeDelete and onContentAfterDelete with the contexts com_media.file and com_media.folder, so a content plugin can veto or log an upload. Listing and reading dispatch onFetchMediaItem, onFetchMediaItems and onFetchMediaFileUrl, which let a plugin change what the interface displays.

Media fields

A media field (form field type media, class Joomla\CMS\Form\Field\MediaField) is the control that opens the Media Manager in a modal from any form: the intro and full-article images of an article, a module parameter or a custom field. It renders with the layout joomla.form.field.media. In an XML form it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<form>
  <fieldset name="basic">
    <field
      name="cover_image"
      type="media"
      label="COM_TALLPINE_FIELD_COVER_IMAGE_LABEL"
      types="images"
      directory="trails"
      preview="tooltip"
    />
    <field
      name="gpx_file"
      type="media"
      label="COM_TALLPINE_FIELD_GPX_FILE_LABEL"
      types="documents"
      directory="gpx"
    />
  </fieldset>
</form>

The attributes that matter:

  • types: a comma-separated list chosen from images, audios, videos, documents and directories; the default is images. The permitted extensions of each type come from the extension options above. directories lets the user pick a folder rather than a file, which is what the media custom field uses for its own Directory parameter.

  • directory: the starting folder, relative to the images path, or an adapter:path string for another root. It is used only when the folder exists and belongs to a registered local directory.

  • preview (true, tooltip or false; the default is tooltip), preview_width and preview_height (default 200 x 200): whether and how a preview is shown.

  • width and height (default 800 x 500): the size of the modal.

The stored value is a path followed by a fragment that records the adapter and the image size, for example images/trails/ridge.jpg#joomlaImage://local-images/trails/ridge.jpg?width=1200&height=800. Output code must remove the fragment before using the value as a URL; HTMLHelper::cleanImageURL() does that and returns the clean URL plus the width and height, which can be placed on the img element to avoid layout shift. A plain local path (the Joomla 3 format) is still accepted if the file exists, so content from old sites keeps working.

The media custom field

For the Tallpine trail article the site builder creates a custom field GPX file of type Media (the fields plugin plg_fields_media). Its parameters are Directory (a folder picker restricted to directories, so the editor starts in gpx), Preview (inline preview of the selected image or not) and Image class, a CSS class added to the img tag on output; the User Guide’s example is w-25. Custom fields in general are covered in Custom Fields. The plugin normalises the stored value before output: a JSON value is decoded, and a legacy plain string is wrapped as an imagefile with an empty alt text.

Accessible images: alt text and the accessiblemedia field

Every informative image needs a text alternative, and every purely decorative image needs an explicit empty one. Joomla supports both in the places where editors work:

  • the article Images and Links tab has an alt text input and a "no description" option for the intro image and for the full-article image

  • the editor’s image dialog asks for an image description and has an "image has no description" option, which emits alt=""

  • the accessiblemedia field type (Joomla\CMS\Form\Field\AccessiblemediaField, extending SubformField) is a media field that carries its accessibility information with it. The media custom field is exposed to editors as an accessiblemedia field, and it is the field type to use in new extensions

The accessiblemedia field builds its subform from the types attribute: for images it shows a media selector named imagefile, a text field alt_text and a checkbox alt_empty ("no description", for decorative images); for documents a linktext field; for videos an optional poster selector when video_poster is 1; and for audio a single file selector. The types attribute was added to this field in 6.1. The stored value is a JSON object, and the field accepts a legacy plain path by converting it to imagefile with an empty alt_text.

<field
  name="hero"
  type="accessiblemedia"
  label="COM_TALLPINE_FIELD_HERO_LABEL"
  types="images"
  directory="trails"
/>
<?php

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;

defined('_JEXEC') or die;

// $hero is the decoded JSON value of the accessiblemedia field.
$hero = json_decode($this->item->params->get('hero', '{}'), true) ?: [];

if (!empty($hero['imagefile'])) {
    $image = HTMLHelper::cleanImageURL($hero['imagefile']);
    $alt   = empty($hero['alt_empty']) ? ($hero['alt_text'] ?? '') : '';
    ?>
    <img src="<?php echo htmlspecialchars($image->url, ENT_QUOTES, 'UTF-8'); ?>"
         alt="<?php echo htmlspecialchars($alt, ENT_QUOTES, 'UTF-8'); ?>"
         width="<?php echo (int) $image->attributes['width']; ?>"
         height="<?php echo (int) $image->attributes['height']; ?>"
         loading="lazy">
    <?php
}

Escape the alt text on output as shown: it is editor input. A missing alt_text with alt_empty unset is an editorial error, not a decorative image; the emitted alt must be a deliberate choice. More on accessibility testing is in Web Accessibility and on Joomla’s own accessibility settings in Colour Modes, RTL and Accessibility.

Common errors and pitfalls

  • "This file type is not allowed" for a type that is in the list. The extension must be in the allowlist, in the type list for the field and, when check_mime is on, its detected MIME type must be in upload_mime.

  • Uploads fail only for large files. The effective limit is the smallest of upload_maxsize, PHP’s upload_max_filesize and post_max_size, and the web server’s body limit (see Web Server, Reverse Proxy and HTTPS).

  • A thumbnail view that shows broken images is usually a missing GD or Imagick extension, or a read-only media/cache folder, because thumbnail failures are silent.

  • Moved or renamed images break articles, because articles store paths. Rename within the manager and then fix the links, or keep the folder tree stable from the start.

  • Spaces and capitals in file names. The manager sanitises names and a move that would change the name is refused; rename the file instead.

  • Disabling restrict_uploads to make an odd file pass removes the main defence against disguised scripts.

  • A custom root that is not listed because the plugin is disabled or the folder does not exist at the site root.

  • Treating the Media Manager as private storage. Every root is web-accessible; confidential files do not belong in it.

Corrections to older books and tutorials

Joomla! 4 Masterclass (2023) is the book that covers articles and the Media Manager in depth, and its screens still match the current one. It was written before Joomla 5.3 and says nothing of the files folder or of the per-root thumbnail switch, and it predates the accessiblemedia field and the types attribute added in 6.1. Older books and tutorials, and the User Guide page on media options, describe a new installation in which both the image path and the file path point to the images folder; since 5.3 the file path defaults to files. Material written for Joomla 3, with its older image modal, does not apply to the Vue-based manager. The 5.x development material in Developing Extensions for Joomla! 5 (2023) is otherwise a good source for media fields in forms.