Media Management

Last modified: 4/23/2026

Media Management

User guide for the Media Management feature in GeoHazardWatch.

Table of Contents

  1. Overview
  2. Prerequisites
  3. Browsing Media by Year
  4. Browsing by Keyword
  5. Searching Media
  6. Item Detail Page
  7. Embedding Media in Pages (MediaPlugin)
  8. Embedding a Single Photo with Image or ATTACH
  9. Thumbnails
  10. Supported File Formats
  11. Admin: Configuring and Scanning
  12. Configuration Reference
  13. Limitations

Overview

The Media Management feature allows GeoHazardWatch to browse, search, and display media files — photos and videos — stored on external drives or local folders, without moving or modifying the source files. It is designed for large personal or family photo libraries (500,000+ files).

Key facts at a glance

PropertyValue
Source filesNever modified or moved
IndexPersistent JSON, updated on demand
MetadataEXIF / IPTC / XMP (via ExifTool)
ThumbnailsGenerated on first request; cached
BrowseBy year, by keyword, or full-text search
Private awarenessItems linked to private pages are hidden from unauthorised users

The feature is disabled by default. An administrator must enable it and configure at least one media folder before it is accessible.


Prerequisites

The Media Management feature must be enabled and configured by an administrator before users can browse media.

If these prerequisites are not met, all /media/* URLs return 503 Service Unavailable.


Browsing Media by Year

URL: /media

The media home page displays a grid of years for which at least one media item has been indexed. Click any year to see the items from that year.

URL: /media/year/{year}

The year page displays a thumbnail grid of all items indexed for that year, sorted by filename. Each card shows:

Click any card to open the Item Detail Page.


Browsing by Keyword

URL: /media/keyword/{keyword}

The keyword album page displays a thumbnail grid of all indexed media items whose EXIF/IPTC/XMP keyword list contains the specified keyword. Keyword matching is exact and case-sensitive.

The page shows:

How to reach a keyword album


Searching Media

URL: /media/search

The search page provides a free-text search across the media index. All query words must appear somewhere in the item's metadata for the item to appear in results (AND semantics).

Fields searched

FieldExample
FilenameIMG_1234.jpg
Year2023
EXIF titleSummer Vacation
EXIF descriptionAt the beach
EXIF/IPTC keywordsfamily, holiday

Tips


Item Detail Page

URL: /media/item/{id}

The item detail page shows:

JSON API

For programmatic access, the same data is available as JSON:

GET /media/api/item/{id} — single item metadata
GET /media/api/year/{year} — all items for a year


Embedding Media in Pages (MediaPlugin)

The [{MediaPlugin}] plugin lets you embed live media counts, lists, or thumbnail galleries on any page.

Basic syntax

[{MediaPlugin}]
[{MediaPlugin format='count'}]
[{MediaPlugin format='list'}]
[{MediaPlugin format='album'}]
[{MediaPlugin format='album-link'}]

Parameters

ParameterValuesDescription
formatcount (default), list, album, album-linkOutput format
keywordany keyword string, or 'current'Filter by EXIF/XMP keyword
pageany page name, or 'current'Filter by linked page name
yearfour-digit yearFilter by year
maxintegerMaximum number of items to display

Only one filter (keyword, page, or year) should be used at a time. If none is given, all indexed items are included.

format='count'

Outputs the number of matching items as plain text.

[{MediaPlugin}]

Outputs: 14327 (the total number of indexed items)

[{MediaPlugin format='count' keyword='current'}]

Outputs: the count of items whose keywords include the current page name.

format='list'

Outputs a bulleted list of filenames, each linking to its item detail page.

[{MediaPlugin format='list' keyword='Molly'}]
[{MediaPlugin format='list' year='2023' max='10'}]
[{MediaPlugin format='list' page='current'}]

format='album'

Outputs an inline thumbnail grid. Each thumbnail links to the item detail page, and the link includes ?keyword={keyword} when a keyword filter is active so that Prev/Next navigation on the detail page stays within the album context.

[{MediaPlugin format='album' keyword='current'}]
[{MediaPlugin format='album' keyword='Summer 2024' max='20'}]

For keywords that contain an apostrophe, use double quotes around the value:

[{MediaPlugin format='album' keyword="Molly's Cooking"}]

Outputs a styled button that links to the /media/keyword/{keyword} album page. The button shows the keyword name and item count.

[{MediaPlugin format='album-link' keyword='current'}]
[{MediaPlugin format='album-link' keyword="Molly's Cooking"}]

Note: format='album-link' requires a keyword= parameter. It returns an error message if no keyword is provided.

keyword='current' and page='current'

Both keyword='current' and page='current' resolve to the current page's name at render time. This makes the plugin portable — you can add the same snippet to many pages and each page will automatically show its own related media.

[{MediaPlugin format='album' keyword='current'}]

On the page named Molly, this is equivalent to:

[{MediaPlugin format='album' keyword='Molly'}]

Examples

Show a count of all indexed media items:

This platform has [{MediaPlugin}] media items indexed.

Show a thumbnail album of photos tagged with the current page's name:

[{MediaPlugin format='album' keyword='current'}]

Show a link button to a specific keyword album:

[{MediaPlugin format='album-link' keyword='Family Holidays'}]

Show the first 10 items from 2022 as a list:

[{MediaPlugin format='list' year='2022' max='10'}]

Show all media linked to the current page by page association:

[{MediaPlugin format='count' page='current'}] photos are linked to this page.
[{MediaPlugin format='list' page='current'}]


Embedding a Single Photo with Image or ATTACH

To embed a single media library photo inline in page content — rather than a full album — use the media:// URI with Using ImagePlugin or Using AttachPlugin:

[{Image src='media://IMG_1234.jpg' caption='Family Trip 2024' align='center'}]
[{Image src='media://DSC_0042.jpg' align='left' display='float'}]
[{ATTACH src='media://vacation.jpg' caption='Summer 2024'}]

Use the original filename (e.g. IMG_1234.jpg) exactly as it appears in the media index. The file is served from /media/file/:id; items linked to Private Pages are only visible to authorised users.

For layout options (align, display, caption, width, etc.) see Attachments, Using ImagePlugin, or Using AttachPlugin.


Thumbnails

URL: /media/thumb/{id}?size={WxH}

Thumbnails are generated on the first request and cached to disk. Subsequent requests for the same item and size are served from the cache instantly.

Default sizes used by the browser UI: 300x300 (grid), 800x600 (detail).

Any WxH value can be requested via the API. Thumbnails are always JPEG at 85% quality, cropped to fit the requested dimensions (cover mode).

Video files do not have thumbnails in the current version — a film icon placeholder is shown instead. Video playback is available on the item detail page via the HTML5 <video> element.


Supported File Formats

The list of indexed file extensions is configurable via the ngdpbase.media.extensions config key. The default set is shown below.

Images

ExtensionFormat
jpg, jpegJPEG
pngPNG
gifGIF
heic, heifHEIF / HEIC (Apple)
tiff, tifTIFF
webpWebP
raw, orf, cr2, nef, arw, dngCamera RAW formats
bmpBitmap

Videos

ExtensionFormat
mp4MPEG-4
movQuickTime
aviAVI
mkvMatroska
m4viTunes Video
wmvWindows Media Video
3gp3GPP Mobile Video

To add or remove extensions, set ngdpbase.media.extensions to the desired list in your instance configuration. For example, to also index .flv and .webm files:

ngdpbase.media.extensions = ["jpg", "jpeg", "png", "mp4", "mov", "flv", "webm"]

The leading dot is optional — both "jpg" and ".jpg" are accepted. Values are normalised to lowercase.


Admin: Configuring and Scanning

Enabling the feature

In your instance configuration (or app-custom-config.json), set:

ngdpbase.media.enabled = true
ngdpbase.media.folders = ["/path/to/photos", "/path/to/more-photos"]

Restart the server after changing these settings.

Triggering a scan

URL: GET /admin/media

The admin media page shows the current index statistics (number of years indexed, year range) and a Trigger Rescan button.

Clicking Trigger Rescan sends a POST /admin/media/rescan request. The scan runs synchronously and the page shows a summary of the result:

For very large libraries the scan may take several minutes. The browser will wait for the response.

Automatic background scans

The server automatically re-scans all configured folders on a schedule. The default interval is every hour (3600000 ms). Configure with:

ngdpbase.media.scaninterval = 3600000

Set to 0 to disable background scanning.


Configuration Reference

All settings live in the ngdpbase.media.* namespace.

KeyDefaultDescription
ngdpbase.media.enabledfalseEnable the media feature
ngdpbase.media.folders[]Absolute paths to media root folders
ngdpbase.media.maxdepth5Maximum directory depth (0 = unlimited)
ngdpbase.media.scaninterval3600000Background rescan interval in ms
ngdpbase.media.ignoredirs[".dtrash", ".ts"]Directory names to skip during scan
ngdpbase.media.ignorefiles[".photoviewignore", ".plexignore"]Sentinel files that exclude a directory
ngdpbase.media.extensions*(see Supported File Formats)*File extensions to index (overrides built-in list)
ngdpbase.media.index.file*(data dir)*Absolute path to media-index.json
ngdpbase.media.thumbnail.dir*(data dir)*Absolute path to thumbnail cache directory
ngdpbase.media.thumbnail.sizes300x300,150x150Comma-separated size specs
ngdpbase.media.metadata.priority["EXIF","IPTC","XMP"]Metadata extraction priority

ignoredirs and ignorefiles


Limitations

Video thumbnails

Thumbnail generation for video files requires FFmpeg, which is not currently bundled. Video items show a placeholder icon in the grid and detail views. Video playback is supported in the item detail page via the browser's native HTML5 <video> player.

Write access

The media feature is strictly read-only. It never modifies, moves, renames, or deletes source media files.

First scan required

The index is empty until the first scan completes. Year browsing and search return no results before then.

Incremental scans

Background scans compare each file's modification time against the index. If you replace a file with new content but preserve the modification time, the change will not be detected unless you trigger a forced rescan from the admin page.


See Media for an overview, Attachments for uploading files, and Using ImagePlugin, Using AttachPlugin, and Using MediaPlugin for plugin parameter references.