Docs MediaHub Version 1.x Working with Files

Working with Files

Using MediaHub for PDFs, documents, audio, video, and other non-image assets.

Full non-image support from v1.11.0. As of v1.11.0, non-image assets are first-class citizens across the entire MediaHub UI: the TinyMCE picker, Insert Link dialog, Library display, and Inputfield rendering all handle PDFs, videos, audio, and documents natively. See the Rich Text Integration page for TinyMCE and Insert Link details.

MediaHub is not just for images. Every asset in the library is a ProcessWire page, and the same upload, tagging, collection, and querying workflow applies to PDFs, Word documents, spreadsheets, audio files, video files, and anything else your allowed extensions list permits.

What works for all file types

These features are identical regardless of whether the asset is an image, a PDF, an MP3, or a spreadsheet:

  • Upload: drag and drop any allowed file type into the uploader
  • Library browsing: filter by type (Images, Documents, Audio, Video) using the dropdown in the toolbar
  • Tags and collections: organise files with the same tagging and collection system used for images
  • Per-reference metadata: attach page-specific descriptions to a file just as you would to an image
  • Querying: find assets by MIME type, tag, collection, or any ProcessWire selector
  • Picker: the MediaHub field picker in the page editor works for all asset types

What is image-only

A few features depend on the asset having pixel data and are skipped for non-image files:

  • Cropping: the crop editor and crop presets apply only to images
  • Resizing: image(), sized(), and ProcessWire's image API methods require a Pageimage
  • imgTag(): returns an empty string for non-image assets
  • Thumbnail previews: non-image assets display a file-type icon in the library grid instead of a visual preview
  • Thumbnail size slider: in MediaHub fields, the size slider affects images only; non-image assets render as fixed-size detail cards

Rich text and linking

Non-image assets can be inserted into TinyMCE rich text fields and linked via the Insert Link dialog. The TinyMCE picker inserts MIME-appropriate HTML (<video>, <audio>, or <a> download links), and the Insert Link dialog includes a "Select from Media Hub" option for linking highlighted text to any library asset. See Rich Text Integration for full details.

Allowed extensions

The default allowed extensions list is:

jpg jpeg png gif pdf doc docx xls xlsx pptx csv mp3 mp4 wav

You can add or remove extensions in Configuration under Allowed file extensions. For example, adding zip psd makes those file types uploadable. ProcessWire's server-level upload restrictions still apply on top of your list.

SVG uploads are blocked by default regardless of the extensions list, because SVG files can contain embedded scripts and other security risks. Proper SVG support with sanitisation is planned for a future release.

Type detection

MediaHub stores each asset's MIME type and provides methods to check it in template code:

MethodReturns true whenExample MIME types
$asset->isImage()MIME starts with image/image/jpeg, image/png
$asset->isDocument()MIME starts with application/application/pdf, application/msword
$asset->isVideo()MIME starts with video/video/mp4
$asset->isAudio()MIME starts with audio/audio/mpeg, audio/wav

You can also read the raw MIME string and file extension directly:

$asset->mimeType();   // "application/pdf"
$asset->extension();  // "pdf"

Retrieving the file

For non-image assets, use file() or fileUrl() instead of image():

MethodReturnsNotes
$asset->file()Pagefile|Pageimage|nullWorks for every asset type. For images, checks the image field first then falls back to the file field.
$asset->fileUrl()stringThe URL of the primary file, or empty string.
$asset->image()Pageimage|nullReturns null for non-image assets.

Template examples

Download link

$doc = $page->downloads->first();
if ($doc && $doc->isDocument()) {
$file = $doc->file();
echo "<a href='{$file->url}'>Download {$doc->title} ({$doc->extension()}, " .
number_format($file->filesize / 1024) . " KB)</a>";
}

Audio player

foreach ($page->podcast_episodes as $asset) {
if ($asset->isAudio()) {
echo "<div class='episode'>";
echo "  <h3>{$asset->title}</h3>";
echo "  <audio src='{$asset->fileUrl()}' controls preload='metadata'></audio>";
echo "</div>";
}
}

Video embed

$video = $page->featured_video;
if ($video && $video->id && $video->isVideo()) {
echo "<video src='{$video->fileUrl()}' controls preload='metadata' width='800'></video>";
}

Mixed media output

When a MediaHub field holds a mix of images, documents, and other files, use the type-checking methods to render each one appropriately:

foreach ($page->media as $asset) {
if ($asset->isImage()) {
echo $asset->imgTag(800, 600, ['loading' => 'lazy']);
} elseif ($asset->isVideo()) {
echo "<video src='{$asset->fileUrl()}' controls preload='metadata'></video>";
} elseif ($asset->isAudio()) {
echo "<audio src='{$asset->fileUrl()}' controls></audio>";
} elseif ($asset->isDocument()) {
$file = $asset->file();
echo "<a href='{$file->url}'>{$asset->title} ({$asset->extension()})</a>";
}
}

Querying by type

To find all assets of a specific type in the library, query by MIME prefix using a ProcessWire selector:

// All PDFs in the library
$pdfs = $pages->find('template=pkd-mediahub-asset, pkd_mediahub_mime^=application/pdf');
// All audio assets
$audio = $pages->find('template=pkd-mediahub-asset, pkd_mediahub_mime^=audio/');
// All video assets
$video = $pages->find('template=pkd-mediahub-asset, pkd_mediahub_mime^=video/');

You can also filter a specific field's assets in memory:

// Get only the documents from a mixed-type field
$docs = [];
foreach ($page->resources as $asset) {
if ($asset->isDocument()) $docs[] = $asset;
}