WordPress plugin · v1.0

Client proofing, uncompromised.

A WordPress plugin that turns your site into a client proofing system. Send galleries. Let them pick. Own every pixel.

Scroll

— Manifesto

You don't just shoot. You curate. Your tools should respect that.

Most client proofing tools treat your photographs like products in a checkout flow. PhotoProof treats them like a body of work.

Self-hosted on your own WordPress. No subscription. No pixel ceiling. No data handed to a third party. Just your galleries, your clients, your rules.

01

Step one

You shoot.

Weddings, portraits, editorials, product — whatever fills your card. Then comes the part that makes or breaks the relationship: getting the client to choose.

02

Step two

You share.

Create a gallery in your WordPress admin. Assign a client, set a watermark, rename files, lock it down with an expiration date. Send the link.

  • Per-gallery watermarks Opacity, position, custom logo.
  • Smart file renaming Mariage-Dupont-001.jpg, automatically.
  • UUID private URLs Unguessable. No password walls.
  • Expiration dates Auto-lock after deadline.
yoursite.com/wp-admin/post.php
PhotoProof admin interface
yoursite.com/gallery/a8f3...
Client gallery view
03

Step three

They select.

A distraction-free, standalone gallery experience. No theme noise. No tracking scripts. Just the photographs, full-bleed, and a single tap to pick favorites.

  • Isolated template Your theme's scripts can't interfere.
  • Fluid animations Tactile feedback, clients love it.
  • Photographer recommendations Guide their eye, optional badges.
04

Step four

It's done.

They confirm. You get notified by email. Export their selection as a CSV. Move on to the next shoot with a clean handoff behind you.

  • Email notifications Customizable templates, both sides.
  • CSV export Filenames ready for your Lightroom pipeline.
  • Reopenable Keep or reset, your call.
yoursite.com/gallery/a8f3...
Confirmation modal

— Under the hood

Everything included.
Nothing withheld.

Full feature list. No "premium tier" hiding behind a paywall. No "contact sales" for the good stuff. Everything ships in v1.0.

Security

Watermarks that actually ship

Auto-applied on upload. Adjustable opacity from 10% to 100%. Per-gallery toggle. Your logo, your rules.

Built-in
©
No limits

Unlimited galleries

No photo caps. No gallery caps. Your server is the only limit.

Upload

Bulk drag-and-drop

Drop 500 photos at once. Live progress, resumable.

Upload

Media library isolation

Gallery photos stay out of your main WP media library.

Automation

Smart file renaming

Pattern-based, auto-incremented.

IMG_4821.jpg
Mariage-Dupont-001.jpg
Client experience

A theme-proof template

The gallery runs in its own template. Your WordPress theme, its scripts, its tracking — none of it touches the client view.

// Your theme scripts
barba.js · analytics.js · ...
// Gallery runs clean
photoproof-public.js
Security

UUID private URLs

/gallery/a8f3-c2e9-...

Unguessable. No password walls.

Security

Gallery expiration

Set a deadline, gallery auto-locks. Daily cron handles it.

Security

Right-click disabled

Optional protection against casual downloads.

Notifications

Two inboxes.
Both notified.

When a client validates, the photographer gets the list, the client gets the receipt. Fully editable templates with placeholders.

{gallery_name} {client_name} {count} {photos} {url}
Export

CSV export

Selection as a file list. Lightroom-ready import.

filename,status
Mariage-Dupont-012.jpg,selected
Mariage-Dupont-018.jpg,selected
Mariage-Dupont-024.jpg,...
Workflow

Reopen for edits

Client changed their mind? Reopen with or without reset.

Client

Dashboard shortcode

[photoproof_galleries_client]

Lists all client's galleries on any page.

Customization

Full color theming

Background, text, selection. No code.

+
Branding

Custom logo

Your brand mark on every gallery header.

Workflow

Recommendation badges

Mark your top picks. Star or heart, your choice.

Philosophy

Self-hosted.
GPL v2.
Yours forever.

No external API calls. No vendor lock-in. Your database, your files, your decisions. Fork it if you want. Audit the source end-to-end.

Zero tracking Zero analytics Zero dependencies
International

5 languages, translate-ready

EN
FR
DE
IT
ES

Full .pot for more.

Workflow

Client assignment

Link galleries to WP users. Multi-gallery per client.

Developer

Action & filter hooks

photoproof_gallery_selection_confirmed

Extend freely, WP-native.

Stack

PHP 7.4+ · WP 6.4+

Modern baseline. No legacy cruft. WP.org certified.

— Developer reference

Extend it.
Without waiting for us.

