Aumframe

Description

Aumframe is a visual editor built around one idea: you design a template, and the template decides which pages it draws. Give it a rule — the front page, every post in a category, single products, search results, 404 — and every page that matches is laid out by that one design. Change the design once and all of them change.

Layout is done with frames and relational sizing rather than fixed columns, so a row can say “this part takes the space that is left” instead of “this part is 480 pixels”. The same design holds together at phone width without a separate mobile version to maintain.

What it gives you:

  • Templates by rule — front page, singular, archive, taxonomy term, search, 404, plus per-slug rules and a priority when two rules could both match
  • A shell with a slot: the header and footer you design once, with each template’s content dropped into the slot
  • Reusable components — build a card once, place it anywhere; editing the component updates every instance
  • Dynamic data — bind text, images and links to the post, term, author, meta field or query being shown, so one design fills itself from content
  • Loops — a row that repeats over a query, with the query written in the editor rather than in code
  • Motion — entrance, scroll-linked and looping animation, compiled to the same output the front end uses
  • Revisions on every design, with a read-back check so a save that did not land is reported instead of silently lost
  • Per-language variants of a design, for sites running a translation plugin
  • Kits — export a whole site’s designs, content model, components and media as one file, and import it into another site

Aumframe does not render your designs on every page load. The layout is compiled to HTML and CSS in the browser when you save, and PHP only fills in the dynamic parts. There is one compiler, in one language, so what you see while editing is what visitors get.

Where it stores things

Four tables of its own: aumframe_templates, aumframe_revisions, aumframe_template_i18n and aumframe_components. Your posts, pages and media stay where WordPress keeps them — Aumframe reads them, it does not move them.

WP-CLI

  • wp aumframe import <file> — import a kit
  • wp aumframe kit-requires <file> — print what a kit needs before you import it

Build

The front end runs the source directly; nothing about it is compiled. The editor is bundled because it is written with JSX, and because one file means one ?ver= to invalidate.

Everything needed to rebuild it ships inside this plugin — packages/core/src, packages/editor/src, packages/runtime/src, build.mjs, package.json and package-lock.json. From the plugin’s own folder:

npm ci && node build.mjs

That writes three files, and the build is deterministic — the same source and the same lockfile give byte-identical output. For this release, sha256:

  • assets/editor.js — acb7f130204650a0a9a53f02986362b282ae0343d68eed92a7a4ad143a2bd586
  • assets/motion.js — 1992377aa2274be47ce353652169f659032f020694eeb4b84c4048136771b637
  • assets/editor.css — 125b366178f856065f4e11bf283cade2182cc09a93c528db1e6ba1e0502de313

Built and checked with Node 24 and esbuild 0.25. The other files in assets/ are written by hand and are not build output.

npm test runs the core, schema, style, editor-store and renderer suites, plus a regression that re-bakes the templates of three frozen reference sites and requires the output to be byte-identical.

Installation

  1. Upload the aumframe folder to /wp-content/plugins/, or install the zip from Plugins > Add New
  2. Activate the plugin through the Plugins screen
  3. Open Aumframe in the admin menu and create your first design
  4. Give it a rule — start with the front page — and save

FAQ

Does it replace the block editor?

No. A design only takes over the pages its rule matches; everything else keeps rendering the way your theme renders it. On a page that Aumframe draws, the block editor still opens and still stores your content — Aumframe shows that content in the place its design gives the page body.

Does it work with my theme?

For the pages it draws, Aumframe supplies the whole document, so the theme’s templates are not involved. The header and footer on those pages come from the shell you design. Themes that add styles or scripts through the normal hooks keep working.

What happens to my designs if I deactivate the plugin?

Pages go back to being rendered by your theme. Nothing is deleted — the designs stay in their tables and come back when you reactivate. Deleting the plugin removes them.

Is the editor’s JavaScript included as source?

Yes. packages/core/src, packages/editor/src and packages/runtime/src ship with the plugin. The front-end runtime is plain ES modules and is loaded as-is, with no build step at all. Only the editor is bundled, into assets/editor.js, with esbuild — see Build below.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Aumframe” is open source software. The following people have contributed to this plugin.

