Changelog
Release history for TAW Theme and the taw/core framework package.
2026-06-16Docs update
docs
Docs — June 2026 (2)
New: Framework and Dump helpers
TAW\Helpers\Framework— documented the path/URL resolver helpers (path(),url(),themePath(),themeUrl()) that were present in thetaw/coreREADME but missing from the docs.TAW\Helpers\Dump— documented the debug utility helpers (Dump::dd(),Dump::log()), also missing from the docs.
Blocks
getData(int|false)404 note — added explanation thatgetData()receivesint|falsebecauseget_the_ID()returnsfalseon 404 pages, and that all MetaBlock convenience helpers handlefalsesafely.
2026-06-11Docs update
docs
Docs — June 2026
Options page
- OptionsPage field types expanded — per the authoritative
taw/coreREADME,OptionsPagenow supports the same field types asMetabox(all types, includingfiles,group,post_select,repeater, anddatepicker). The previous explicit subset list has been replaced with the correct statement.
2026-06-10Docs update
docs
Docs — June 2026
Visual Editor
- Visual Editor documented — the Visual Editor (
TAW\Core\Editor\VisualEditor) is now opt-in and production-ready. Enable it by callingVisualEditor::enable()beforeTheme::boot()infunctions.php. The new Visual Editor section covers automatic behaviour, template annotations (Editor::field(),Editor::attrs()), and the save endpoint. - Updated theme boot callout — removed the "not ready for production" warning from the Theme boot page; replaced with a note pointing to the Visual Editor API.
REST API
- Visual editor endpoints documented —
POST /taw/v1/visual-editor/saveandGET /taw/v1/visual-editor/fieldsare now listed in the REST API endpoint table.
Options page
- Removed
filesfrom supported field types —filesis not supported inOptionsPage(only inMetabox). Corrected the supported-types list to match the authoritative README.
2026-06-05taw/core v1.15.52
stable
taw/core v1.15.52 — June 2026
Block system
MetaBlock::variations()static method — block variations are now declared by overridingpublic static function variations(): arrayand returning an array of string suffixes (''= default variation). The previous constructor-basedparent::__construct(['variations' => [...]])approach is replaced.
Asset pipeline
ViteLoader::inlineCriticalCss(string $path)— inline critical CSS directly into<head>from any path relative to the Vite asset root. Use this to manage critical CSS loading from code rather than relying solely on the automaticcritical.scssdetection.ViteLoader::preloadAssets(array $paths)— addmodulepreloadhints for JS chunks to improve first-load parse performance.
Theme boot
Theme::boot()accepts optional config array — pass['performance' => [...]]directly toTheme::boot()as a shorthand for callingTheme::performance([...])as a separate step. Both patterns remain supported.
2026-06-05taw/core v1.15 · TAW Theme update
stable
taw/core v1.15 · TAW Theme — June 2026
Asset pipeline
ViteLoaderOOP API —TAW\Support\ViteLoaderis now the authoritative way to interact with Vite assets. New static methods:ViteLoader::assetUrl(),ViteLoader::isDevServerRunning(),ViteLoader::enqueueAsset(), andViteLoader::init().- Legacy procedural helpers removed from autoload —
vite_asset_url()andvite_is_dev()are no longer in the Composerfilesautoload and are not available globally. UseViteLoaderinstead. - SCSS block asset priority — when a block has both
style.scssandstyle.css, SCSS now takes priority.
Form system
Form::register()+Form::display()— forms are now registered statically viaForm::register()insideboot()and displayed in templates withForm::display('id'). The oldnew Form()+$form->render()pattern has been replaced.- New input field types:
radio(withoptionsandlayout),checkbox_group(stored as comma-separated string),date(withmin_dateandmax_date). - Structural field types:
heading,divider, andhtml— cosmetic fields for layout and copy inside a form with no submission data. - AND / OR conditional logic —
conditionsnow supports'relation' => 'any'for OR logic. The old flat-array AND format is still fully supported. - Multi-step forms — replace the top-level
fieldskey withsteps. Each step has atitleand its ownfieldsarray. Includes a numbered step indicator, per-step client-side validation, and automatic navigation to the failing step on server error. SubmissionsHandlerauto-wired —Theme::boot()now registersSubmissionsHandlerautomatically; manual instantiation is no longer needed.
Metabox engine
datepickerfield type — jQuery UI date picker; stored as a date string (YYYY-MM-DDdefault). Supportsdate_format,min_date, andmax_dateoptions.- Repeater
layoutoption — repeater rows can now render astabbed_horizontalortabbed_verticalin addition to the default accordion. screenskey (plural) — the Metabox config option is nowscreens(accepts an array of post types, page slugs, or page template filenames). The singularscreenis no longer used.
Transactional email
- Template path updated — pre-compiled HTML templates now live at
mails/html/{name}.html. MJML source files remain atmails/{name}.mjmlfor dev-time compilation. MailTesterregistration — register manually with(new \TAW\Core\Mail\MailTester())->register()infunctions.php.
Block system
defaultData()method — UI Blocks now usedefaultData()instead ofdefaults()to define prop fallbacks.getData(int|false $postId)—MetaBlock::getData()now acceptsint|falseso blocks return safe empty values on 404 pages.boot()for all blocks —BlockLoadernow callsboot()on every block type (not just UI Blocks) during discovery.
Navigation menus
MenuItem::target()— new method returning'_self'or'_blank'.MenuItem::isActiveAncestor()— new method;isInActiveTrail()now means any of active/activeParent/activeAncestor is true.MenuItem::wpPost()— new method returning the rawWP_Postmenu item object.
TAW Theme
ThemeUpdaterre-introduced viataw/core—TAW\Core\ThemeUpdateris available again for GitHub Releases-based auto-updates. Instantiate it infunctions.php.- CSS Studio toggle — CSS Studio is now activated via WP Admin → TAW Settings → Developer Tools → Enable CSS Studio (previously auto-activated when the Vite dev server was running).
Image::render()signature — the$altparameter has been removed. Pass options (includingclass,sizes,above_fold,attr) as the third argument directly.Image::preloadTag()— renamed frompreload_tag()to camelCasepreloadTag().
2026-04-14taw/core v1.14 · TAW Theme update
stable
taw/core v1.14 · TAW Theme — April 2026
Metabox engine
filesfield type — new multi-file picker with drag-to-reorder. Stores an array of attachment IDs. Acceptslimitto cap the number of selectable files.- Nested repeaters — repeater fields now fully support nesting: place a
repeaterinside another repeater'sfieldsarray for hierarchical data structures up to three levels deep. Serialization is pre-submit and handles re-entrant calls safely. - JSON encoding — all repeater data is now serialized with full Unicode support.
postMatchesTemplate— new method onMetaboxfor template matching;screennow accepts multiple post types (comma-separated or array).- Repeater template tag — internally switched from
<script>to<template>for repeater row prototypes (better browser compatibility). - jQuery selector optimization — repeater element selectors are scoped for improved performance on pages with multiple repeaters.
Block system
- Block variations —
MetaBlocknow accepts avariationsarray in its constructor to declare WordPress block variations. Asset handles are automatically namespaced per variation. BlockLoader::boot()for plain blocks — whenBlockLoaderloads a UI Block (extendingBlock), it now calls the block'sboot()method if one exists. Use it for one-time setup such as registering hooks.
REST API
post_selectpage handling —SearchEndpointsnow properly validates thepagepost type and handles the WordPress special case automatically.
TAW Theme
ThemeUpdaterremoved — theThemeUpdaterclass has been removed from TAW Theme. Usecomposer update taw/coreto update the framework.SearchEndpointscleaned up — removed the theme-level override; the endpoint is now served exclusively bytaw/core.- Hero block — added
content(wysiwyg) field. Added a three-levelnested_repeaterfield as a reference implementation for hierarchical repeater data. - CSS Studio — added as a dev-only dependency. Activated automatically when
vite_is_dev()istrue; never shipped to production. - Performance —
Theme::performance()now schedules its work onafter_setup_themefor better WordPress filter compatibility.
2026-03-19Initial release
stable
v1.0.0 — Initial release
TAW Theme and taw/core v1.0.0 are the first stable release of the framework. Everything below ships out of the box when you run composer create-project taw/theme.
Block system
- Auto-discovery — drop a class and a template inside
Blocks/and TAW finds it automatically. No registration step, nofunctions.phpedits required. - MetaBlock — page sections backed by metabox data. Extend
TAW\Core\MetaBlock, define fields inregisterMetaboxes(), return template vars fromgetData(). - Block (UI Block) — stateless components that receive props at render time. Extend
TAW\Core\Blockand define adefaults()array. Missing props always fall back safely. - Block nesting — UI Blocks compose naturally inside MetaBlock templates via
(new Button())->render([...]). - Subgroup organisation — blocks can live in nested folders (
Blocks/sections/Hero/) for large projects. BlockRegistry::queue()/::render()— queue a block's assets beforeget_header(), render it anywhere in the template.
CLI scaffolding (bin/taw)
Powered by Symfony Console, shipped inside taw/core.
make:block Name --type=meta|ui— scaffold a MetaBlock or UI Block with the correct class stub and template.--with-style— include astyle.scsswired into the Vite pipeline.--with-script— include ascript.jsloaded as an ES module in the footer.--group=sections— place the block inside a subgroup folder.--force— overwrite an existing block.export:block Name— export any block as a portable ZIP file.import:block path.zip— import a block from a ZIP into theBlocks/directory.
Metabox engine
Config-driven metaboxes with no plugin dependencies. All field types render, validate, sanitize, and save through TAW\Core\Metabox\Metabox.
Supported field types: text, textarea, wysiwyg, url, number, range, select, checkbox, color, image, files, group, repeater, post_select
- Conditional logic — show or hide fields based on other field values. Evaluated live in the admin with Alpine.js and server-side on save. Operators:
==,!=,contains,empty,!empty. - Tabbed layouts — group fields into tabs using the
tabskey; each tab references field IDs from thefieldsarray. - Responsive grid — control field width with the
widthoption (e.g.'50'for two-column). show_oncallable — conditionally hide an entire metabox per post.- Retrieval helpers —
Metabox::get(),::get_bool(),::get_image_url(),::get_color(),::get_posts(),::get_repeater()cover every field type.
Options page
TAW\Core\OptionsPage— site-wide settings stored inwp_optionsusing the same field config as metaboxes.- Supports tabbed layouts, validation, and all field types except
repeaterandgroup. - Retrieval via
OptionsPage::get()andOptionsPage::get_image_url().
Forms
TAW\Core\Form\Form— config-driven frontend forms with CSRF (nonces), honeypot spam protection, field validation, and PRG redirect after success.- Supports
text,email,textarea,select, and any standard HTML input type. - Sends dual emails (to-self and to-client) via
Mailerwhen templates are configured; falls back to plain-textwp_mail()otherwise. TAW\Core\Form\SubmissionsHandler— stores successful submissions as ataw_submissionCPT in WP Admin.- Optional webhook forwarding (n8n, Zapier, Make, etc.) with HMAC-signed payloads. Configure endpoint and secret under Settings → Form Webhook.
Transactional email
TAW\Core\Mail\Mailer— fluent wrapper aroundwp_mail()with ato(),subject(),template(),setVariables(),send()chain.TAW\Core\Mail\MailTemplate— resolves templates frommails/html/{name}.html(production) ormails/{name}.mjml(dev, compiled viaspatie/mjml-php). Uses{{variable}}placeholder syntax.TAW\Core\Mail\MailTester— admin page under Tools → Test Emails for sending test emails against any compiled template without a real form submission.
Navigation menus
TAW\Core\Menu\Menu— typed wrapper around WordPress nav menus. Load by location slug withMenu::get('primary').TAW\Core\Menu\MenuItem— exposestitle(),url(),openInNewTab(),hasChildren(),children(),isActive(),isInActiveTrail(),classes(), and more. WP auto-classes are filtered out by default.
Asset pipeline
- Per-block assets —
style.scss(orstyle.css) andscript.jsinside any block folder are auto-detected and auto-enqueued only on pages that use that block. - Critical CSS —
resources/scss/critical.scssis compiled and inlined in<head>to eliminate a render-blocking network round-trip for above-fold styles. - Async CSS —
app.css/app.scssare loaded non-render-blocking viamedia="print"+onloadswap. - ES module JS — block scripts and the main
app.jsare loaded astype="module". - Content-hashed filenames — all production assets are cache-busted automatically.
vite_asset_url($path)/vite_is_dev()— global helpers available anywhere in your templates.- Tailwind CSS v4 via
@tailwindcss/vite. Alpine.js v3 for interactivity.
Performance
Theme::performance([...]) (forwarded to TAW\Core\Support\Performance) supports:
remove_bloat— strips unnecessary WordPress front-end scripts, styles, and features.remove_emoji— disables WordPress emoji detection scripts.remove_meta_tags— removes default WordPress generator and discovery meta tags.remove_oembed— disables oEmbed support and associated scripts.preconnect_origins— emits<link rel="preconnect">hints for external origins.preload_fonts— preloads self-hosted WOFF2 font files resolved viaViteLoader.preload_images— emits<link rel="preload">for above-fold images by attachment ID and size.
Image helper
TAW\Helpers\Image::render($id, $size, $alt, $options)— generates<img>with correctloading,fetchpriority,decoding,srcset, andsizesattributes. Pass['above_fold' => true]for hero images.TAW\Helpers\Image::preload_tag($id, $size)— generates a<link rel="preload">tag for your single most important image.
SVG support
TAW\Helpers\Svg::register()— enables sanitized SVG uploads in WordPress (called automatically byTheme::boot()).Svg::render($id, $alt, $options)— renders a sanitized<img>tag.Svg::inline($id, $options)— outputs inline SVG markup for CSS/animation targeting.Svg::url($id)— returns the URL for a stored SVG attachment.
REST API
GET /wp-json/taw/v1/search-posts— powers thepost_selectmetabox field. Supportss,post_type,per_page, andexcludeparameters. Requiresedit_postscapability.
Theme updater
TAW\Core\Theme\ThemeUpdater—removed in a later releasehooked into the WordPress update system to check a GitHub Releases URL for new versions. Shows the standard Update Available notice in admin. Updates are cached for 6 hours. Deprecated — see the v1.14 entry below.
Boot process
TAW\Core\Theme::boot()— single entrypoint that wires block loading, Vite assets, REST endpoints, and SVG support into WordPress hooks.TAW\Core\Theme::performance([...])— configures performance behavior after boot.
Was this page helpful?