Gatilab Products

Changelogs

Improvements, fixes, and the details behind each release.

All Products

Release history across our plugins and themes.

Stable

Functionalities 1.6.1

Read release notes

What's Changed

  • Fixed: The WordPress 7 data panel no longer appears for a module that is switched off. On a site with Redirect Manager disabled, its page still rendered two empty tables and a working "Add redirect" form, even though the module refuses every write while disabled, so the form could only produce an error.
  • Changed: The panel's "WordPress 7 workspace" heading is gone. Its tables already carry their own headings, and naming a section after the WordPress version labelled the implementation rather than what you are looking at.
  • Fixed: The Performance & Cleanup settings page was headed "Miscellaneous (Bloat Control)", which matched neither the module card you clicked nor any other name in the interface.
  • Changed: The dashboard box holding the AI opt-in is now called "AI explanations", after the single setting it contains, instead of advertising four platform features that are not configurable there.
  • Fixed: Link Management's JSON preset filter note now matches the format used by every other filter note in the plugin.

= 1.6.0 = = 1.6.1 = Interface fixes. The WordPress 7 data panel no longer appears for modules you have switched off, where it offered a create form that could not work. Several admin headings now match the module names they belong to. No settings, data, or hooks change.

Commits

  • Ship 1.6.1 (933f1be)
  • Stop the WordPress 7 panel labelling itself, and hide it when the module is off (b063842)
Stable

Functionalities 1.6.0

Read release notes

What's Changed

  • Security: Abilities API operations now use a permission callback per ability and reject undeclared input properties. A shared callback previously widened to edit_post whenever the request carried a post_id, so any user who could edit one post could toggle modules, create redirects, create tasks, and trigger scans.
  • Security: Redirects, the bounded 404 log, and Task Manager projects moved to a private folder with a random name under wp-content/functionalities/. Existing files are migrated automatically. Apache, IIS, and directory-listing rules are written alongside them, and a new Site Health check confirms over HTTP that the folder really is unreachable.
  • Fixed: Header and footer snippets are no longer re-filtered against the visitor's capability at output time. Anonymous visitors were receiving mangled code — && became && and comparison operators were eaten as tags — while the logged-in administrator saw the snippet work. Filtering now happens once, at save time, against the author's capability.
  • Fixed: A JSON exception preset served from a URL is fetched at most once per cache window instead of on every page load. The cache clears whenever the module settings change, a post or page is edited, or the theme changes, and the last good list is kept when a fetch fails.
  • Fixed: The bulk nofollow tool pages through posts with an ID cursor and now finishes on sites with more than 100 matches. It previously returned the same first batch on every run.
  • Improved: Link Management, Block Cleanup, and Schema use the WordPress HTML API instead of DOMDocument. Attributes are edited in place, so Vue, Alpine, and mustache syntax survive untouched and the JS-framework skip guard added in 1.4.3 and 1.4.4 is gone. Content that used to be skipped is now processed correctly.
  • Improved: Redirect hits and 404 aggregates are buffered and written in batches rather than rewriting the whole JSON file under an exclusive lock on every request.
  • Improved: Redirects run at parse_request, before WordPress queries the database for a page it is about to discard. WordPress's own entry points are never redirected.
  • Improved: The Content Integrity column on the posts list reads a result cached at save time instead of rendering and parsing every row on every page load.
  • Improved: The SVG icon library is stored without autoloading, so full SVG markup no longer loads on every request.
  • Improved: The service worker skips wp-admin, the login page, REST responses, cross-origin requests, and anything marked no-store or private; caps the runtime cache; and precaches URLs individually so one stale entry cannot stop it installing. The manifest now includes an id.
  • Improved: Login Security adds per-username throttling, an IP allowlist, an unlock button on the lockout log, and a warning when every recent lockout shares one address, which is the signature of a site behind a CDN.
  • Improved: Prism.js is bundled with the plugin instead of being loaded from a third-party CDN.
  • Improved: Performance & Cleanup makes the revision limit configurable, and disabling Heartbeat now applies to the frontend only unless the new admin option is also enabled, so autosave and post locking keep working.
  • Improved: Content Integrity and Assumption Detection gained the filters their documentation promised, and the module documentation now lists hook names that exist. Nineteen documented hooks were never fired.
  • Fixed: Settings export no longer redacts the GA4 measurement ID as if it were custom code.
  • Fixed: Core icons get the same definition-ID prefixing as custom icons, so two gradient icons on one page no longer collide.
  • Fixed: Saving PWA settings flushes rewrite rules once instead of twice.
  • Fixed: Disabling feeds falls back to a message only when a redirect is genuinely impossible, making the documented message filter reachable.
  • Changed: The translation template is generated from the source. It was a one-string placeholder.
  • Changed: src/ and docs/ are excluded from the distribution, and build.sh now uses the same exclude list as the release workflow so a local build and a tagged release cannot drift.
  • Changed: Tested up to WordPress 7.1.

