Static Site generation through EMCP Cloud, backups kept out of the web root with retention for every backup, a Block Builder that honors block styles on the front end with a real repeater, and a fix for sites where another plugin took over EMCP's licence details.
- New: Static Site module. Turn your site into plain HTML files, download them as a ZIP, keep them in a folder, or serve them to visitors. Generations are counted by your EMCP Cloud account: 3 free, plus a monthly allowance with an EMCP Pro licence.
- New: GeneratePress theme settings are free. On a site running GeneratePress,
generatepress-readreads the global color palette, body and link colors, container width and layout, and body font size, andgeneratepress-writechanges them and refreshes GeneratePress's cached CSS. Both were Pro-only; the write tool still ships switched off. The Tools screen also showed them as available on free installs, where they never registered. GenerateBlocks stays in Pro. - Security: GeneratePress settings are checked before they are saved.
generatepress-writestored any value it was given, and GeneratePress prints these settings into the CSS on every page, so a value could close the style element and add a script. Each value is now checked the way GeneratePress's own Customizer checks it (colors as hex,rgb(),rgba()or a palette variable; layout and alignment from GeneratePress's own choices; whole-number sizes; palette slugs of letters, numbers and hyphens), and a refused value is reported inrejectedwith nothing written. The documented alignment value was wrong too: GeneratePress usesboxes, notboxed.astra-writeandkadence-writehad the same gap and get the same treatment: Astra values are checked like Astra's Customizer checks them (colors, font lists, responsive font sizes, whole-pixel widths, layout ids), and Kadence's settings objects may hold only identifier keys, numbers, palette slugs, colors, plain web URLs and plain text that cannot end a CSS rule. Real stored settings from two Astra sites and both themes' defaults all pass. - Fixed: GeneratePress body font size and the Kadence palette now take effect. On GeneratePress 3.1 and later,
body_font_sizewas written to a setting the theme ignores once dynamic typography is on (the default), so the size never changed; it now sets the body rule of GeneratePress's typography list, keeping that rule's font family, and still uses the old setting on sites without dynamic typography.kadence-writesavedglobal_paletteas a theme setting Kadence never reads; it now saves to Kadence's own palette option, accepts 9 to 15 colors per palette in order, keeps the palettes you do not send, and can switch the active palette. - Fixed: History can undo database changes again. Since 3.17.0 History recorded
insert-row,update-rowsanddelete-rows(and All in One SEO post changes) but could never undo them, because the old record could not tell rows apart safely. Each write now locks the rows it touches, and History records each row by its primary key with what it held before, in the same transaction as the write. Undo puts the rows back by key, deleted rows return under their original ids, and an inserted row is removed. If a row has changed since, the undo reports a conflict and only Undo anyway overwrites it. The tools say when a change cannot be undone and why: a table with no primary key, a table that is not InnoDB, or an update that changes primary key values. A write that would change more than 500 rows is refused, with nothing changed. Changes recorded by older versions stay not undoable. - New: Category, tag and custom taxonomy term tools. Five free WordPress tools:
list-terms(search, parent filter, paging),get-term(with term meta, children and archive link),create-term,update-term(only the fields you send) anddelete-term(confirm required, ships switched off). They work with any registered taxonomy, including WooCommerce product categories, and follow each taxonomy's own permissions. Every write can be undone from History: an undone delete brings the term back under its original id with its meta, its posts and its child terms, and takes off the default category WordPress gave posts left without one. The default category and terms a menu links to cannot be deleted. - Fixed: Account page showing another plugin's name and version. When EMCP was installed or activated by another plugin, for example ManageWP Worker deploying it across sites, Freemius could cache that plugin's main file as EMCP's. The Account page then showed the other plugin (such as "ManageWP Worker 4.9.38"), update checks compared against that plugin's version so no EMCP updates appeared, and the deactivation hook was registered on the wrong file, so deleting and reinstalling EMCP never cleared it. EMCP now checks the two cached paths before Freemius starts and corrects them if they point anywhere else, and seeds the correct path on a fresh install. Only EMCP's own Freemius entries are touched. Affected sites are corrected on the first page load after updating, but because they cannot see updates, they need this version installed once by hand or through the site manager. Reported and fixed by Amir Iqbal.
- Security: Backups are no longer reachable from the web. Backups (database dumps,
.emcparchives and restore uploads) were kept inwp-content/emcp-backups/behind an.htaccessdeny, which nginx hosts ignore, so a backup's files could be downloaded by anyone who knew the address. Backups now go outside the web root when the folder above WordPress is safe to use, or else to a folder in wp-content with a name derived from the site's secret keys that cannot be guessed, also protected by .htaccess (Apache) and web.config (IIS). SetEMCP_BACKUP_DIRin wp-config.php to choose the folder yourself. Existing backups move automatically. A weekly check fetches a test file from the folder and the Dashboard warns, with the nginx rule, if the web server serves it. Reported by a customer. - Security: The migration connector (1.4.0) keeps transfers private too. On the destination site, archives being received and the files unpacked during a restore lived in
wp-content/emcp-connector-inboxandwp-content/emcp-connector-work-*, protected only by.htaccess. They now live in one folder named from the destination's secret keys, protected for Apache and IIS, the unpacked files (including the database dump) are deleted when a restore fails as well as when it succeeds, and leftovers older than a day are removed, along with the old folders. Download the connector again from Backup & Migrate, Migrate to update it. - Fixed: Backups no longer fill the disk. Only scheduled backups had a limit. Backups made by hand or by an AI agent now keep the newest 10 by default, with an optional size limit, set on Backup & Migrate, History. A daily cleanup also removes failed partial backups, abandoned restore uploads and leftovers after a day. The History view shows the folder, whether the web check passed and the disk used.
- Improved: The admin sidebar's sections are divided by a line, their headers open and close, and each person's choice is remembered. Static Site sits under Build.
- Improved: Notifications look like cards. Each announcement shows its icon, a colour for its kind (info, success, warning, offer), its date, a New badge until read and a clear call to action. Icons were missing before.
- Fixed: Block Builder supports now reach the front end. A custom block that switched on
supportsshowed color, spacing and typography panels in the editor, but the generatedrender.phpnever printed WordPress's wrapper attributes, so every choice was silently dropped on the live page. Generated blocks now merge the wrapper attributes (support classes and inline styles, the "Additional CSS class" field and alignment) into the template's root element, with no extra wrapper element. The merge uses core APIs only, so it keeps working in a Sandbox plugin export. Inside the editor preview it is skipped, because the editor's own block wrapper already carries those styles. Existing blocks pick this up the next time they are updated. - New: More native style panels for custom blocks.
supportsalso acceptsborder(radius, width, color, style),shadow,dimensionsandbackground, alongsidealign,color,spacingandtypography. - New: Sidebar panels and help text for custom blocks. An attribute's optional
groupplaces it in a named, collapsible sidebar panel (the first opens by default), and itshelptext is now shown under the control. Previously every control sat in one "Settings" panel andhelpwas ignored. - New: Repeater attribute for custom blocks.
type: "repeater"with typedfieldsgives a list of rows that the person editing can add, remove, reorder and edit in the sidebar, each row opening on its own, with an optional row title field, starter rows,min_rows/max_rowsand custom button labels. Rows loop in the template with{{#each}}, each field escaped by its own type, and media fields in a row expose{{field_alt}}/{{field_id}}. Repeaters cannot nest. - Improved: Custom block color controls offer the theme palette. They previously showed an empty swatch list, so only a custom color could be picked.
- Improved: Custom block media controls show a thumbnail with Replace and Remove, instead of the file URL as button text, and store the alt text and media type.
media_typeswidens the picker to video, audio or documents. Templates can print{{name_alt}}and{{name_id}}, so images get their Media Library alt text. - Fixed: Block attribute names that collide with WordPress are refused. An attribute named
align,className,style,textColorand similar was silently overwritten by the core attribute of the same name. The create, update and validate tools now refuse these names and suggest an alternative. Blocks already on the site, and blocks arriving through an import, a Cloud pull or a Marketplace install, keep working unchanged. - Fixed: An empty
mediadefault was written to a custom block'sblock.jsonas[]instead of{}. - Improved:
list-block-control-typesnow returns the attribute options and the allowedsupportskeys, and theemcp-blocksskill documents them. - Fixed: A selective Sync could replace the whole destination database. Table names given without the prefix were trimmed character by character (
postsbecameosts), and a selection that matched no table was exported as "every table". Bare names now resolve correctly, and a selection that matches nothing is refused. - Security: The database write tools check column names.
insert-row,update-rowsanddelete-rowspassed the agent's column names to WordPress, which places them in the query without escaping, so a crafted name could run its own SQL and read past the protected user tables. Every name must now be a real column of the table. These tools ship switched off. - Security: The OAuth screen no longer redirects before login. A connection request with bad parameters now shows an error page instead of sending the visitor back to the app's address, so the site cannot be used as an open redirect by a self-registered app.
- Security: Changing Sandbox widgets and blocks needs
unfiltered_html, as PHP snippets already did. Widgets carry front-end JavaScript, so multisite site administrators and sites withDISALLOW_UNFILTERED_HTMLcan no longer import or switch them on. - Fixed: A post containing the Themer Post Content block no longer crashes. It rendered itself again and again until PHP ran out of memory; each post now renders once per nesting.
- Fixed: Database undo snapshots now capture rows matched with an empty (NULL) value, as WordPress does, and a malformed backup owner value no longer becomes the text "Array".
- Improved: Deactivating EMCP stops its maintenance tasks. Recurring cleanup events no longer keep firing while the plugin is off; they come back on reactivation. Your backup schedule is kept.
- Improved: Uninstall cleans every site of a network and also removes the Filesystem tool backups and WP-CLI job output in uploads, Themer PHP templates, leftover builder locks, Backup & Migrate worker events and two more user settings.
- Improved: Fewer database queries on every page view. Eleven settings EMCP reads on each request are now loaded in one query, the menu list for the Themer menu block loads only in the block editor, and Themer reads a post's terms from the cache WordPress already filled (141 to 128 queries on a test home page).
- Improved: Translations: the plugin loads translations from its own
languagesfolder, ships a.pottemplate, sets translation paths for its scripts, and every string with a placeholder has a note for translators. - Improved: The readme lists every external service the plugin can contact, with what is sent and when, its title matches the plugin name, and the FAQ points to Compact tool mode instead of the removed Low-tools mode. The plugin declares an
Update URIso a directory plugin with the same folder name can never replace it. - Improved: Lighter page views for visitors. The admin screens' server code, AI Chat, the Backup & Migrate engine and the Static Site generator no longer load when a visitor opens a page; they load for wp-admin, REST, WP-CLI and scheduled tasks. A test home page loads 100 fewer plugin files (403 to 303). While the Static Site module is on, the part that serves its pages still loads.
- Fixed: The Templates library is saved in small pieces. It was kept in one database row of about 8 MB, which hosts with a small
max_allowed_packetor a 1 MB object cache limit refused without an error, so every Templates screen load downloaded the whole library again. It is now stored in 512 KB parts, and a library that still cannot be saved waits a few minutes before downloading again. The Prompts and Brand Kits libraries are stored once instead of twice. - Improved: Licence notices for the bundled jsdiff, Fuse.js and Lucide code and for Composer now ship with the plugin; the Dashboard's video thumbnails ship with the plugin instead of loading from YouTube; the upgrade banner's style and script load as enqueued files; a test file no longer ships in the release zips.
- Fixed: Bricks Interactions and conditions are accepted.
_interactionsand_conditionsare universal Bricks settings edited in their own panels, so they are not in any element's control list, and every write that used them was refused as an unknown setting. They are now accepted with a shape check. JavaScript interactions are still refused, like other executable code, and so are attribute interactions that would set an event handler (on*),srcdoc, or ajavascript:ordata:URL, because Bricks applies those attributes unfiltered. - Fixed: Bricks global classes can be applied.
_cssGlobalClassesis set from the class picker, not an element control, so every element that referenced a global class was refused as an unknown setting before its IDs were checked. It is now accepted, and each ID must still exist on the site. - Fixed: Custom CSS works on Bricks 2.4. Bricks 2.4 resolves the builder's
%root%token when it saves and no longer resolves it on the frontend. EMCP writes element data directly, so%root%reached the page and every custom CSS rule was ignored. EMCP now stores it as the element's persisted selector (#{cssId},#brxe-{id}, or.brxe-{id}inside a component), as the builder does. Older Bricks versions are unchanged. - Fixed: Bricks options switched off with
falsestayed on. Bricks reads checkbox controls withisset(), so a storedfalse(for example slider pagination) enabled the option. EMCP now removes false checkbox values on save, on every breakpoint. An image from Bricks' HTML converter (_importImage) becomes the element's external image, as Bricks' own import does, instead of refusing the save, and the nested-section error says how to fix it. - New:
bricks-get-contextreports the root font size. Bricks setshtml { font-size: 62.5% }by default, so1remis 10px; designs authored for a 16px base rendered at about 60% size. The context now returns the value, its source andrem_px, and theemcp-bricksskill no longer tells agents to assume 16px. - New:
bricks-get-contextreports Bricks' own Abilities API (Bricks 2.4+): whether it is available and enabled, how to enable it, and which abilities cover what EMCP leaves out (palettes, global classes and variables, theme styles, templates with conditions, popups). - New: HTML-to-Bricks import guide in the Bricks skill (
references/html-import.md): preparing HTML/CSS for Bricks' converter, the fixes its output needs, native widgets, Theme Style mapping and verification, from two full landing-page imports on Bricks 2.4.2. - Improved: The
emcp-bricksskill corrects the shape-divider example (verticalAligntakes flex values such asflex-end;bottomsilently fell back to the top) and covers sticky headers with the Nav (Nestable) mobile menu, heading margins after paragraphs on Bricks 2.4, button tags, slider sizing and grid item settings.