Open Source · GPL v3 · WordPress 6.0+

Image Compression & Metadata
the way it should work.

Metamanager pairs WordPress's media library with OS-level daemons to deliver truly lossless image compression, bidirectional EXIF/IPTC/XMP metadata sync, GPS coordinate import, and automatic Schema.org and Open Graph output — all managed natively from your dashboard.

wget -qO- https://raw.githubusercontent.com/richardkentgates/metamanager/main/install.sh | sudo bash

What Metamanager Does

PHP can't do lossless compression or write IPTC and XMP. Metamanager can.

🗜

True Lossless Compression

JPEG files are optimised with jpegtran — no re-encoding, no quality loss, no pixel changes. PNG files are processed by optipng. Files are only replaced if the result is smaller.

🏷

Full Metadata Standards

Write EXIF, IPTC, and XMP simultaneously via ExifTool — the industry standard. Every tag written in all three formats at once for maximum compatibility across editing software, search engines, and CMS platforms.

🔄

Bidirectional Metadata Sync

On upload, embedded EXIF/IPTC/XMP tags are read from the file and used to pre-populate WordPress fields automatically. User-set values are never overwritten. Edit fields in WordPress and the daemon writes them back into the file.

📍

GPS Coordinates

When clients shoot with location services enabled, Metamanager reads GPS latitude, longitude, and altitude directly from the camera's EXIF data. No manual entry — coordinates are imported and stored automatically at upload time.

🔍

Schema.org & Open Graph

Every attachment page and post with a featured image automatically receives an ImageObject JSON-LD block and Open Graph tags. When GPS data is present, a full GeoCoordinates object is included — everything Google Images and social platforms need.

🖥

Native Dashboard Integration

Custom fields on every image edit screen. A live compression-status column in the Media Library. Searchable job history. All inside WordPress — no separate admin interface to learn.

Asynchronous by Design

Image uploads never slow down. Jobs are queued as JSON files. Two inotifywait-powered daemons process them immediately in the background. Results feed back into WordPress via WP-Cron.

🔒

Bulk Without False Attribution

Bulk actions are limited to injecting Publisher and Website — neutral site provenance only. Creator, Copyright, and Owner are individual fields, intentionally never overwritten in bulk.

🔁

Re-queue Failed Jobs

Every failed job appears in the history table with a one-click Re-queue button. No manual file hunting, no WP-CLI commands needed to recover from a temporary failure.

📦

Native Auto-Updates

Integrates with the WordPress update pipeline. New releases published to GitHub appear automatically in Dashboard → Updates — update with one click, just like any other plugin. A manual “Check for Updates” link is also available on the Plugins page.

How It Works

PHP coordinates. The OS executes. Clean separation of responsibility.

1

Upload or Edit

On upload, embedded metadata is read from the file into WordPress fields. On edit, changed fields are queued for writing back to the file.

2

Job Written

Metamanager writes a small JSON job file to the queue directory. PHP does nothing else.

3

Daemon Processes

inotifywait detects the new file. The daemon processes the image with jpegtran, optipng, or ExifTool.

4

Result Recorded

The daemon writes a result JSON to the completed folder. WP-Cron picks it up every minute and records it in the database.

WordPress (PHP)                  OS (Bash Daemons)
────────────────                 ──────────────────────────────────
Upload image
        │
        ▼
import_from_file()         ◄── ExifTool reads embedded tags
  populates empty WP fields         (EXIF / IPTC / XMP / GPS)
        │
        ▼
Write job JSON to          ◄── inotifywait detects new file
  metamanager-jobs/                      │
  compress/ or meta/                     ▼
                                  Process image:
                                    jpegtran / optipng  [compression]
                                    ExifTool            [metadata write]
                                         │
WP-Cron (60s) ◄──── result JSON ────────┘
reads, inserts to DB,
updates history table

Keeping Metamanager Up to Date

Two methods — choose what fits your workflow.

📦

WordPress Dashboard (recommended)