= 1.5.0 = = 1.6.0 = Security release. Fixes an Abilities API permission flaw that let any user who could edit a post reach administrator-only operations, moves redirect and task data into a private folder, and stops header/footer snippets being mangled for logged-out visitors. Also replaces DOMDocument with the WordPress HTML API in three content filters, so pages using Vue or Alpine are processed correctly instead of skipped. Existing settings, hooks, admin URLs, and data files are migrated automatically.

Commits

  • Readme: test against WordPress 7.1, correct stale claims, link the docs site (bbcd38d)
  • Fix CI: ship the Prism assets and make the POT check reproducible (c199bbd)
  • Migrate legacy data even when the file modules are disabled (e1c467d)
  • Ship 1.6.0: Abilities permission fix, private data storage, HTML API filters (c5cdccd)
Stable

Core Forms 4.9.0

Read release notes

Core Forms 4.9.0 improves submission reliability, spam protection, payment validation, and the WordPress admin experience.

  • Fixes reCAPTCHA and math-captcha validation, draft-save protections, and sensitive template-field access.
  • Preserves form HTML when saving from other tabs and prevents submission deletion from touching unrelated post metadata.
  • Recomputes calculated payment amounts on the server, reports failed submission writes, and preserves uploads without JavaScript.
  • Makes activation safer, improves duplicate prevention and GDPR erasure, and adds submission indexes and diagnostic tools.
  • Adds searchable settings sections, accurate unsaved-change indicators, consistent borders and colors, and accessible copy controls.
  • Improves Commerce navigation and activity, form-builder toolbar states, and submissions filtering.
  • Repairs standalone URL-base changes and shows URL controls only when fullscreen mode and standalone publishing are enabled.

Requires WordPress 6.4+ and PHP 8.1+. Tested with WordPress 7.1.

Validation: 336 unit tests, PHPStan, JavaScript lint, generated-asset checks, package integrity and PHP syntax checks, plus local browser verification.

Read the Core Forms 4.9 release post.

Stable

GT Page Blocks Builder 3.0.0

Read release notes

A correctness release. It repairs paths that silently corrupted or discarded work, gives the plugin a test suite and CI for the first time, and makes the upgrade itself verifiable.

Back up your database before upgrading — the schema change is one-way. Requires PHP 8.1. Flush your page cache and CDN afterwards: generated CSS and JS filenames now carry a content hash.

Breaking

  • PHP 8.1 is the minimum. WordPress will not offer this to a site below it, and activation stops with a notice instead of a white screen.
  • The CSS minifier no longer collapses whitespace around :. .menu :hover stays a descendant selector instead of silently becoming .menu:hover. If a stylesheet unknowingly depended on the collapsed form, that rule changes what it matches — this fixed eight blocks on our own site whose typography had quietly stopped applying.
  • Minified JavaScript changes shape. A line comment no longer swallows the rest of the file, and newlines survive so semicolon-free code is not concatenated. Blocks whose JS silently did nothing start working.
  • Generated asset filenames carry a content hash. Every cache and CDN misses once. The old unhashed name is still written as a copy for this major version.
  • Utility-class output is switched off once during the upgrade, with a notice. The scanner never emitted anything for page blocks, so this is a zero-visual-change upgrade; turning it back on is your decision.
  • PHP execution in the block preview requires administrator access. It previously ran for anyone who could edit the post.
  • The AI panel requires manage_options. Restore with add_filter( 'gt_pb_ai_capability', fn() => 'edit_posts' );.
  • The undocumented terminal endpoint is removed.
  • Uninstalling deletes options, transients and stored AI keys. The library is dropped only if you tick the new setting.
  • Library usage counts change on block themes, where the invalidation hooks were never registered.

Correctness

