<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[57157] trunk: Block Hooks: Store ignored hooked blocks metadata in anchor block.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/57157">57157</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/57157","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>Bernhard Reiter</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2023-12-04 20:24:33 +0000 (Mon, 04 Dec 2023)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Block Hooks: Store ignored hooked blocks metadata in anchor block.

The biggest tradeoff that was made in the implementation of Block Hooks was that they were limited to layouts (i.e. templates, template parts, and patterns) that ''didn't have any user modifications'' (see <a href="https://core.trac.wordpress.org/ticket/59313">#59313</a> for the reason). This changeset is a preparatory step to remove this limitation, so they'll eventually also work with user-modified layouts.

The crucial problem to solve is how to acknowledge that a user has opted to remove or persist a hooked block, so that the auto-insertion mechanism won't run again and inject an extraneous hooked block on the frontend when none is solicited.

This is achieved by storing all known blocks hooked to a given anchor block in the `metadata` attribute on that anchor block; specifically in a field called `ignoredHookedBlocks` inside of the `metadata`. Hooked blocks are only rendered on the frontend if they're absent from that field; OTOH, they're injected into that field (via the REST API) when first loaded in the editor.

This simple logic guarantees that once a user modifies a given layout, those changes are respected on the frontend; yet if a plugin that includes a hooked block is activated after those modifications have taken place, the hooked block will be rendered on the frontend. This new technique supplants the one previously used (i.e. rendering hooked blocks on the frontend only if a layout doesn't have any modifications) in a rather direct way.

Note that this changeset only introduces the new metadata field and relevant logic; it does not yet enable hooked block insertion into modified layouts. That will be done in a subsequent step (see <a href="https://core.trac.wordpress.org/ticket/59646">#59646</a>).

Props gziolo.
Closes <a href="https://core.trac.wordpress.org/ticket/60008">#60008</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesblocksphp">trunk/src/wp-includes/blocks.php</a></li>
<li><a href="#trunktestsphpunittestsblocksgetHookedBlocksphp">trunk/tests/phpunit/tests/blocks/getHookedBlocks.php</a></li>
<li><a href="#trunktestsphpunittestsblockswpBlockPatternsRegistryphp">trunk/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestsblocksgetHookedBlockMarkupphp">trunk/tests/phpunit/tests/blocks/getHookedBlockMarkup.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesblocksphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/blocks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/blocks.php  2023-12-04 19:57:30 UTC (rev 57156)
+++ trunk/src/wp-includes/blocks.php    2023-12-04 20:24:33 UTC (rev 57157)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -758,6 +758,38 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Conditionally returns the markup for a given hooked block type.
+ *
+ * Accepts two arguments: A reference to an anchor block, and the name of a hooked block type.
+ * If the anchor block has already been processed, and the given hooked block type is in the list
+ * of ignored hooked blocks, an empty string is returned.
+ *
+ * This function is meant for internal use only.
+ *
+ * @since 6.5.0
+ * @access private
+ *
+ * @param array   $anchor_block      The anchor block. Passed by reference.
+ * @param string  $hooked_block_type The name of the hooked block type.
+ * @return string The markup for the given hooked block type, or an empty string if the block is ignored.
+ */
+function get_hooked_block_markup( &$anchor_block, $hooked_block_type ) {
+       if ( ! isset( $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) ) {
+               $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] = array();
+       }
+
+       if ( in_array( $hooked_block_type, $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) ) {
+               return '';
+       }
+
+       // The following is only needed for the REST API endpoint.
+       // However, its presence does not affect the frontend.
+       $anchor_block['attrs']['metadata']['ignoredHookedBlocks'][] = $hooked_block_type;
+
+       return get_comment_delimited_block_content( $hooked_block_type, array(), '' );
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Returns a function that injects the theme attribute into, and hooked blocks before, a given block.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * The returned function can be used as `$pre_callback` argument to `traverse_and_serialize_block(s)`,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -813,7 +845,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                         */
</span><span class="cx" style="display: block; padding: 0 10px">                        $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context );
</span><span class="cx" style="display: block; padding: 0 10px">                        foreach ( $hooked_block_types as $hooked_block_type ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $markup .= get_hooked_block_markup( $parent_block, $hooked_block_type );
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -826,7 +858,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                /** This filter is documented in wp-includes/blocks.php */
</span><span class="cx" style="display: block; padding: 0 10px">                $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context );
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $hooked_block_types as $hooked_block_type ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $markup .= get_hooked_block_markup( $block, $hooked_block_type );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                return $markup;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -874,7 +906,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                /** This filter is documented in wp-includes/blocks.php */
</span><span class="cx" style="display: block; padding: 0 10px">                $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context );
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $hooked_block_types as $hooked_block_type ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $markup .= get_hooked_block_markup( $block, $hooked_block_type );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if ( $parent_block && ! $next ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -888,7 +920,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        /** This filter is documented in wp-includes/blocks.php */
</span><span class="cx" style="display: block; padding: 0 10px">                        $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context );
</span><span class="cx" style="display: block; padding: 0 10px">                        foreach ( $hooked_block_types as $hooked_block_type ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $markup .= get_hooked_block_markup( $parent_block, $hooked_block_type );
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunktestsphpunittestsblocksgetHookedBlockMarkupphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/blocks/getHookedBlockMarkup.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/blocks/getHookedBlockMarkup.php                         (rev 0)
+++ trunk/tests/phpunit/tests/blocks/getHookedBlockMarkup.php   2023-12-04 20:24:33 UTC (rev 57157)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,68 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Tests for the get_hooked_block_markup function.
+ *
+ * @package WordPress
+ * @subpackage Blocks
+ *
+ * @since 6.5.0
+ *
+ * @group blocks
+ * @group block-hooks
+ */
+class Tests_Blocks_GetHookedBlockMarkup extends WP_UnitTestCase {
+       /**
+        * @ticket 59646
+        *
+        * @covers ::get_hooked_block_markup
+        */
+       public function test_get_hooked_block_markup_adds_metadata() {
+               $anchor_block = array(
+                       'blockName' => 'tests/anchor-block',
+               );
+
+               $actual = get_hooked_block_markup( $anchor_block, 'tests/hooked-block' );
+               $this->assertSame( array( 'tests/hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] );
+               $this->assertSame( '<!-- wp:tests/hooked-block /-->', $actual );
+       }
+
+       /**
+        * @ticket 59646
+        *
+        * @covers ::get_hooked_block_markup
+        */
+       public function test_get_hooked_block_markup_if_block_is_already_hooked() {
+               $anchor_block = array(
+                       'blockName' => 'tests/anchor-block',
+                       'attrs'     => array(
+                               'metadata' => array(
+                                       'ignoredHookedBlocks' => array( 'tests/hooked-block' ),
+                               ),
+                       ),
+               );
+
+               $actual = get_hooked_block_markup( $anchor_block, 'tests/hooked-block' );
+               $this->assertSame( array( 'tests/hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] );
+               $this->assertSame( '', $actual );
+       }
+
+       /**
+        * @ticket 59646
+        *
+        * @covers ::get_hooked_block_markup
+        */
+       public function test_get_hooked_block_markup_adds_to_ignored_hooked_blocks() {
+               $anchor_block = array(
+                       'blockName' => 'tests/anchor-block',
+                       'attrs'     => array(
+                               'metadata' => array(
+                                       'ignoredHookedBlocks' => array( 'tests/hooked-block' ),
+                               ),
+                       ),
+               );
+
+               $actual = get_hooked_block_markup( $anchor_block, 'tests/other-hooked-block' );
+               $this->assertSame( array( 'tests/hooked-block', 'tests/other-hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] );
+               $this->assertSame( '<!-- wp:tests/other-hooked-block /-->', $actual );
+       }
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestsblocksgetHookedBlocksphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/blocks/getHookedBlocks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/blocks/getHookedBlocks.php      2023-12-04 19:57:30 UTC (rev 57156)
+++ trunk/tests/phpunit/tests/blocks/getHookedBlocks.php        2023-12-04 20:24:33 UTC (rev 57157)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -149,7 +149,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $template->content
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertStringContainsString(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        '<!-- wp:post-content {"layout":{"type":"constrained"}} /-->'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 '<!-- wp:post-content {"layout":{"type":"constrained"},"metadata":{"ignoredHookedBlocks":["tests/hooked-after"]}} /-->'
</ins><span class="cx" style="display: block; padding: 0 10px">                         . '<!-- wp:tests/hooked-after /-->',
</span><span class="cx" style="display: block; padding: 0 10px">                        $template->content
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -176,7 +176,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertStringContainsString(
</span><span class="cx" style="display: block; padding: 0 10px">                        '<!-- wp:tests/hooked-before /-->'
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        . '<!-- wp:navigation {"layout":{"type":"flex","setCascadingProperties":true,"justifyContent":"right"}} /-->',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 . '<!-- wp:navigation {"layout":{"type":"flex","setCascadingProperties":true,"justifyContent":"right"},"metadata":{"ignoredHookedBlocks":["tests/hooked-before"]}} /-->',
</ins><span class="cx" style="display: block; padding: 0 10px">                         $template->content
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertStringNotContainsString(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -215,7 +215,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $pattern['content']
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertStringContainsString(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        '<!-- wp:comments -->'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 '<!-- wp:comments {"metadata":{"ignoredHookedBlocks":["tests/hooked-first-child"]}} -->'
</ins><span class="cx" style="display: block; padding: 0 10px">                         . '<div class="wp-block-comments">'
</span><span class="cx" style="display: block; padding: 0 10px">                        . '<!-- wp:tests/hooked-first-child /-->',
</span><span class="cx" style="display: block; padding: 0 10px">                        str_replace( array( "\n", "\t" ), '', $pattern['content'] )
</span></span></pre></div>
<a id="trunktestsphpunittestsblockswpBlockPatternsRegistryphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php      2023-12-04 19:57:30 UTC (rev 57156)
+++ trunk/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php        2023-12-04 20:24:33 UTC (rev 57157)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -381,14 +381,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $pattern_three['name']     = 'test/three';
</span><span class="cx" style="display: block; padding: 0 10px">                $pattern_three['content'] .= '<!-- wp:tests/my-block /-->';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $expected = array(
-                       $pattern_one,
-                       $pattern_two,
-                       $pattern_three,
-               );
-
</del><span class="cx" style="display: block; padding: 0 10px">                 $registered = $this->registry->get_all_registered();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertSame( $expected, $registered );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertCount( 3, $registered );
+               $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $registered[1]['content'] );
+               $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $registered[1]['content'] );
+               $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $registered[2]['content'] );
+               $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $registered[2]['content'] );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -444,11 +442,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->registry->register( 'test/two', $pattern_two );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $pattern_one['name']    = 'test/one';
-               $pattern_one['content'] = '<!-- wp:tests/my-block /-->' . $pattern_one['content'];
-
</del><span class="cx" style="display: block; padding: 0 10px">                 $pattern = $this->registry->get_registered( 'test/one' );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertSame( $pattern_one, $pattern );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertStringStartsWith( '<!-- wp:tests/my-block /-->', $pattern['content'] );
+               $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $pattern['content'] );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span></span></pre>
</div>
</div>

</body>
</html>