Contributors

Translate “Aumframe” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

The full history, including older releases, is in changelog.txt inside the plugin folder.

1.39.3

  • Changed: stylesheets are now generated by the plugin from a template’s own stored values.
    The save endpoints and the kit importer no longer read CSS from what they are given: the
    compiler walks the node tree, emits one rule per node and builds every selector itself from
    an identifier it has checked.
  • Changed: a style rule written as text is parsed into declarations and rebuilt rather than
    passed through. A declaration is kept when its value uses only the functions listed in
    packages/core/src/css-properties.json; url() is refused outright, since a fill or an
    image is its own field and carries an attachment id. The only at-rules kept are a width
    media query and an animation definition.
  • Changed: a selector that does not name part of the design is now contained by the design’s
    own root, so a rule can no longer reach the rest of the page.
  • Changed: a component’s stylesheet now covers its own nodes only. The front end follows the
    component markers inside component markup as well, so a component used solely inside another
    one keeps its styles.
  • Fixed: an animation definition written in a template’s style rules used to be discarded.
  • Fixed: array_is_list() is a PHP 8.1 function, and WordPress began shipping a fallback for
    it in 6.5. This plugin supports PHP 7.4 and WordPress 6.2, where the new compiler would
    have stopped the site on sight. It no longer calls it.
  • Fixed: a translator comment was missing from one importer warning.
  • Fixed: a rule aimed above the design — html body { padding-left }, which a sidebar pinned
    to the viewport uses to keep the page’s own content clear of it — was being contained by the
    design’s root, where it matched nothing. Custom properties and page spacing on the document
    element are now left where they were written; anything else aimed outside is still contained.
  • Changed: which selectors are contained by the design’s root. A rule written with nothing
    but element names sweeps the whole document and is contained; a rule naming a class, an id
    or an attribute is aimed at something specific and is left as written. Whether that element
    sits inside the design cannot be told from the selector, and much of what a design styles is
    printed outside its root by something else — a booking modal goes out on wp_footer — so
    containing those selectors stopped them matching instead of making them safe.

1.38.2

  • Changed: wording in two older changelog entries below. They now state what changed and what
    to use instead. Nothing in this plugin is locked, limited or behind a key.

1.38.1

  • Changed: the plugin’s own source comments. 322 blocks of design history and commentary were
    removed from the files that ship, and the remaining annotations are all in English, as the
    code and the strings already were. No behaviour changes with it. The reason is specific: an
    automated review had read our comments as a description of what the plugin does, and a
    comment that is read that way is worse than no comment.
  • Changed: WP-CLI output (wp aumframe import, kit-requires, doctor) is now in English,
    matching the rest of the plugin.

1.38.0

  • Fixed: with the view counter enabled, every single post page carried a broken piece of
    JavaScript. The script was assembled in a way that left four pieces of PHP in it
    unevaluated, so the browser saw a syntax error and the counter never ran. Nothing was
    logged, because PHP itself raised nothing.
  • Changed: the editor now sanitises the compiled HTML and CSS it stores. The compiler runs in
    the browser and the result arrives over the REST API, so it is treated as submitted data:
    it is filtered against WordPress’s own allow-list for post content, plus the elements and
    attributes the renderer needs. Script elements, event-handler attributes and script URLs
    cannot be stored. Every one of the 1304 compiled documents in our 24 templates passes
    through with nothing removed.
  • Changed: the view counter’s AJAX endpoint now rejects a request whose nonce is missing or
    expired, where before it carried on. A nonce was never what limited the count – the
    endpoint is open to visitors, so every visitor has a valid one – so the endpoint now also
    counts at most one view per visitor, per post, per day, decided on the server. The visitor
    is identified by a salted hash; no address is stored. On a site whose pages are cached for
    longer than a nonce lives, the counter now under-reports instead of counting forged
    requests.
  • Changed: the stats setting is sanitised with WordPress’s own boolean function rather than a
    cast, which reads values such as the string “false” correctly.
  • Changed: internal code comments that described a feature as living in a separate plugin.
    They were comments, never shown to anyone, but they described the plugin as something it is
    not. Nothing in this plugin is locked, limited or behind a key.