Editing a library block reaches the visitor — in file-output mode the generated file was written once and never again. The builder stops blanking core and third-party blocks on every keystroke. Renaming a section persists. A failed save says so instead of showing a green notice over a discarded session. Inline SVG backgrounds survive the CSS sanitiser. A block detached from the library stops rendering the library version over your own copy.

Recovery

Library blocks keep a revision history with one-click restore. Document-level undo covers add, delete, duplicate, reorder and import. Cmd+Backspace and Cmd+D stop acting on the whole section from inside a code pane. Undo after switching sections no longer pastes the previous section's code.

Security

The PHP-execution checksum is keyed with the site salt, so it cannot be recomputed by whoever wrote the row; existing blocks keep working and are re-keyed in the background. The licence and update channel verifies TLS certificates and rejects package URLs that are not HTTPS on the licence host.

Free, with licensed updates

Every feature works without a licence key; nothing is gated. A licence buys automatic updates and support. Security releases reach every install regardless, through a separate channel — see SECURITY.md.

Going back

Reinstall v2.8.1. The database stays at schema 1.2, which is expected and harmless. PHP-enabled blocks strip their tags until re-saved. Detail in README.md under "Going back from 3.0.0".

Release Candidate

GT Page Blocks Builder 3.0.0-rc.3

Read release notes

Release candidate. Not for production. This carries a one-way database migration to schema 1.2 — take a database backup before installing.

Install

Download the ZIP below and install it through Plugins → Add New → Upload Plugin, or:

wp plugin install page-blocks-builder-v3.0.0-rc.3.zip --force

Before you start

define( 'GT_PB_DISABLE_SECURITY_CHANNEL', true );  // stops the RC being swapped mid-test
define( 'GT_PB_ALLOW_PHP', true );                 // only if testing PHP blocks

Run the test site on pretty permalinks — on plain permalinks the library screen's REST calls fail. Known, fixed for final.

What to exercise, in order

  1. Upgrade a site that has PHP-enabled blocks and confirm they still render. The checksum scheme changed and old values are rewritten in the background; this is the highest-risk path.
  2. A page mixing page blocks with core blocks. Open the visual builder, type, save, reload — core and third-party blocks must survive, and the page must save twice in a row.
  3. A block using External File output. Edit its CSS and confirm the change reaches the front end. This never worked before 3.0.
  4. Detach a linked block in the block editor, edit the copy, and check the front end shows your version — fixed in rc.3.

New since rc.2

  • A block detached from the library kept rendering the library version. Fixed on both the editor and the server, so content already saved in that state is healed too.
  • tags and description are writable and round-trip over REST; both get fields on the edit screen.
  • Display Conditions are always visible, not only with a hook position set. Linked blocks get a respectConditions toggle, off by default.
  • New gt_pb_block_rendered filter, and a hooks reference in README.md.
  • CI syntax-checks assets/js — there is no bundler, so those files ship exactly as committed.

Going back

Reinstall v2.8.1. The database stays at schema 1.2, which is expected and harmless. PHP-enabled blocks strip their tags until re-saved. Full detail in README.md under "Going back from 3.0.0".

Reporting

Include the version from the Plugins screen (should read 3.0.0-rc.3), single vs multisite, and whether you upgraded or installed fresh. Security issues: see SECURITY.md.

Stable

GT Page Blocks Builder 2.8.1

Read release notes

Security release. Update before anything else.

Privilege escalation in the block preview. PHP in a Page Block no longer runs for users who can merely edit the post. The builder's preview endpoint is reachable by anyone with edit_post — an Author, or a Contributor on their own draft — and it executed the section's PHP after deriving the content checksum from the very content it was about to run, so the check was satisfied by definition. On any site that had turned PHP blocks on, that left the site-wide constant standing alone as the only gate. Running PHP in a preview now requires administrator access, and everyone else previews with the tags stripped and a note saying so rather than silently different output.

The update channel verifies certificates again. It was requesting with sslverify off, and the server's reply supplies the package URL WordPress downloads and installs a plugin from, so anything able to answer as the licence server could have installed arbitrary code. Certificates are now verified, the request goes through wp_safe_remote_post(), and any package, url or homepage pointing somewhere other than the licence server's own host is discarded rather than followed. A host with a genuinely broken CA bundle can opt out per-site with GT_PB_LICENSE_INSECURE. The changelog the update screen renders is escaped before display.