PhotoProof exposes action hooks, filters, helper functions and a shortcode. Everything you need to wire it into your own workflow — or build a plugin on top.

01

Action hooks

Fire your own code when PhotoProof does something.

do_action

photoproof_gallery_selection_confirmed

Triggered the moment a client validates their selection. Perfect for custom notifications, CRM sync, or analytics.

// Log validated selections to your CRM
add_action( 'photoproof_gallery_selection_confirmed',
  function( $gallery_id, $selected_ids ) {
    my_crm_sync( $gallery_id, $selected_ids );
  }, 10, 2 );
$gallery_idint — Post ID of the gallery
$selected_idsarray — Attachment IDs selected by the client
do_action

photoproof_attachment_uploaded

Fires after a photo is successfully uploaded into a gallery (after watermark & rename). Use it for post-processing.

// Push uploaded photos to external storage
add_action( 'photoproof_attachment_uploaded',
  function( $attachment_id, $gallery_id ) {
    push_to_s3( $attachment_id );
  }, 10, 2 );
$attachment_idint — Attachment ID of the new photo
$gallery_idint — Parent gallery ID
do_action

photoproof_daily_expiration_check

Cron event fired once a day. Used internally to archive expired galleries — hook in to add your own maintenance.

// Add your own daily cleanup
add_action( 'photoproof_daily_expiration_check',
  function() {
    my_custom_cleanup();
  } );
No parameters
02

Template tags

Public PHP functions — call them from any theme template.

function

photoproof_get_client_galleries

Return every gallery assigned to a given user. Ideal for a client dashboard page outside the shortcode.

$galleries = photoproof_get_client_galleries( $user_id );

foreach ( $galleries as $g ) {
  echo $g['title'] . ' — ' . $g['status'];
}
$user_idint — User ID to query
@returnarray — Galleries with keys: title, url, status, photo_count, date, thumbnail_url
function

photoproof_get_gallery_status

Current lifecycle state of a gallery: brouillon, publie, valide, archive.

$status = photoproof_get_gallery_status( $post_id );

if ( $status === 'valide' ) {
  echo 'Client has confirmed.';
}
$post_idint — Gallery post ID
@returnstring — Status slug
function

photoproof_get_gallery_photo_count

Number of photos currently attached to the gallery. Cached for 60 seconds.

$count = photoproof_get_gallery_photo_count( $post_id );

echo $count . ' photos in this gallery';
$post_idint — Gallery post ID
@returnint — Photo count
function

photoproof_get_gallery_thumbnail

URL of the gallery's cover image, in any WordPress image size.

$url = photoproof_get_gallery_thumbnail( $post_id, 'large' );

echo '<img src="' . esc_url( $url ) . '">';
$post_idint — Gallery post ID
$sizestring — WP image size. Default: medium
@returnstring — Thumbnail URL, or empty string
function

photoproof_get_gallery_selection

Get the array of attachment IDs that the client selected. Returns an empty array if the gallery isn't validated yet.

$selected = photoproof_get_gallery_selection( $post_id );

foreach ( $selected as $att_id ) {
  echo wp_get_attachment_image( $att_id );
}
$post_idint — Gallery post ID
@returnarray — Selected attachment IDs
function

photoproof_is_gallery_locked

Whether the gallery is locked (validated or archived). Useful for conditional display.

if ( photoproof_is_gallery_locked( $post_id ) ) {
  echo 'Selection is final.';
}
$post_idint — Gallery post ID
@returnbool
03

Shortcode

Drop it into any page or post.

shortcode

[photoproof_galleries_client]

Displays a grid of galleries assigned to the currently logged-in user. Requires authentication — shows a notice otherwise.

// Minimal usage
[photoproof_galleries_client]

// Custom layout, status hidden
[photoproof_galleries_client columns="3" show_status="false"]

// Everything disabled except title and thumbnail
[photoproof_galleries_client columns="2"
  show_status="false"
  show_count="false"
  show_date="false"]
columnsint — Grid columns, 1 to any. Default: 1
show_statusbool — Show open / validated dot. Default: true
show_countbool — Show photo count. Default: true
show_datebool — Show creation date. Default: true

— Support

Fuel the next release.

PhotoProof is free and always will be. If it saved you a monthly subscription or a long afternoon of coding, consider throwing something in the jar.

Every donation goes directly into development time — new features, bug fixes, better docs. No middlemen.

— Get started

Free.
Forever.
Yours.

Install it like any WordPress plugin. Configure in five minutes. Send your first gallery before lunch.

Tested on WordPress 6.4+ · PHP 7.4+ · MIT & GPL dependencies only