diff --git a/CHANGELOG.md b/CHANGELOG.md index ee02330..23e6104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [Unreleased] — Replace the phase-services dynamic block with per-phase patterns (LS-4179) + +### Changed + +- Replaced the `ls-theme/phase-services` dynamic block, which chose its "Services in this phase" cards from the current page slug, with six static patterns you can insert from the editor: `patterns/sections/phase-services-{discover,create,build,launch,grow,evolve}.php` (Section - Phase Services: Discover … Evolve). Each one holds its own phase's heading, service tiles and phase accent colour, so the content no longer depends on which page it's placed on. + +### Removed + +- `blocks/phase-services/`, `inc/blocks.php` (and its `require` in `functions.php`), and `patterns/sections/phase-services-in-phase.php`, the wrapper pattern that only contained the block. + +([#76](https://github.com/lightspeedwp/ls-theme/pull/76)) + +--- + ## [Unreleased] — Make phase section patterns follow the current phase colour (LS-4179) ### Fixed diff --git a/blocks/phase-services/block.json b/blocks/phase-services/block.json deleted file mode 100644 index e64ee3e..0000000 --- a/blocks/phase-services/block.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 3, - "name": "ls-theme/phase-services", - "title": "Phase Services", - "category": "text", - "description": "Renders the current lifecycle phase page's \"Services in this phase\" heading and service cards. Implements CodeRabbit's request-time rendering fix for patterns/sections/phase-services-in-phase.php: PHP phase-detection baked into a pattern's own content only re-evaluates while the pattern stays a live wp:pattern reference, and is lost if WordPress flattens it, so the phase-dependent selection and markup now live in this dynamic block's render.php instead, which runs at real request time regardless of how the surrounding pattern is stored.", - "textdomain": "ls-theme", - "usesContext": [ "postId" ], - "render": "file:./render.php" -} diff --git a/blocks/phase-services/index.js b/blocks/phase-services/index.js deleted file mode 100644 index 065d90f..0000000 --- a/blocks/phase-services/index.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Editor-side registration for ls-theme/phase-services. - * - * The PHP registration in inc/blocks.php (register_block_type against this folder's block.json) - * only tells WordPress how to render this block on the front end — the block editor's own JS - * registry is entirely separate, and needs its own wp.blocks.registerBlockType() call by the same - * name or it shows "Your site doesn't include support for this block" and renders nothing in the - * canvas. ServerSideRender is used for `edit` (rather than reimplementing the markup in JS) so the - * editor preview always matches render.php's actual output, including the current phase's real - * content and colour — no separate editor-only representation to keep in sync. - * - * Plain global-based script (no build step), per AGENTS.md "Avoid inventing a build pipeline". - * - * @package ls-theme - */ -( function ( blocks, element, serverSideRender ) { - var el = element.createElement; - - blocks.registerBlockType( 'ls-theme/phase-services', { - title: 'Phase Services', - category: 'text', - usesContext: [ 'postId' ], - description: 'Renders the current phase page\'s "Services in this phase" heading and service cards.', - edit: function ( props ) { - return el( serverSideRender, { - block: 'ls-theme/phase-services', - urlQueryArgs: { post_id: props.context ? props.context.postId : undefined }, - } ); - }, - save: function () { - return null; - }, - } ); -} )( window.wp.blocks, window.wp.element, window.wp.serverSideRender ); diff --git a/blocks/phase-services/render.php b/blocks/phase-services/render.php deleted file mode 100644 index 28bf9bc..0000000 --- a/blocks/phase-services/render.php +++ /dev/null @@ -1,213 +0,0 @@ - array( - array( - 'label' => __( 'Discovery', 'ls-theme' ), - 'description' => __( 'Stakeholder workshops, audits, scoping and feasibility — the evidence layer that comes before design or build.', 'ls-theme' ), - 'url' => '/services/discovery/', - 'icon' => 'search', - ), - ), - 'create' => array( - array( - 'label' => __( 'Content', 'ls-theme' ), - 'description' => __( 'Content modelling, editorial workflow and governance that holds up at scale.', 'ls-theme' ), - 'url' => '/services/content/', - 'icon' => 'file-text', - ), - array( - 'label' => __( 'Design', 'ls-theme' ), - 'description' => __( 'Design systems, accessible patterns and Figma→WordPress parity. Already a deeper page.', 'ls-theme' ), - 'url' => '/services/design/', - 'icon' => 'paint-brush', - ), - ), - 'build' => array( - array( - 'label' => __( 'Development', 'ls-theme' ), - 'description' => __( 'Block themes, WooCommerce, integrations and platform refactors built for long-term health.', 'ls-theme' ), - 'url' => '/services/development/', - 'icon' => 'code', - ), - array( - 'label' => __( 'Migrations', 'ls-theme' ), - 'description' => __( 'Audits, mapping and redirects that take legacy platforms apart without losing traction.', 'ls-theme' ), - 'url' => '/services/migrations/', - 'icon' => 'arrows-left-right', - ), - ), - 'launch' => array( - array( - 'label' => __( 'Hosting', 'ls-theme' ), - 'description' => __( 'Managed environments that match the platform, the workflows and the support model around it.', 'ls-theme' ), - 'url' => '/services/hosting/', - 'icon' => 'cloud', - ), - array( - 'label' => __( 'Performance', 'ls-theme' ), - 'description' => __( 'Core Web Vitals, caching, query review and template optimisation against real production data.', 'ls-theme' ), - 'url' => '/services/performance/', - 'icon' => 'gauge', - ), - array( - 'label' => __( 'Security', 'ls-theme' ), - 'description' => __( 'Audits, hardening guidance, monitoring and recovery planning that reduces risk before incidents.', 'ls-theme' ), - 'url' => '/services/security/', - 'icon' => 'shield', - ), - array( - 'label' => __( 'Training', 'ls-theme' ), - 'description' => __( 'Role-specific training and reference materials that move teams from dependency to confidence.', 'ls-theme' ), - 'url' => '/services/training/', - 'icon' => 'graduation-cap', - ), - ), - 'grow' => array( - array( - 'label' => __( 'Support', 'ls-theme' ), - 'description' => __( 'Maintenance, incident response and quiet improvement so platforms keep getting easier to run.', 'ls-theme' ), - 'url' => '/services/support/', - 'icon' => 'lifebuoy', - ), - array( - 'label' => __( 'SEO', 'ls-theme' ), - 'description' => __( 'Technical SEO, internal linking, schema and the publishing discipline that supports visibility.', 'ls-theme' ), - 'url' => '/services/seo/', - 'icon' => 'chart-line-up', - ), - array( - 'label' => __( 'Accessibility', 'ls-theme' ), - 'description' => __( 'Audits, remediation and the semantic structure that helps WCAG 2.2 AA stick over time.', 'ls-theme' ), - 'url' => '/services/accessibility/', - 'icon' => 'wheelchair', - ), - array( - 'label' => __( 'Email marketing', 'ls-theme' ), - 'description' => __( 'Journey planning, consent flows and the connection between email and the WordPress platform behind it.', 'ls-theme' ), - 'url' => '/services/email-marketing/', - 'icon' => 'envelope', - ), - ), - 'evolve' => array( - array( - 'label' => __( 'AI', 'ls-theme' ), - 'description' => __( 'AI-readiness reviews, governance and workflow planning — practical use without messy adoption.', 'ls-theme' ), - 'url' => '/services/ai/', - 'icon' => 'special-interests', - ), - ), -); - -$ls_phase_labels = array( - 'discover' => __( 'Discover', 'ls-theme' ), - 'create' => __( 'Create', 'ls-theme' ), - 'build' => __( 'Build', 'ls-theme' ), - 'launch' => __( 'Launch', 'ls-theme' ), - 'grow' => __( 'Grow', 'ls-theme' ), - 'evolve' => __( 'Evolve', 'ls-theme' ), -); - -$ls_post_id = isset( $block->context['postId'] ) ? (int) $block->context['postId'] : (int) get_the_ID(); -if ( ! $ls_post_id ) { - $ls_post_id = (int) get_queried_object_id(); -} - -$ls_current_phase_slug = ''; -$ls_queried_post = get_post( $ls_post_id ); -if ( $ls_queried_post instanceof WP_Post ) { - $ls_current_phase_slug = $ls_queried_post->post_name; -} - -$ls_active_phase_slug = isset( $ls_phase_services_by_phase[ $ls_current_phase_slug ] ) ? $ls_current_phase_slug : 'discover'; -$ls_active_phase_label = $ls_phase_labels[ $ls_active_phase_slug ]; -$ls_active_services = $ls_phase_services_by_phase[ $ls_active_phase_slug ]; -$ls_service_rows = array_chunk( $ls_active_services, 4 ); -$ls_phase_accent = 'var(--wp--custom--color--phase--' . $ls_active_phase_slug . ')'; - -ob_start(); -?> - -
- -