Metamanager integrates with the native WordPress update system. When a new release is tagged on GitHub, it appears in Dashboard → Updates automatically within 12 hours. Click Update now — exactly the same as any other plugin.

A Check for Updates link is available next to the plugin on Plugins → Installed Plugins for an immediate check.

🖥

Server Script (plugin files only)

Use --update to sync only PHP, JS, and asset files. Daemons keep running, dependencies are not reinstalled, and systemd services are not restarted — zero downtime for the compression and metadata pipelines.

sudo bash install.sh --update

Metadata Field Map

Every logical field writes to all three standards simultaneously.

Field Set By EXIF IPTC XMP
WordPress Native — bidirectional sync
Title WP Post Title Title ObjectName Title
Description WP Post Content ImageDescription Caption-Abstract Description
Caption WP Excerpt Caption-Abstract Caption
Alt Text WP Alt Field AltTextAccessibility
Attribution & Rights — per-image only, never bulk
Creator Per-image Artist By-line Creator
Copyright Per-image Copyright CopyrightNotice Rights
Owner Per-image OwnerName Owner
Editorial
Headline Per-image Headline Headline
Credit Per-image Credit Credit
Classification
Keywords Per-image Keywords Subject
Date Created Per-image DateTimeOriginal DateCreated DateCreated
Rating (0–5) Per-image Rating
Location — IPTC Photo Metadata Standard
City Per-image City City
State / Province Per-image Province-State State
Country Per-image Country-PrimaryLocationName Country
GPS — read-only, auto-imported from camera EXIF
Latitude GPS Auto Composite:GPSLatitude
Longitude GPS Auto Composite:GPSLongitude
Altitude (m) GPS Auto Composite:GPSAltitude
Site Provenance — bulk-safe, neutral
Publisher Site Name (auto) Source Publisher
Website Site URL (auto) Source WebStatement

Per-image fields are never touched by bulk actions. Only Site auto fields (Publisher + Website) can be injected in bulk — neutral provenance, not an ownership claim. GPS Auto fields are imported from the camera at upload time and are never editable in the UI.

Schema.org & Open Graph

Every image page gets structured data automatically — no configuration required.

🔍

Schema.org ImageObject

A full JSON-LD block is emitted in <head> on attachment pages and any post with a featured image. Includes name, description, creator, copyright, keywords, date, location, and GPS coordinates when available. Eligible for Google Images rich results and Google Discover.

📲

Open Graph Tags

Correct og:image, og:image:alt, og:image:width, og:image:height, and og:image:type tags are written for every image. Social platforms — Facebook, LinkedIn, Slack, iMessage — use these to generate accurate link previews.

⚖️

License Link

When a copyright value is set, Metamanager emits <link rel="license"> for URL-format values (e.g. Creative Commons URIs) or <meta name="copyright"> for plain-text notices — giving crawlers and aggregators a machine-readable rights signal.

Sample ImageObject JSON-LD output

{
  "@context": "https://schema.org",
  "@type": "ImageObject",
  "url": "https://example.com/wp-content/uploads/2026/01/photo.jpg",
  "contentUrl": "https://example.com/wp-content/uploads/2026/01/photo.jpg",
  "width": 4032,
  "height": 3024,
  "name": "Sunrise over the ridge",
  "description": "Morning light breaking through the canyon walls.",
  "headline": "Golden Hour in Red Rock Canyon",
  "creditText": "Jane Doe / Mountain Light Photography",
  "creator": { "@type": "Person", "name": "Jane Doe" },
  "copyrightNotice": "© 2026 Jane Doe",
  "copyrightHolder": { "@type": "Organization", "name": "Mountain Light Photography" },
  "keywords": ["landscape", "sunrise", "canyon", "nature"],
  "dateCreated": "2026-01-15",
  "locationCreated": {
    "@type": "Place",
    "name": "Boulder, CO, USA",
    "geo": {
      "@type": "GeoCoordinates",
      "latitude": 40.014984,
      "longitude": -105.270546,
      "elevation": 1655.0
    }
  },
  "contentLocation": { "@type": "Place", "name": "Boulder, CO, USA", "geo": { ... } },
  "thumbnail": { "@type": "ImageObject", "url": "https://example.com/.../photo-300x225.jpg" },
  "mainEntityOfPage": { "@type": "WebPage", "@id": "https://example.com/?attachment_id=42" }
}

