Documentation
Bindery docs
Everything to install Bindery, decide what your client can edit, and wire it into any theme — no‑code or with the template API.
Introduction
Bindery lets a developer declare exactly what a client may change on a site, then gives the client a locked, edit‑in‑place experience over only those things. The theme keeps its hand‑written markup; the client edits text on the live page like a document.
It’s built entirely on native WordPress primitives — the Block Bindings API, block.json and the REST API — so it never owns your markup and adds no builder lock‑in.
Installation
- Install from Plugins → Add New → Upload Plugin, or search the directory for “Bindery”.
- Activate Bindery.
- Open Bindery in the admin menu, turn on inline editing and tick which elements are editable.
- Visit any page on the front end and click ✎ Edit page.
No build step or Composer is required to use the plugin — the compiled assets ship in the package. Requires WordPress 6.5+ and PHP 8.1+.
Core concepts
A Bindery field is one editable thing, identified by a key (hero_title), with a type (text, richtext, url, image, repeater…) and a scope:
- Page scope — the value belongs to the post being viewed.
- Global scope — one value shared site‑wide (an announcement bar, a footer line).
Where content is stored
Values live in a dedicated table (wp_bindery_values), one row per field / object / locale — never mixed into your post markup.
How a value resolves
The rule is simple and predictable:
stored override for the current locale (any value the client saved — even "")
└─ else: the default you passed in code The default is never persisted, so improving it in code reaches every site that hasn’t overridden the field.
The settings page
Everything a site owner needs lives under wp‑admin → Bindery:
- Editable Content — turn on inline editing and tick which elements (headings, paragraphs, lists, quotes…) are editable, and on which post types.
- Editing Experience — show/hide the floating button, auto‑enter edit mode, strict mode, and the accent colour.
- Permissions — which roles may edit (Administrators always can).
- History & Data — keep a revision history, set how many versions per field, and Export / Import all values as JSON.
With auto content editing on, that’s the entire setup — no code at all.
The live overlay
For any user with the editing capability, Bindery adds a floating ✎ Edit page button on the front end of singular pages. Clicking it:
- outlines every editable region;
- makes them editable in place;
- saves each on blur, for the current language;
- shows a language switcher when more than one locale exists.
Everything not declared editable is left completely alone. Visitors never receive the overlay or the editing markers — they’re emitted only for capable, logged‑in users.
Auto content editing
The fastest path: make a page’s existing text editable with no code. Enable it on the settings page and pick which tags qualify. Bindery walks the page body and marks each pure‑text element (headings, paragraphs, list items…) with a stable key derived from its position.
- A stored override replaces the element’s text for every visitor; editors get the inline‑edit markers.
- Edits are scoped per page, with revision history.
- Declared regions (blocks /
bindery_attrs()) always take precedence and are never re‑marked.
Disable globally or per post with the bindery/auto_editable filter.
Attribute helper
The cleanest path for a developer who owns the theme. You write the markup; Bindery prints the hooks and resolves the value.
<h1 <?php bindery_attrs( 'hero_title', array( 'type' => 'h1' ) ); ?>><?php
echo esc_html( (string) bindery_value( 'hero_title' ) );
?></h1> bindery_attrs( $key, $args )prints thedata-bindery-*hooks — only for users who can edit, and only when the field isn’t locked.bindery_value( $key )returns the resolved value (override ?? default). You own the tag, so escape it yourself.
A site‑wide field is identical with 'scope' => 'global' — edit it once on any page and it updates everywhere.
// A guarded, site-wide editable line (e.g. in footer.php):
if ( function_exists( 'bindery_attrs' ) ) :
$args = array( 'type' => 'span', 'scope' => 'global', 'default' => '© Acme' );
?>
<span <?php bindery_attrs( 'footer_note', $args ); ?>><?php
echo esc_html( (string) bindery_value( 'footer_note' ) );
?></span>
<?php endif; Blocks
Bindery ships eight self‑contained blocks that store their content in the Bindery store (per locale) instead of in the post markup:
editable‑text · cards · slider · image · button · icon · form · section.
Their colours adapt to the active theme via --bindery-* CSS variables, so they look native anywhere. There are also ready‑made block patterns (Hero, Features, Testimonials, Contact, full Landing page) under the “Bindery” category.
Multilingual
Every field is locale‑aware by default. The overlay’s language switcher reloads the page in a locale, and edits store a value per locale; unedited locales fall back to your code default.
Plug in WPML/Polylang via the bindery/locale_provider filter, or use the built‑in provider with a ?lang= parameter.
Filters & hooks
| Filter | Controls |
|---|---|
bindery/settings | Override any resolved setting in code (wins over the UI). |
bindery/auto_editable | Enable/disable auto content editing per post. |
bindery/strict_overlay | Overlay edits only hand‑coded regions, not blocks. |
bindery/storage_adapter | Swap the storage backend (table, meta, custom). |
bindery/locale_provider | Provide locales (WPML / Polylang adapter). |
bindery/record_history · bindery/history_cap | History on/off and version cap. |
Actions: bindery/register (register custom field types/sources), bindery/booted, bindery/activated.
History & migration
Every edit is recorded with who changed it and when (capped per field, configurable). Restore any past value with one click, or move all values between sites.
From the settings page
History tab → Export values (JSON) to download a full snapshot, or pick a file to Import.
From WP‑CLI
wp bindery export --file=values.json # export all values
wp bindery import --file=values.json # import (history-suppressed)
wp bindery history hero_title --object=9 --locale=en_US # list versions
wp bindery restore 42 # restore to version #42 Imports are sanitised (wp_kses_post) and bounded, so a hand‑edited file can’t inject scripts or exhaust storage.
Security model
- Capability‑gated. Editing requires
bindery_edit_content; settings requiremanage_options. Administrators always retain the editing capability. - Whitelisted writes. The editor endpoint accepts writes only for fields present on the page, rejects locked fields, and re‑checks the per‑field capability.
- Sanitised in, escaped out. Each field type sanitises on save and escapes on render (
esc_html,wp_kses_post,esc_url…). - Visitors get clean markup. The editing hooks and overlay assets are emitted only for capable, logged‑in users.
FAQ
Does Bindery change my theme’s markup?
No. It resolves a value and outputs your own clean markup. Editable regions are marked with data-* attributes emitted only for logged‑in editors.
Do I have to write code?
No. With auto content editing enabled, your existing page text becomes editable with zero code. The template API exists for developers who want precise, per‑region control.
Can a client break the layout?
No. Only the regions you declared editable can change. Everything else is untouchable.
Can I move content between sites?
Yes — export/import all values as JSON from the settings page or with wp bindery export / import.
Ready to try it?
Install Bindery, tick what’s editable, and hand your client a site they can update.
Download v0.1.0Pre‑release v0.1.0 · pending review on WordPress.org