- - - -

- - - -

- -
- - - $ls_row ) : ?> - -
- - -
- -
- -
- - - -
- -

- - - -
- -

- -
- -
- - - - - -
- - -
- - - __( 'Development', 'ls-theme' ), + 'description' => __( 'Block themes, WooCommerce, integrations and platform refactors built for long-term health.', 'ls-theme' ), + 'url' => '/services/development/', + 'icon' => 'code', + ), + array( + 'label' => __( 'Migrations', 'ls-theme' ), + 'description' => __( 'Audits, mapping and redirects that take legacy platforms apart without losing traction.', 'ls-theme' ), + 'url' => '/services/migrations/', + 'icon' => 'arrows-left-right', + ), +); + +$ls_service_rows = array_chunk( $ls_services, 4 ); +$ls_phase_accent = 'var(--wp--custom--color--phase--build)'; +?> + +
+ + +
+ +

+ + + +

+ + + +

+ +
+ + $ls_row ) : ?> + + +
+ + + +
+ +
+ +
+ + + +
+ +

+ + + +
+ +

+ +
+ +
+ + + + + +
+ + +
+ + + +
+ diff --git a/patterns/sections/phase-services-create.php b/patterns/sections/phase-services-create.php new file mode 100644 index 0000000..af2a02e --- /dev/null +++ b/patterns/sections/phase-services-create.php @@ -0,0 +1,99 @@ + __( 'Content', 'ls-theme' ), + 'description' => __( 'Content modelling, editorial workflow and governance that holds up at scale.', 'ls-theme' ), + 'url' => '/services/content/', + 'icon' => 'file-text', + ), + array( + 'label' => __( 'Design', 'ls-theme' ), + 'description' => __( 'Design systems, accessible patterns and Figma→WordPress parity. Already a deeper page.', 'ls-theme' ), + 'url' => '/services/design/', + 'icon' => 'paint-brush', + ), +); + +$ls_service_rows = array_chunk( $ls_services, 4 ); +$ls_phase_accent = 'var(--wp--custom--color--phase--create)'; +?> + +
+ + +
+ +

