Skip to main contentSkip to footer
    Back to Case Studies
    Jules BretonCatalogue raisonné, julesbreton.com
    WordPressCustom PluginArt Archive

    Jules Breton Archive

    An online catalogue raisonné of the 19th-century French painter Jules Breton, with more than a thousand catalogued works. We maintain the custom plugin that makes it searchable, sortable and protected, and when edits started disappearing we found out exactly why.

    Project Preview

    Live website preview - julesbreton.com

    1,159
    Published artwork posts in the catalogue
    16
    Decade categories: eight for paintings, eight for drawings
    3,933
    Lines in the custom plugin's main file
    39
    Commits from March to June 2026

    UID-based catalogue order

    Every work carries a UID such as P1844-01 or D1865-09. Galleries sort by the year inside the UID, then its sequence number, so the catalogue reads the way a printed raisonné does.

    AJAX search and filters

    Exact-year and keyword search over the catalogue without a page reload, with a shared keyword taxonomy across both catalogues.

    Password-protected galleries

    A shortcode renders the category grid and artwork grid behind a password stored in ACF options, with separate passwords for paintings, drawings and the second catalogue.

    A second catalogue

    A separate custom post type with its own hierarchical categories, gallery and search shortcodes, AJAX action and permalink base, sharing the keyword taxonomy with the first.

    Auto-categorisation on save

    Saving a work extracts the year from its UID, fills the year fields and assigns the right decade term, so editors type one identifier rather than four fields.

    Three cache layers, purged in order

    LiteSpeed page cache, the host CDN and the browser. Every deploy ends with a purge, because stale HTML is the most common false bug report on this site.

    The archive

    Jules Breton (1827–1906) painted rural life in Artois and Brittany, and julesbreton.com is the online catalogue raisonné of his work: paintings and drawings organised by decade from 1844 to 1906, plus undated works, each with a unique identifier, provenance and bibliography. At 1,159 published works it is a serious scholarly resource, curated by an editor who works in the WordPress admin every week.

    Frenchy Digital took over the site in March 2026. The custom plugin that drives it had grown organically, WordPress core was managed by the host, and there was no version control, no staging discipline and no activity log. The first month went into fixing what visitors could see: a pagination cap that hid works from category pages, gallery links broken by a typographic ligature filter rewriting "oe" to "œ" inside URLs, and a single-artwork layout that overflowed when descriptions used column blocks.

    What a catalogue raisonné needs from its software

    • A stable identifier: P and D prefixes for paintings and drawings, PND and DND for undated works, sequential within each year.
    • Scholarly ordering: Sort by the year in the UID, never by a free-text year field that may contain a range like 1844–1850.
    • Controlled access: Some galleries are password-protected for researchers; the public sees the introduction, biography and methodology.
    • An editor who can trust the save button: A hand-corrected date must survive the next save.

    The plugin

    How the catalogue is modelled

    Works are posts with a UID meta field and derived year fields. Sixteen decade categories, eight for paintings and eight for drawings, are hard-coded in the plugin, along with a handful of non-catalogue categories for doubtful attributions and unknown supports that never render on the front end. A function decides whether a post is a drawing by checking category membership first and the UID prefix second, and the gallery sort extracts the year from the UID before falling back to meta, because meta can hold ranges and PHP casts "1844-1850" to 1844.

    Search, galleries and the single view

    The protected-gallery shortcode handles password authentication, the category grid and the artwork grid with UID sorting. An AJAX handler serves exact-year and keyword search from script.js. A custom single template renders each work with a Slick slider for its images. In June 2026 we added a second catalogue as a separate custom post type with its own hierarchical category taxonomy, gallery and search shortcodes, AJAX action and permalink base, sharing the keyword taxonomy so cross-catalogue keyword browsing works. Auto-categorisation for the new type looks terms up by slug, so the editor creates the decade terms once and the plugin does the rest.

    The forensic audit

    In April 2026 the client reported that corrections made months earlier had disappeared from the drawings. That is the worst kind of bug report for an archive: no error, no timestamp, just missing scholarship. We treated it as an investigation rather than a fix.

    Who changed what

    Session tokens in user meta, the last-editor field on each post, trash timestamps and our own tooling transcripts were cross-referenced to attribute every trashing and UID change in the window to a specific actor and minute.

    What it turned out to be

    A deliberate catalogue consolidation by the editor: duplicates merged, UID sequences tightened, a miscategorised work rewritten. Canonical, and correctly left alone. Neither our tooling nor any automation had deleted anything.

    The real bug

    The save hook wrote first_year from the UID on every save with no empty check, unlike its two sibling fields. Any hand-entered first year that differed from the UID year was reverted on the same save, silently.

    The fix and the safety net

    A guard so first_year is only populated when empty, deployed to live by the project's SCP convention with no downtime, and an activity-log plugin installed so future questions are answered from the dashboard.

    A drawing with any non-empty first_year, typed by the editor, set by an import, set by a prior backfill, is never overwritten by the save hook. Full stop.

    Fix report, 15 April 2026

    How the site is run

    Plugin changes deploy to staging by SCP, are verified, then deploy to live
    Every deploy ends with a LiteSpeed purge and a cache flush; the host CDN is purged from the panel
    WP-CLI on the server for content operations, with category slugs rather than numeric ids to avoid creating duplicates
    UIDs are trimmed before comparison because some carry leading whitespace from historical imports
    Server-side PHP settings live in wp-config because the host ignores .user.ini
    Rewrite rules are flushed after the second catalogue's permalinks change

    Where it stands

    What we can and cannot claim

    The catalogue is live at julesbreton.com, in French. The published-post count comes from the project documentation; the category, plugin-size and commit counts are taken from the repository. The site's visual design and its page-builder layouts predate our engagement; our scope is the custom catalogue plugin, deployment discipline, the audit and fix described above, and ongoing maintenance. We have no analytics access for this client and make no traffic claims.

    What This Project Does Well

    The catalogue's whole wp-content tree, 33 plugins and database dumps are in version control, with backup archives and TIFF originals excluded by policy
    Staging first, then live: every plugin change is deployed to a staging copy and verified before it touches the public catalogue
    A forensic audit that reconstructed a week of catalogue edits from session tokens, post meta and trash timestamps, and cleared both the client's editor and our own tooling of any data loss
    A one-guard fix that stopped the save hook from silently reverting hand-curated dates, deployed with zero downtime
    An activity log installed so the next 'who changed this' question is answered from the dashboard, not a forensic report
    Gallery pagination cap removed, ligature-filter URL breakage fixed, single-artwork layout overflow fixed, all within the first month

    Technologies Used

    WordPress 6.9 on Hostinger with LiteSpeed Cache and the host CDN, PHP, a single-file custom plugin (jules-breton-master-4) with templates, script.js and style.css, ACF Pro, Elementor and JS Composer, Slick slider on single-artwork views, Simple History, WP-CLI, MySQL, deployment by SCP

    Ready to Build Something Similar?

    Let's discuss how we can help transform your business with a custom digital solution.