The plugin declares what it needs. Requires PHP: 8.1, Requires at least: 6.0, a licence and a text-domain path. It previously declared none, so WordPress offered the update to sites that would fatal on it, and the update payload separately claimed PHP 7.4 while the code has needed 8.1 since 2.7. A site below 8.1 now gets an admin notice naming the versions instead of a white screen. Update URI is set, so the plugin can only ever be updated from its own source.

The licence screen is reachable. It is registered under the Page Blocks menu, but the Plugins row action and both admin notices linked to options-general.php, a screen that does not exist.

Also: the preview endpoint checks the post type, matching the builder; and the GPLv2 text the header declares now ships with the plugin.

Stable

GT Performance 1.0.8

Read release notes

Correctness release. Everything here is a defect a site could hit without opting into anything, or a claim the shipped documents made that was not true.

Fixed

  • The managed Cloudflare Cache Rule instructed the edge to cache responses the origin marks no-store, private. cloudflare.edge_ttl now defaults to 0, so the rule compiles as respect_origin. A positive lifetime still compiles as override_origin, but the expression is then narrowed to requests with no query string, because overriding the origin cannot be made safe for the unbounded set of query parameters the origin refuses.
  • Trashing, unpublishing, or renaming a post never cleared its cached page. The save_post handler returns early for posts that are not publicly viewable, and a status change reaches it with the new status already applied, so a withdrawn page kept returning 200 for the rest of its stale window.
  • Saving settings orphaned the whole cache. generation is part of the cache key and is bumped on every save; nothing deleted the now-unreachable entries.
  • The capture pipeline ran when no page-cache drop-in was installed, which is the state directly after activation.
  • A full purge deleted the .htaccess and index.html that keep the cache directory unreadable from the web.
  • The private-fragments AJAX endpoint was registered even when the feature was off.

Removed

  • The WordPress revision limit control. It filtered wp_revisions_to_keep unconditionally at 5 on every activation, whether or not its own module was enabled, discarding revision history irreversibly on the next save.
  • The X-GT-Performance-Bypass request header. Its reason code claimed a signature that nothing ever computed or verified, so any client could force a full uncached render on every request.
  • The "Remove unused CSS" setting. The engine flattens native CSS nesting, drops @import stylesheets, prunes escaped utility class names, and runs during the visitor request; the damage was silent and cached. Define GTPERF_UNUSED_CSS in wp-config.php to run it anyway. It returns as a supported feature once generation moves out of the request and the differential safety net lands.
  • Multisite activation. One compiled config and one cache root are shared across a network, so the last subsite to save decided every other subsite's cache behavior.

Added

  • LICENSE, and a Third-party libraries section disclosing the three bundled MIT libraries.
  • Update URI: false, so nothing claiming the unclaimed gt-performance directory slug can push a package to existing installs.
  • A golden-file HTML regression fixture, and a Plugin Check job in CI that runs against the built ZIP rather than the working tree.
  • Upgrade Notice entries, including the one 1.0.4 shipped without.

Changed

  • Documentation no longer describes WordPress.org as the update authority. The plugin is not listed in the directory yet.
Stable
Read release notes

What's Changed

  • New: a copy button on the Branded URL column. It appears when you hover the row or focus it with the keyboard, copies the full branded link, and confirms with an inline Copied badge that clears itself.
  • New: the plugin's own icon now appears in the admin menu, replacing the generic WordPress link dashicon. It is painted as a mask filled with the menu's own text colour, so it matches the icons beside it in every state and every admin colour scheme, staying light on dark sidebars and dark on light ones.
  • Updated: refreshed the WordPress.org plugin icon.

= 1.8.0 = = 1.8.1 = Adds a hover-and-click copy button to the Branded URL column and the plugin's own icon in the admin menu, plus an expanded readme and FAQ. No database changes.

Commits

  • Release 1.8.1: copy button, brand menu icon, expanded readme (ead0ff0)
Stable
Read release notes

