Skip to content

Render the example block on the server and name the greeting demo - #32

Merged
ahegyes merged 16 commits into
trunkfrom
fix/example-block-greeting-and-settings
Nov 10, 2026
Merged

ahegyes merged 16 commits into
trunkfrom
fix/example-block-greeting-and-settings

Conversation

@ahegyes

@ahegyes ahegyes commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

The template's example block saved English markup that the editor showed translated, registered its Outlined style from a separate script and carried no version, so its stylesheet's cache ignored the plugin's releases. The greeting thanked customers whose only orders had failed or were cancelled, loaded its stylesheet for logged-out visitors and was named Feature\Feature, and the template enqueued handles its registrars had not registered. The settings explained their defaults only in placeholders, and the validator refused whole numbers the number input sends. This renders the block on the server with its style and version in block.json, gives the editor script a command-palette command, counts only paid orders, rewords the settings, accepts any whole-number form, names the demo, the revision option and the boot boundary after their roles, and lowers the fill-in's prefix cap to 22.

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Build / CI / tooling
  • Documentation
  • Dependency update

Checklist

  • Changelog fragment added (composer changelog:add): the template takes no fragments
  • Tests added/updated
  • composer quality-check passes locally
  • Plugin header updated if runtime requirements changed: no requirement changed

Breaking changes for forks

  • Example block: dynamic, rendered by blocks/src/example-notice/render.php; save.tsx is gone, and content saved with the old static markup no longer validates. block.json carries version, styles and render, and each block's version must equal the entry's Version.
  • Editor script: registers an "Insert an example notice" command instead of the Outlined style; @wordpress/commands and @wordpress/data are devDependencies.
  • Greeting: src/Greeting/ with GreetingFeature and AccountDashboardGreeting; the toggle is DWS_TPL_OPTION_GREETING_ENABLED (dws_tpl_greeting_enabled); only paid orders count.
  • Options and boot: DWS_TPL_OPTION_REVISION holds the revision key; Plugin::$boot is Plugin::$boundary.
  • Fill-in: the prefix's segment is at most 22 characters; a name may hold { and }.

The lock held laravel/serializable-closure 2.1.0, while Packagist has
served 2.2.0 since 2026-11-10 16:11 UTC, after T-boot's check. The
declared minimum sits at the newest release, so it moves with the lock;
nothing else in either lock moved, since npm lists only TypeScript 7,
which X ruling 320 holds.

Assisted-by: Claude Code:claude-opus-5-5
The example block saves English markup that the editor shows translated,
registers its Outlined style from a separate script, and carries no
version, so its stylesheet's cache follows WordPress releases rather
than the plugin's.

These rows fail until the block renders on the server: one renders it
through translation with the Outlined class, the registration row
expects the Outlined style from block.json, a Unit row expects every
block.json to carry the entry's Version, and an end-to-end row inserts
the block through the editor's command palette (X rulings 200 and 357).

Assisted-by: Claude Code:claude-opus-5-5
The example block saved its text as English markup, because the editor
validates saved markup against the post and a translated string would
break the block in another locale, while the editor showed the text
translated. Its block.json carried no version, so WordPress versioned
its stylesheet by its own release instead of the plugin's.