Install in One Command

Works on Ubuntu 22.04+, Debian 12+, RHEL/Rocky 9+. Requires systemd and root access.

One-command installer (auto-detects WordPress path)
wget -qO- https://raw.githubusercontent.com/richardkentgates/metamanager/main/install.sh | sudo bash
With explicit WordPress path
sudo bash install.sh --wp-path /var/www/html
Update plugin files only (keeps daemons running, skips dependencies)
wget -qO- https://raw.githubusercontent.com/richardkentgates/metamanager/main/install.sh | sudo bash -s -- --update

What the installer does

  1. Detects your WordPress installation path
  2. Installs jpegtran, optipng, exiftool, inotify-tools, and jq via apt or dnf
  3. Copies the plugin into wp-content/plugins/metamanager/
  4. Patches daemon scripts with your actual WP_CONTENT_DIR — no hardcoded paths
  5. Installs and starts both systemd daemons as www-data
  6. Activates the plugin via WP-CLI if available
WordPress
6.0+
PHP
8.0+
ExifTool
any
jpegtran
any
optipng
any
systemd
v232+

Open Source Credits

Metamanager is built on the shoulders of these outstanding open source projects. Full credit and gratitude to their authors and maintainers.

🏷

ExifTool

Phil Harvey
Artistic License / GPL

The backbone of all metadata work in Metamanager. ExifTool reads and writes EXIF, IPTC, and XMP tags across virtually every image format in existence. We use it to import embedded metadata on upload and to write all metadata fields back to the file.

🗜

libjpeg-turbo / jpegtran

libjpeg-turbo Project · Independent JPEG Group
BSD / IJG License

jpegtran performs lossless JPEG optimisation — reordering Huffman tables and enabling progressive scan without decoding or re-encoding a single pixel. The IJG created the original implementation; libjpeg-turbo maintains and accelerates it.

🖼

optipng

Cosmin Truță
zlib / libpng License

optipng tries multiple DEFLATE parameters and filter combinations to find the smallest lossless PNG representation. No pixels are changed. We use -o2 -preserve to balance speed and compression while retaining all file metadata.

👁

inotify-tools

inotify-tools contributors
GPL v2

inotifywait is what makes the daemons instant-response rather than polling. When a job file is written, inotifywait fires immediately — no sleep loops, no latency. The Linux kernel's inotify subsystem watches; inotify-tools provides the userspace interface.

{ }

jq

Stephen Dolan · jqlang organisation
MIT License

jq is used inside the Bash daemons to parse job JSON files written by PHP — extracting field values by key without requiring any additional runtime. Lightweight, dependency-free in execution, and universally available on our supported Linux distributions.

systemd

systemd contributors
LGPL v2.1+

The compression and metadata daemons run as systemd services. systemd manages process lifecycle, automatic restart on failure, boot-time startup, and journal-based logging. We use a PID-file pattern so the WordPress plugin never needs systemctl privileges.

🌐

WordPress

WordPress Foundation & contributors
GPL v2+

Metamanager is a WordPress plugin and relies on the WordPress API — hooks, post meta, REST API, WP-Cron, the admin UI framework, media handling, and the plugin update pipeline. WordPress is itself GPL v2+, the reason Metamanager is GPLv3 (a compatible later version).

Aa

Inter & JetBrains Mono

Rasmus Andersson · JetBrains
SIL Open Font License 1.1

The typefaces used on this website. Inter (Rasmus Andersson) for UI text; JetBrains Mono (JetBrains) for code samples. Both are served via Google Fonts and are not bundled with the plugin itself.