1.37.3

  • Changed: wording of an internal code comment that described where template import used to
    live. No change to behaviour.

1.37.1

  • Changed: the WooCommerce part of template import now uses WordPress’s own file functions to
    move and delete files, instead of PHP’s. This code came from the companion theme in 1.35.0,
    where a different set of coding standards applies to it.
  • Changed: several places that read submitted data now say, next to the line, which function
    sanitises it, so that an automated scan does not report them as unchecked.

1.37.0

  • Changed: the Raw HTML box on an Embed is no longer part of this plugin. WordPress.org does
    not allow a plugin hosted there to let people save arbitrary HTML, CSS or JavaScript. An Embed
    still takes a URL, which is what it is for; designs that already carry raw HTML keep rendering
    it, unchanged.
  • Changed: markup returned by the aumframe/shortcode_html filter is now passed through an
    allow-list before it is printed. Whoever answers that filter is a theme or another plugin,
    and this plugin is the one printing the result. The list is WordPress’s own list for post
    content plus the form controls a search box needs.
  • Fixed: the prev and next text of the pagination shortcode went into the page unescaped.

1.36.2

  • Fixed: a component’s parameter list was treated as “this component has parameters” whenever it
    was present, including when it was empty. An empty list can arrive as an empty array after the
    design has been saved, imported or exported, and that alone was enough to change how every
    instance of the component was rendered – which is what made the previous two releases’
    problem appear on a site where nobody had edited the component. The check now counts the
    parameters.
  • Fixed: adding a parameter to a component whose parameter list had become an empty array was
    discarded when the design was saved. The parameter appeared in the editor and was gone after
    a reload, with no error.

1.36.1

  • New: wp aumframe doctor now also reports designs whose rendered output has collapsed – the
    case 1.36.0 fixed. Upgrading does not repair a page that was already saved wrongly: the
    design itself was never damaged, and rendering only happens when a design is saved, so each
    affected design has to be saved once in the editor. This tells you which ones.

1.36.0

  • Fixed: a component instance whose individual parts had been edited – a different heading and
    image on each of four cards, for example – was saved as a plain reference to the component,
    and every one of those instances then rendered the component’s own content instead. The page
    showed the same card repeated. The edits were never lost from the design; only the rendered
    page was wrong, so re-saving the page in the editor is enough to correct it. Instances that
    only set the component’s parameters are unaffected and still share one copy, so a change to
    the component still reaches every site.

1.35.0

  • New: a template’s settings for AumViso, AumLang, WooCommerce, AumReserva and AumNexCart are
    now applied by this plugin. They were previously applied by the AumCreate theme, so importing
    a template on a site running any other theme left those settings unwritten and reported
    success.
  • Changed: this plugin’s admin pages – Forms, Content Model – are always under its own Aumframe
    menu. They previously moved under the AumCreate theme’s menu when that theme was active.

1.34.2

  • Fixed: on a site served from a port other than the default – a local or staging install, for
    instance – the check that runs after importing a template reported every one of the site’s own
    images as pointing somewhere else. It compared host names while the addresses carried a port.
  • New: other plugins can add fields to the editor’s panels. The designer screen takes over the
    whole page and never reaches the usual asset hook, so there was no moment at which anything
    else could add to it.

1.34.1

  • Changed: wording of an internal code comment. No change to behaviour.

1.34.0

  • New: Template packages now have their own screen under AumCreate, so a package can be imported
    or built without any other plugin or theme. It was already possible from WP-CLI; now it is in
    the admin where it belongs.
  • Changed: the Custom CSS boxes are no longer part of the editor. WordPress.org does not allow a
    plugin hosted there to let people save arbitrary CSS, and WordPress has an editor of its own
    for it. Designs that already carry custom CSS are unaffected – it is still compiled and applied
    exactly as before. To write CSS of your own, use Appearance > Customize > Additional CSS; every
    element in a design carries a stable class you can target.
  • Fixed: a security check on the page-views metabox did not clean the submitted value before
    verifying it.
  • Changed: the stylesheet and the two small scripts the plugin prints on the front end now go
    through WordPress’s own enqueue functions instead of being written into the page directly.
  • Changed: custom CSS stored in a design is now checked again at the moment it is printed, not
    only when the editor saves it, so CSS that reached the database some other way cannot break out
    of the style element.
  • Changed: translations are no longer bundled. They will be delivered through
    translate.wordpress.org instead.