+ + + +

+ + + +

+ +
+ + $ls_row ) : ?> + + +
+ + + +
+ +
+ +
+ + + +
+ +

+ + + +
+ +

+ +
+ +
+ + + + + +
+ + +
+ + + +
+ diff --git a/patterns/sections/phase-services-discover.php b/patterns/sections/phase-services-discover.php new file mode 100644 index 0000000..54b7f6f --- /dev/null +++ b/patterns/sections/phase-services-discover.php @@ -0,0 +1,93 @@ + __( 'Discovery', 'ls-theme' ), + 'description' => __( 'Stakeholder workshops, audits, scoping and feasibility — the evidence layer that comes before design or build.', 'ls-theme' ), + 'url' => '/services/discovery/', + 'icon' => 'search', + ), +); + +$ls_service_rows = array_chunk( $ls_services, 4 ); +$ls_phase_accent = 'var(--wp--custom--color--phase--discover)'; +?> + +
+ + +
+ +

+ + + +

+ + + +

+ +
+ + $ls_row ) : ?> + + +
+ + + +
+ +
+ +
+ + + +
+ +

+ + + +
+ +

+ +
+ +
+ + + + + +
+ + +
+ + + +
+ diff --git a/patterns/sections/phase-services-evolve.php b/patterns/sections/phase-services-evolve.php new file mode 100644 index 0000000..d22ed7e --- /dev/null +++ b/patterns/sections/phase-services-evolve.php @@ -0,0 +1,93 @@ + __( 'AI', 'ls-theme' ), + 'description' => __( 'AI-readiness reviews, governance and workflow planning — practical use without messy adoption.', 'ls-theme' ), + 'url' => '/services/ai/', + 'icon' => 'special-interests', + ), +); + +$ls_service_rows = array_chunk( $ls_services, 4 ); +$ls_phase_accent = 'var(--wp--custom--color--phase--evolve)'; +?> + +
+ + +
+ +

+ + + +

+ + + +

+ +
+ + $ls_row ) : ?> + + +
+ + + +
+ +
+ +
+ + + +
+ +

+ + + +
+ +