What's Changed

  • Fixed: the links table collapsed narrow columns when many were shown at once. With every column visible, Mode and Clicks were squeezed to a few pixels and their values wrapped one character per line. Every column now has a minimum width, the wide ones wrap instead of being clipped, and the table scrolls sideways on its own rather than stretching the admin page.
  • New: Optional click counting, off by default. Turn it on under Settings and each link gets a running total of how many times it has been followed, shown as a sortable Clicks column and included in CSV export. It stores one number per link and nothing else -- no IP address, user agent, referrer, or timestamp -- and the count is written after the redirect has already been sent, so the redirect itself is not slowed down. The plugin's suggested privacy-policy text updates itself to match whichever setting you choose. Use gtlm_count_click to skip clicks you do not want counted.
  • Fixed: a deleted, trashed, or deactivated short link returned HTTP 200 with the site's front page instead of a 404. The prefix rewrite rule matches the whole namespace, so an unresolved slug fell through to the home page, and search engines could index every dead link as duplicate front-page content. Unresolved prefixed links now return a real 404 rendered by the theme's own template. Direct and regex mode still fall through untouched, and the gtlm_404_on_missing_link filter restores the old behaviour.
  • Fixed: rel values separated by spaces were silently discarded. The plugin writes space-separated rel into Link headers and core Button blocks, but only accepted commas on input, so round-tripping a value emptied it. Commas, spaces, and arrays are all accepted now, and the allowed-token validation is unchanged.
  • Fixed: the Active, Inactive, and Trash views were implemented but never rendered, leaving them reachable only by typing the URL by hand. They now appear above the links table.
  • Fixed: bulk actions ran while the page rendered, which gave no confirmation message and re-ran the action on a browser refresh. They now run before output and redirect to a clean URL with a result message.
  • New: Undo. Trashing, restoring, activating, and deactivating a link now offer a one-click Undo in the success notice, for single links and bulk selections alike.
  • New: Trash retention. Links left in the Trash can be permanently deleted after a configurable number of days, set under Settings. New installs start at 30 days. Existing sites are left at 0 (keep forever) on upgrade, so nothing already sitting in your Trash is deleted because you updated; switch it on yourself when you want it.
  • New: Empty Trash button on the Trash view.
  • Improved: the admin screens now inherit the WordPress admin surface instead of painting over it. Custom admin colour schemes, high-contrast mode, and reduced-motion preferences are all respected.
  • Improved: accessibility. Row checkboxes and every filter dropdown have proper labels, keyboard focus is visible, and the notice area sits where WordPress expects it.
  • Improved: long URLs no longer break across three lines in the links table. The Branded URL column shows the readable path, with the full URL on hover and in the Copy URL action.
  • Improved: a fresh install now records its schema version during activation instead of re-running the migration on the first admin page load.
  • Compatibility: Tested against WordPress 7.1. Verified on a WordPress 7.1 and PHP 8.4 install: redirects, geolocation targeting, the REST API, CSV import and export, the links list table, and both block editor inserters all behave as before, with no deprecation notices raised.
  • Compatibility: Confirmed the GT Link format and the core Button control still work inside the iframed block editor canvas, including search, insertion, and rel handling.

= 1.7.1 = = 1.8.0 = Tested with WordPress 7.1. Fixes a soft 404 that made every dead, trashed, or deactivated short link return the site's front page at HTTP 200, and fixes space-separated rel values being silently dropped. Adds optional click counting (off by default), Undo for trash and status changes, optional automatic Trash cleanup (off for existing sites, so nothing in your Trash is deleted by updating), and an accessibility and native-UI pass on the admin screens. Adds one column to the links table on upgrade; existing links are untouched.

Commits

  • Release 1.8.0: WordPress 7.1 support, redirect fixes, trash undo, click counting (b120a8c)
Stable

GT Performance 1.0.7

Read release notes

Fixed

  • The gtperf_private_island shortcode now escapes the fragment fallback where it is returned. The fallback was already filtered through wp_kses_post() inside the fragment registry, so the rendered output is unchanged, but the escaping was applied in a different class and was not visible at the point of output.

Changed

  • The release package no longer contains the extensionless command line wrappers that Composer packages ship in their own bin/ directories, such as matthiasmullie/minify/bin/minifyjs and bin/minifycss. WordPress.org does not permit them, and the minifier library itself is unaffected.
  • bin/build-package.sh now fails the build when the staged package contains a file type the plugin directory does not permit, instead of producing an archive that is rejected on review.
Stable

GT ACF Blocks Plugin 2.11.2

Read release notes