1.33.2

  • Fixed: opening a design block to edit it showed an empty canvas. The block was being drawn
    inside the site header and footer, as though it were a page – and a header pinned to the top of
    the window covered it completely, so a block shorter than the header had nowhere to appear. The
    layer list showed everything was there, which made it look as though the block itself was empty.
    A design block is now shown on its own while you edit it.

1.33.1

  • Fixed: editing the site shell – the design that holds the header and footer – showed the footer
    underneath the header instead of below it. The opening the page content goes into rendered as
    nothing at all while that design was open on its own, so a header that is pinned to the top of
    the window had nothing to push the footer past. The opening is now drawn as a marked-out area,
    which also makes it visible where a page will be inserted. Only the editor changes; what
    visitors see was never affected.

1.33.0

  • New: the desktop canvas width can be chosen – 1280, 1440 or 1920 pixels, with 1440 as the new
    default. The canvas has always shown a real browser width scaled to fit, but that width was fixed
    at 1280, so on a wider screen the crop of a full-width image in the canvas did not match what the
    same page showed on the front end. Nothing about a design changes when you switch; only what you
    are looking at.
  • New: wp aumframe doctor checks a site for two faults that do not announce themselves. Image
    addresses in layouts and design blocks that still point at the site a template was built on – the
    images simply do not load, and nothing says why. And design blocks left behind by an earlier
    template, which importing never removes, and which can show the wrong images in the editor while
    the front end looks right.
  • New: importing a template now runs both of those checks when it finishes, and reports what it
    found. Both report the number of addresses and blocks they examined, not only the number of
    problems, so “nothing wrong” can be told apart from “nothing checked”.

1.32.5

  • Fixed: the three sha256 checksums published under “Build” did not match the files in the
    package. Two of them had been left behind by an earlier release. Anyone rebuilding the editor to
    check them, which that section invites, would have found a mismatch.
  • Changed: package.json now carries the same version as the plugin. It ships with the plugin
    because GPLv2 requires the scripts used to control compilation, so a wrong number in it is a
    wrong number in the package.
  • Removed: a build-time constant that no source file referenced. The output is byte-identical
    without it.

1.32.4

  • Changed: the changelog in this file now carries only recent releases. wordpress.org truncates
    that section at 5000 bytes without saying so, and this plugin’s full history is far longer. All
    of it is kept in changelog.txt inside the plugin folder.

1.32.3

  • Changed: the filter that lists meta keys hidden from the content model is now named
    aumframe/ct_hidden_meta. It was aumcreate/ct_hidden_meta, carrying the theme’s prefix rather
    than this plugin’s. Nothing was listening to it.
  • Changed: the cached interaction counts are stored as _aumframe_like_count and
    _aumframe_favorite_count. The previous names, _like_count and _favorite_count, carried
    nothing identifying this plugin and could collide with any other plugin counting likes. The
    authoritative counts live in the plugin’s own table; this post meta is only a cache for list
    screens, and nothing read the old keys at the time of the rename.

1.32.2

  • Fixed: a kit could report a required plugin as missing on a site where it was installed. The check
    read only this site’s list of active plugins, so a plugin activated for a whole network, or
    installed as a must-use plugin, was not found. It now reads the network list as well, and the
    fallback used for must-use plugins covers every plugin the shipped kits require.

1.32.1

  • Fixed: a taxonomy whose identifier is longer than 20 characters was shortened on import, because the
    20-character limit WordPress applies to post types was being applied to taxonomies as well. WordPress
    allows 32 for a taxonomy. The shortened name then did not match the one the registering plugin uses,
    so the guard against re-registering an existing name did not recognise it and a second taxonomy was
    registered under the same URL prefix. Its rewrite rules took precedence and pointed at a query
    variable holding no terms, so every category archive returned 404 while both taxonomies appeared in
    the admin, each with its own list of terms. Identifiers already stored are left unchanged.