+ +
+ +
+ + + + + +
+ + +
+ + + +
+ diff --git a/patterns/sections/phase-services-grow.php b/patterns/sections/phase-services-grow.php new file mode 100644 index 0000000..7c7d08c --- /dev/null +++ b/patterns/sections/phase-services-grow.php @@ -0,0 +1,111 @@ + __( 'Support', 'ls-theme' ), + 'description' => __( 'Maintenance, incident response and quiet improvement so platforms keep getting easier to run.', 'ls-theme' ), + 'url' => '/services/support/', + 'icon' => 'lifebuoy', + ), + array( + 'label' => __( 'SEO', 'ls-theme' ), + 'description' => __( 'Technical SEO, internal linking, schema and the publishing discipline that supports visibility.', 'ls-theme' ), + 'url' => '/services/seo/', + 'icon' => 'chart-line-up', + ), + array( + 'label' => __( 'Accessibility', 'ls-theme' ), + 'description' => __( 'Audits, remediation and the semantic structure that helps WCAG 2.2 AA stick over time.', 'ls-theme' ), + 'url' => '/services/accessibility/', + 'icon' => 'wheelchair', + ), + array( + 'label' => __( 'Email marketing', 'ls-theme' ), + 'description' => __( 'Journey planning, consent flows and the connection between email and the WordPress platform behind it.', 'ls-theme' ), + 'url' => '/services/email-marketing/', + 'icon' => 'envelope', + ), +); + +$ls_service_rows = array_chunk( $ls_services, 4 ); +$ls_phase_accent = 'var(--wp--custom--color--phase--grow)'; +?> + +
+ + +
+ +

+ + + +

+ + + +

+ +
+ + $ls_row ) : ?> + + +
+ + + +
+ +
+ +
+ + + +
+ +

+ + + +
+ +

+ +
+ +
+ + + + + +
+ + +
+ + + +
+ diff --git a/patterns/sections/phase-services-in-phase.php b/patterns/sections/phase-services-in-phase.php deleted file mode 100644 index 248ba09..0000000 --- a/patterns/sections/phase-services-in-phase.php +++ /dev/null @@ -1,29 +0,0 @@ - - -
- -
- diff --git a/patterns/sections/phase-services-launch.php b/patterns/sections/phase-services-launch.php new file mode 100644 index 0000000..e8ee687 --- /dev/null +++ b/patterns/sections/phase-services-launch.php @@ -0,0 +1,111 @@ + __( 'Hosting', 'ls-theme' ), + 'description' => __( 'Managed environments that match the platform, the workflows and the support model around it.', 'ls-theme' ), + 'url' => '/services/hosting/', + 'icon' => 'cloud', + ), + array( + 'label' => __( 'Performance', 'ls-theme' ), + 'description' => __( 'Core Web Vitals, caching, query review and template optimisation against real production data.', 'ls-theme' ), + 'url' => '/services/performance/', + 'icon' => 'gauge', + ), + array( + 'label' => __( 'Security', 'ls-theme' ), + 'description' => __( 'Audits, hardening guidance, monitoring and recovery planning that reduces risk before incidents.', 'ls-theme' ), + 'url' => '/services/security/', + 'icon' => 'shield', + ), + array( + 'label' => __( 'Training', 'ls-theme' ), + 'description' => __( 'Role-specific training and reference materials that move teams from dependency to confidence.', 'ls-theme' ), + 'url' => '/services/training/', + 'icon' => 'graduation-cap', + ), +); + +$ls_service_rows = array_chunk( $ls_services, 4 ); +$ls_phase_accent = 'var(--wp--custom--color--phase--launch)'; +?> + +
+ + +
+ +

+ + + +

+ + + +

+ +
+ + $ls_row ) : ?> + + +
+ + + +
+ +
+ +
+ + + +
+ +

+ + + +
+ +

+ +
+ +
+ + + + + +
+ + +
+ + + +
+ diff --git a/patterns/sections/phase-where-to-go-next.php b/patterns/sections/phase-where-to-go-next.php index 6d55e87..115e23f 100644 --- a/patterns/sections/phase-where-to-go-next.php +++ b/patterns/sections/phase-where-to-go-next.php @@ -9,7 +9,7 @@ * Our Process overview); the eyebrow and card content still need to be pulled out per-page before * this is reused on the other five pages. Two equal-width cards reusing the existing * Card - Link Row style and Link Arrow Accent paragraph style (same "Explore service"/"Read more" - * convention used in phase-services-in-phase.php), rather than the source design's 4-column grid, + * convention used in the phase-services-{phase}.php patterns), rather than the source design's 4-column grid, * which only ever renders two cards. Adapts between the site's light and dark style variations via * text tokens; the phase accent uses the plain phase.{slug} token, same reasoning as * phase-support-focus.php and phase-common-services.php.