The block is dynamic: block.json names render.php, which prints the
text through esc_html_e() inside the block's wrapper attributes, and
save.tsx, the save registration and the type shim's save declaration go
(X ruling 200's A240). block.json carries version 1.0.0, the entry's,
which the Unit row pins and CONTRIBUTING's release step names (A242),
and its description no longer calls the notice static. render.php joins
PHPStan's paths, as every PHP folder the plugin ships does. The display
name no longer lands in JSX text, so the fill-in stops refusing { and };
it keeps refusing < and >, which WordPress strips from the name it
shows, and Quality's comment names the editor script the name lands in.

Assisted-by: Claude Code:claude-opus-5-5
The example editor script registered the example block's Outlined
style, which block.json's styles declare natively with a translated
label, so one concept lived in two folders and the script did nothing a
script alone can do. A style on a core block, the ruled example, would
not either: register_block_style() adds one with its stylesheet in PHP.

block.json declares the Outlined style (X ruling 200's A243). The
editor script registers an "Insert an example notice" command in the
editor's command palette, whose callback inserts the example block
through the block editor's store (X ruling 357), still through
dws_tpl_register_script() and its translations. @wordpress/commands and
@wordpress/data join the devDependencies, the block-editor type shim
declares the store, and the scaffold README, tests/README.md and the
Blocks docblock describe the script.

Assisted-by: Claude Code:claude-opus-5-5
The editor-only dashed outline also covered the Outlined style, so in
the editor and the inserter's preview that style looked dashed rather
than as it renders.

The outline applies to :not(.is-style-outlined) (X ruling 200's A247).

Assisted-by: Claude Code:claude-opus-5-5
The greeting counts every order a customer has placed, failed,
cancelled and draft orders included; its stylesheet loads on the
account page for visitors who see no greeting; and the template's own
calls enqueue a handle whether or not their registrar registered it,
so a handle another plugin took first is enqueued as the plugin's.

These rows fail until the greeting counts only paid orders, the
stylesheet skips logged-out visitors and both enqueues follow their
registrar (X ruling 200's A241, A245 and A246). The greeting's other
rows place completed orders, and the stylesheet's cleanup runs after
every row.

Assisted-by: Claude Code:claude-opus-5-5
The greeting thanked customers whose only orders had failed, were
cancelled or were drafts, since wc_get_customer_order_count() counts
every status. Its stylesheet loaded on the account page for visitors
who are never greeted, and the editor script and the stylesheet were
enqueued even when their registrar had registered nothing, so a handle
another plugin took first was enqueued as the plugin's.

The greeting counts the customer's orders in WooCommerce's paid
statuses, up to the set number (X ruling 200's A241); the stylesheet
skips logged-out visitors (A245); and both enqueues run only when their
registrar returns true, as the ports' do (A246).

Assisted-by: Claude Code:claude-opus-5-5
The greeting's default is explained only by a placeholder, the toggle
row repeats the section's title, the consent field drops the warning
the ports give, the threshold's description counts unpaid orders, the
validator refuses whole numbers the number input sends, such as 03 and
3.0, and the build notice words its outcome unlike the framework's.

These rows fail until the fields read as X ruling 201 words them
(A248, A249, A252, and the threshold under A241), the validator stores
any whole number of at least 1 as its digits (A250), and the build
notice follows the framework's sentence (A254); 1e20, which no integer
holds, stays refused.

Assisted-by: Claude Code:claude-opus-5-5
The greeting's default lived only in a placeholder that phones cut off,
the toggle row repeated the section's title, the consent field dropped
the warning v1 and the ports give, the threshold's description still
counted every placed order, the validator refused whole numbers the
number input sends, such as 03 and 3.0, and the build notice worded its
outcome unlike the framework's notices.

The message field explains its empty value (X ruling 201's A248), the
consent field reads as the ports' (A249), the toggle row reads "Show
the greeting" (A252), and the threshold names paid orders (A241). The
validator parses the submission as a float and stores any whole number
of at least 1 as its digits (A250), as both recipes' validators do now,
and the build notice says the features stay off until the plugin is
reinstalled (A254). The framework's rejection sentence already confirms
the other changes (A251).

Assisted-by: Claude Code:claude-opus-5-5
The migration runner's revision option had no constant, so its literal
was built again in the composition root, the footprint and four test
classes, and every port copied each of them.

DWS_TPL_OPTION_REVISION, written as its literal, holds the key in
includes/options.php; the composition root, the footprint's cron hook,
FootprintTest and the Integration rows read it, and the Without
WooCommerce recipe's options.php and composition keep it (X ruling
203's A262).

Assisted-by: Claude Code:claude-opus-5-5
The demo lived in src/Feature/ as Feature and FeatureDetail, a folder
named after the one class it held and two names that say nothing of
what they do, behind a toggle named DWS_TPL_OPTION_FEATURE; every
plugin built from the template inherited the names.

The demo lives in src/Greeting/: GreetingFeature is its composite and
AccountDashboardGreeting its leaf, named for the surface it greets on,
and the toggle is DWS_TPL_OPTION_GREETING_ENABLED, whose key,
dws_tpl_greeting_enabled, is written as its literal (X ruling 203's
A263). The tests, AGENTS.md's layout, the scaffold README's removal row
and the Without WooCommerce recipe follow.

Assisted-by: Claude Code:claude-opus-5-5
DWS_TPL_OPTION_GREETING_ENABLED is one character longer than
DWS_TPL_OPTION_GREETING_ORDERS, so with a 23-character segment its
filled-in name pushes includes/migrations.php's array arrows past
column 60, where PHPCS stops aligning them and the plugin's first
composer lint:php fails; at 22 both files pass.

The fill-in accepts a segment of at most 22 characters, its message and
comment say so, the README's naming rule follows, and Quality rehearses
at the new cap with dws_acmeextraordinarysales (X ruling 196's A218).

Assisted-by: Claude Code:claude-opus-5-5
uninstall.php copied DWS_TPL_OPTION_DELETE_DATA into a variable inside
its try block and passed the copy, though the constant exists wherever
the call runs: a failed require of includes/options.php returns before
it.

Uninstaller::run() takes the constant itself, and the Without
WooCommerce recipe passes its consent array the same way (X ruling
203's A264).

Assisted-by: Claude Code:claude-opus-5-5
dws_tpl_get_asset() built the .asset.php path from basename() of the
path less an extension pathinfo() had read, three calls where
pathinfo()'s filename is one, and dws_tpl_register_script() padded its
three @PARAM lines to a 90-column array shape.

The path reads pathinfo( $path, PATHINFO_FILENAME ), and $args is an
array whose shape a @phpstan-param carries, which PHPStan still checks
at every call (X ruling 203's A265).

Assisted-by: Claude Code:claude-opus-5-5
Plugin exposed a $boot property beside a boot() method, so
$this->boot->run() inside boot() and ->boot->status beside ->boot()
read alike, and a reader had to check the parentheses to tell the
boundary from the action.

The property is $boundary, the diagnostic reads
dws_tpl_plugin()->boundary->status, and the boot rows, the
without-WooCommerce spec and the Without WooCommerce recipe follow, as
the framework's fixtures do (X ruling 203's A266).

Assisted-by: Claude Code:claude-opus-5-5
The wording row held its fields in an array keyed by the option
constants three tabs deep, so a plugin filled in at the prefix cap,
whose constants are 22 characters longer, pushed the arrows past column
60, where PHPCS stops aligning them, and its first composer lint:php
failed in Quality's rehearsal.

The fields come from a data provider keyed toggle, message, threshold
and consent, one row each.

Assisted-by: Claude Code:claude-opus-5-5
@ahegyes ahegyes changed the title Fix/example block greeting and settings Render the example block on the server and name the greeting demo Nov 10, 2026
@ahegyes
ahegyes merged commit 7348b53 into trunk Nov 10, 2026
36 checks passed
@ahegyes
ahegyes deleted the fix/example-block-greeting-and-settings branch November 10, 2026 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant