WordPress 6.9: GOV.UK Accordion via Core Blocks

dgw.ltd November 10, 2025
Source

We are drawing closer to the release of WordPress 6.9, so I figured it was time to road-test the theme and plugins that drive this site. As I’ve been experimenting more with bleeding-edge WP technologies – such as the Abilities API, Interactivity API, and other goodies — I realised that, more so than other updates, I might be exposed to breaking changes. So it’s better to test the beta. As expected, it was pretty smooth. A couple of things needed fixing, but overall it was fine. It’s always worth digging through what to expect in new releases to see what’s new. In this release, there is a shiny new Accordion core block, which renders one of my ACF blocks redundant. I’ve deleted it, meaning I now have only six custom blocks managed via ACF custom fields. Even a couple of those are technically redundant, as I’ve moved much more towards using a mixture of the following methods for amending and extending core blocks: Block variations via registerBlockVariation Block modifiers via WP_HTML_Tag_Processor Block styles A mixture of one or more of these allows us to build out customised core blocks, meaning we’re using native blocks in the editor – and benefiting from all the support and development that brings. Back to the Accordion block. The challenge I faced is that I want to use the GOV.UK’s design system on my front end. So could we use some of these techniques to adapt the new WordPress Accordion block to render more like the GOV.UK version? The answer is yes – here is the code. public function dgwltd_utility_edit_accordion_markup( $block_content, $block, $instance ) { $tags = new WP_HTML_Tag_Processor( $block_content ); $section_count = 0; // Add wrapper classes if ( $tags->next_tag( [ 'class_name' => 'wp-block-accordion' ] ) ) { $tags->add_class( 'govuk-accordion' ); $tags->add_class( 'dgwltd-block-accordion' ); $tags->set_attribute( 'data-module', 'govuk-accordion' ); $tags->set_attribute( 'id', 'accordion-' . get_the_ID() ); } $html = $tags->get_updated_html(); $tags = new WP_HTML_Tag_Processor( $html ); // Process each accordion item while ( $tags->next_tag( [ 'class_name' => 'wp-block-accordion-item' ] ) ) { $section_count++; $tags->add_class( 'govuk-accordion__section' ); $item_bookmark = $tags->set_bookmark( 'accordion_item' ); // Add h3 heading class if ( $tags->next_tag( [ 'tag_name' => 'h3' ] ) ) { $tags->add_class( 'govuk-accordion__section-heading' ); } $tags->seek( 'accordion_item' ); // Add button classes if ( $tags->next_tag( [ 'class_name' => 'wp-block-accordion-heading__toggle' ] ) ) { $tags->add_class( 'govuk-accordion__section-button' ); $tags->set_attribute( 'id', 'accordion-heading-' . $section_count ); } $tags->seek( 'accordion_item' ); // Icon if ( $tags->next_tag( [ 'class_name' => 'wp-block-accordion-heading__toggle-icon' ] ) ) { $tags->add_class( 'visually-hidden' ); } $tags->seek( 'accordion_item' ); // Add content panel classes if ( $tags->next_tag( [ 'class_name' => 'wp-block-accordion-panel' ] ) ) { $tags->add_class( 'govuk-accordion__section-content' ); $tags->set_attribute( 'id', 'accordion-content-' . $section_count ); } $tags->seek( 'accordion_item' ); } $html = $tags->get_updated_html(); // Wrap h3 in section-header div $html = preg_replace( '/(<h3[^>]class="[^"]govuk-accordion__section-heading[^"]"[^>]>.*?</h3>)/s', '

$1
', $html ); return $html; } The regex is a little gnarly because the markup between the two systems doesn’t map directly; we needed one more nested section. I also had to suppress one element via a CSS class, but that seems acceptable to me. And here is the final output: a native WordPress Accordion block, styled as a GOV.UK one. Writing well for the web+ This is the content for Writing well for the web. Writing well for specialists+ This is the content for Writing well for specialists. Know your audience+ This is the content for Know your audience. How people read+ This is the content for How people read.

Discussion in the ATmosphere

Loading comments...