Modernize theme for WordPress 7.1: theme.json, block.json registration, and the missing templates - #1
Merged
Merged
Conversation
error_log() fired on every init in inc/blocks.php, filling the site error log indefinitely. console.log() fired in every block editor session. Neither belongs in shipped code.
The blocks/*/block.json and render.php files were dead code: inc/blocks.php registered the same three blocks from inline PHP arrays with no render_callback, and assets/js/blocks.js registered them a third time client-side with its own save(). The three definitions disagreed, which is how blocks end up failing validation on re-edit. Now block.json is the single source of truth. Blocks are registered with register_block_type() against their directory, making them dynamic: save() serialises only the inner blocks and render.php emits the wrapper via get_block_wrapper_attributes(), so the align/anchor/spacing supports declared in block.json actually apply. The editor script is registered once as a shared handle referenced by each block.json "editorScript", replacing the manual enqueue_block_editor_assets hook. The alert type control moves from a raw <select> in the content area into an InspectorControls panel. Alert type classes are namespaced to is-type-* to avoid colliding with generic .error/.success utility classes; the shortcode emits the same.
The theme had no theme.json, so WordPress emitted its default Global Styles
and the theme fought back: 186 !important declarations in norton.css plus
norton_nuclear_css(), ~250 lines of duplicated rules injected at wp_head
priority 999. Both are gone.
theme.json (v3) now declares the palette, typography, spacing scale, layout
sizes and the link/heading/button element styles, and switches off the core
presets, custom colour pickers and gradients that were the source of the
conflicts. Colours reach CSS as --wp--preset--* custom properties, with the
bevel tokens under settings.custom.
The stylesheet splits in two so the editor can share it:
norton-components.css design tokens plus the box/alert/table chrome
norton.css front-end layout, header, nav, sidebar, footer
editor-style.css and add_theme_support('editor-styles') give the block
editor the theme's look. WordPress 7.0 stopped passing classic themes any
post-editor styling, so without this the canvas is plain white.
Neither stylesheet contains a single !important.
Also adds .screen-reader-text and .skip-link, a :focus-visible ring, and
drops the `cursor: default !important` on `html body *` that was removing
the text caret from inputs.
Verified against WordPress 7.1: theme.json parses as v3, all custom
properties are emitted, both editor stylesheets register, and the rendered
pages are free of PHP notices under WP_DEBUG.
Past the first page of posts there was previously no way to navigate: neither index.php nor archive.php called the_posts_pagination(). Single posts get prev/next navigation too. Comments were unreachable. The theme declared html5 support for comment-form and comment-list but shipped no comments.php and never called comments_template(). Both partials now load it when a post accepts or already has comments. Search results fell through to index.php, so a visitor got a bare list with no confirmation of what they searched for. search.php shows the query and repeats the form.
.screen-reader-text was used by the read-more and continue-reading links but never defined in CSS, so post titles rendered visibly: [READ MORE "My Post"]. The class now exists, a skip link targets #main, and there is a :focus-visible ring. The custom nav walker emitted a bare <a> per item, dropping submenus, aria-current, the menu item classes, and target/rel/title. It is gone: core's Walker_Nav_Menu supplies all of that, and CSS keeps the DOS menu-strip look — submenus drop on hover or focus-within, and stack inline on mobile. The hand-rolled fallback becomes wp_page_menu() so it emits matching markup. Also: - role="main" / role="complementary" removed; <main> and <aside> imply them. - footer.php used PHP date(), which reads the server timezone rather than the site's; now wp_date(). bloginfo() calls escaped. - style.css declares Requires at least / Tested up to / Requires PHP. - load_theme_textdomain() plus languages/norton-simple.pot, so the translation-ready tag is now true. - defined( 'ABSPATH' ) || exit; guards on every PHP file. - automatic-feed-links, responsive-embeds, align-wide, customize-selective-refresh-widgets support added; register_sidebar() moved to the widgets_init hook where it belongs. - CI Node bumped 20 -> 24; Node 20 reached end of life in April 2026.
Documents the blocks, the theme.json styling model and the new file layout, and drops the "nuclear CSS injection layer" from the feature list — it no longer exists. package-lock.json was untracked; running the build generated it, and CI runs `npm install`, so committing it makes the zip build reproducible. build.js already excludes it from the shipped theme.
mark-iid
force-pushed
the
modernize-theme
branch
from
August 28, 2026 22:30
2e1c421 to
cf9988c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the theme up to current WordPress practice. It ran fine on WP 7.1 before this, but architecturally it was a pre-5.9 classic theme: no
theme.json, no editor styles, dead block code, and a!importantlayer fighting the cascade instead of participating in it.Six commits, each self-contained and reviewable on its own.
The main change:
theme.jsonreplaces the nuclear CSSThe theme had no
theme.json, so WordPress emitted its default Global Styles and the theme fought back — 186!importantdeclarations innorton.css, plusnorton_nuclear_css(), ~250 lines of duplicated rules injected atwp_headpriority 999. Both are gone.theme.json(v3) now declares the palette, typography, spacing scale, layout sizes and the link/heading/button element styles, and switches off the core presets and custom colour pickers that caused the conflicts. Colours reach CSS as--wp--preset--*custom properties.The stylesheet splits so the editor can share it:
norton-components.cssnorton.csseditor-style.cssNeither stylesheet contains a single
!important.add_theme_support('editor-styles')gives the block editor the theme's look. WordPress 7.0 stopped passing classic themes any post-editor styling, so without this the canvas is plain white.Blocks:
block.jsonwas dead codeblocks/*/block.jsonandrender.phpexisted but nothing loaded them.inc/blocks.phpregistered the same three blocks from inline PHP arrays with norender_callback, andblocks.jsregistered them a third time client-side with its ownsave(). The three definitions disagreed — that's how blocks fail validation on re-edit.block.jsonis now the single source of truth. Blocks are dynamic:save()serialises only inner blocks,render.phpemits the wrapper viaget_block_wrapper_attributes(), so thealign/anchor/spacingsupports actually apply — and future markup changes reach existing posts without re-saving them.Unreachable features
index.phpnorarchive.phpcalledthe_posts_pagination(). Past page one there was no way to navigate.html5support forcomment-formandcomment-listbut shipped nocomments.phpand never calledcomments_template().index.phpwith no heading, so you couldn't see what you'd searched for.Accessibility
.screen-reader-textwas used by the read-more links but never defined in CSS, so post titles rendered visibly as[READ MORE "My Post Title"]. That's a visible rendering bug, not just an a11y one. Fixed, plus a skip link and a:focus-visiblering. Also droppedcursor: default !importantonhtml body *, which was removing the text caret from inputs.The nav walker is deleted, not patched
It existed only to strip
<ul>/<li>, and in doing so dropped submenus entirely, plusaria-current, menu item classes, andtarget/rel/title. Core'sWalker_Nav_Menuprovides all of that. The DOS menu-strip look is now CSS — submenus drop on hover and:focus-within, and stack inline on mobile. The hand-rolled fallback becamewp_page_menu()so it emits matching markup.Housekeeping
footer.phpused PHPdate(), which reads the server timezone rather than the site's — nowwp_date()error_log()fired on everyinit, filling the site error log indefinitely;console.log()fired in every editor sessionstyle.cssdeclaresRequires at least/Tested up to/Requires PHPload_theme_textdomain()+languages/norton-simple.pot, sotranslation-readyis now truedefined( 'ABSPATH' ) || exit;on every PHP filerole="main"/role="complementary"removedTesting
Verified against a real WordPress 7.1 + MariaDB instance driven by wp-cli and headless Chrome, not just by reading the diff:
WP_DEBUG— home, single, page, paged, search, 404, feedapiVersion 3with render callbacks;theme.jsonparses as v3 and emits every custom property.norton-boxat 20px padding with the bevel border — editor and front end matchwp theme installand renders identicallyThat testing caught a real bug introduced in this branch: a CSS comment reading
blocks/*/render.phphad its*/close the comment early, making the parser swallow the next rule and silently drop all padding and margin from.norton-boxand.norton-box-invert. Both stylesheets lint clean and every PHP file parses, so nothing static would have flagged it — only the rendered page showed it. Fixed inbf3d336.Reviewer notes
Two behaviour changes worth a decision:
theme.jsonrestricts the palette to the Norton colours —color.customand gradients are off. That's what lets the CSS drop!important. Any existing block where someone picked an arbitrary colour will fall back to the palette. Easy to re-enable if that's not wanted.Also beyond the original scope, flagged for a call:
search.phpis new, andpackage-lock.jsonis now tracked (CI runsnpm install;build.jsalready excludes it from the shipped theme).I did not claim the
accessibility-readytag — the work here would likely pass, but that tag carries a formal wordpress.org audit and none was run.