Fixed

  • The URL Preview button was white-on-white in dark mode. .acf-url-preview__button fills with background:var(--acfb-text) and wrote its label in var(--acfb-text-invert). Those two are only inverses of each other in light mode: --acfb-text-invert aliases --color-button-text, which MD deliberately holds at white in both schemes so it stays legible on the saturated --color-button fill, while --acfb-text flips to a light value for dark. Measured on a live page, the button rendered #FFFFFF on #E4E4E4, a contrast ratio of 1.27:1 against the 4.5:1 AA floor, while light mode was fine at 16.09:1. The Featured variant inherited the same label color under an --acfb-text gradient fill. Seven published posts and pages carry URL Preview blocks; every button on them was affected.
  • Dark callouts had the same defect, latent. .acf-callout.is-style-dark also fills with --acfb-text and set its body text, its links, and its button links in --acfb-text-invert, so the box inverted into a light panel with white text wherever dark mode was on. No published post currently uses the variation, so nothing shipped broken, but the rule was wrong in the same way.

Added

  • --acfb-on-text, the companion to --acfb-text used as a background, mirroring how --acfb-on-primary companions --acfb-button. It resolves to --color-content-bg, which is the true inverse of --color-text and flips under both the [data-theme] toggle and the prefers-color-scheme fallback, so a single :root declaration covers both paths and no dark-mode override is required. The five affected rules now use it: the URL Preview button and its :hover, and the Dark callout's base, link, and button-link rules. Dark mode measures 13.69:1 after the change, light mode is untouched at 16.09:1.

--acfb-text-invert keeps its meaning and its 41 remaining consumers across 17 stylesheets, all of which pair it with a saturated accent or brand fill where white is the correct choice. Redefining it for dark would have fixed these five rules and put those at risk, so it was left alone. Reach for --acfb-on-text whenever --acfb-text is the background, and --acfb-text-invert only on a brand-colored one.

Stable

GT ACF Blocks Plugin 2.11.1

Read release notes

What's Changed

Fixed

  • Callout labels ignored the colour the block was given, and every one of them failed contrast. .acf-callout-label carried a hardcoded color:#d4a600 that never varied with the block's own callout_bgColor or callout_textColor, and four style variations replaced it with literals that were just as uncoupled. Across 501 labelled callouts on 272 posts, 500 of the 500 evaluable labels came in under 4.5:1 — none passed. The mustard sat at 2.17:1 on #f0fdf4 (172 blocks) and 2.09:1 on #eff6ff (131), and a "Warning" label on #f8d7da bottomed out at 1.70:1. The label now resolves to currentColor, inheriting the callout's own text colour, which authors already pick to pair with the background: 415 of 415 blocks carrying explicit colours now pass, and the 85 with none fall back to the theme's own --acfb-text on --acfb-bg pair. The Dark and Dashed Dark variants keep their --acfb-star label, which is token-based and already correct on a dark ground.
  • Custom border-color could not override a variation's border. Highlight, Dashed Light, and Dashed Dark set border as a shorthand, so a block supplying only callout_borderColor kept the variation's width and style and changed nothing but the hue — a Highlight callout with custom colours rendered a 3px dashed border it never asked for, on top of the 1px solid the base rule intended. The three variations now set border-width, border-style, and border-color as longhands so a per-block colour lands without dragging the rest of the shorthand with it.
  • Highlight and Testimonial opted out of dark mode. Both hardcoded their surface (#f0fff0 and #fdf6e3) instead of deriving it from --acfb-bg, so they stayed bright on a dark page while every other callout followed the theme. Both now tint the token with color-mix(), which reproduces the previous light-mode surface to within a couple of values and yields a correspondingly dark tint in dark mode. Highlight's → list marker keeps its green.

Notes

  • Callout registers style as an array in block.json, so WordPress inlines the bytes rather than linking a URL. There is no asset URL to bust here; page caches need a purge for the change to appear on already-cached HTML.

Commits

  • 2.11.1: callout labels inherit the block's text color (543e820)

Stats

  • Commits: 1
  • Changes: 8 files changed, 25 insertions(+), 15 deletions(-)

Plugin Info

  • Blocks included: 29
  • Requires WordPress: 6.0+
  • Requires PHP: 7.4+
  • Requires: ACF Pro 6.0+ or Secure Custom Fields

Installation

  1. Download acf-blocks-plugin-*.zip from the assets below
  2. Go to Plugins → Add New → Upload Plugin in WordPress admin
  3. Upload the zip file and activate