Make WordPress Core

#46471 closed defect (bug) (fixed)

Malformed content when using the More block and stripping the teaser

Reported by: lukecarbis Owned by: azaozz
Milestone: 5.2 Priority: normal
Severity: normal Version:
Component: Editor Keywords: has-patch needs-testing
Focuses: Cc:


When using the_content() and specifying the $strip_teaser argument as true, the output contains a malformed "More" block.

Steps to reproduce:

  1. In your theme's single template, output content using <?php the_content( null, true ); ?>
  2. Create a a post that includes multiple paragraph blocks, separated by a single More block

The expected output is:

<span id="more-123"></span>

<p>Second block.</p>

The actual output is:

<span id="more-123"></span>
<!-- /wp:more -->

<!-- wp:paragraph -->
<p>Second block.</p>
<!-- /wp:paragraph -->

Notice that the closing <!-- /wp:more --> tag exists, but the opening one doesn't. Additionally, the malformed block tag at the beginning causes none of the other block tags to be cleaned up.

Most importantly, it breaks any dynamic blocks completed.

Attachments (5)

46471.diff (681 bytes) - added by lukecarbis 23 months ago.
with-patch-46471.png (328.6 KB) - added by ryankienstra 23 months ago.
posts-page-46471.png (431.4 KB) - added by ryankienstra 23 months ago.
46471.1.diff (683 bytes) - added by garrett-eclipse 22 months ago.
Minor grammar fix for the comment. 'it's' indicates 'it is', but the sentence needed 'it has' to read properly.
46471-2.diff (5.8 KB) - added by birgire 22 months ago.

Download all attachments as: .zip

Change History (13)

23 months ago

#1 @lukecarbis
23 months ago

  • Keywords has-patch needs-testing added; needs-patch removed

This patch removes the <!-- wp:more --> starting block tag from the teaser, and the <!-- /wp:more –> closing block tag from the main content.

#2 @ryankienstra
23 months ago

Looks Good, Works As Expected

Hi @lukecarbis,
This looks good. Like you mentioned, I also saw that this removed the extra <!-- /wp:more --> comment.

The single post template looks good, as does the 'Posts' page with multiple posts (shown above).

#3 @lukecarbis
22 months ago

  • Milestone changed from 5.1.2 to 5.2

22 months ago

Minor grammar fix for the comment. 'it's' indicates 'it is', but the sentence needed 'it has' to read properly.

22 months ago

#4 @birgire
22 months ago

As mentioned, the content can be dived through <!--more(.*?)?--> regardless of any More block wrappers around it, leaving unclosed More block tags in each part.

I guess one could enhance that splitting with preg_split() but I think that would not be as clean and simple as in 46471.1.diff.

Currently 46471.1.diff runs the preg_replacement, regardless if there are any blocks in the content or not. The has_block( 'more', $content ) (passing content to avoid get_post) comes to mind or a simple strpos check. I would expect the strpos vs preg_replace performance would only show up for very large content and multiple calls.

Maybe this More block content check is not needed as I can imagine more and more content will contain blocks.

We can also see this with the_content() when using the noteaser text tag.


<!-- wp:paragraph -->
<p>Teaser part.</p>
<!-- /wp:paragraph -->

<!-- wp:more -->
<!-- /wp:more -->

<!-- wp:paragraph -->
<p>Second block.</p>
<!-- /wp:paragraph -->

The patch in 46471-2.diff is a first iteration of tests for 46471.1.diff.

#5 @afercia
22 months ago

  • Component changed from General to Editor

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.

22 months ago

#7 @azaozz
21 months ago

This is somewhat similar to #46133. Ideally the post content should be split on <!--more--> after the blocks have been parsed. As that's not possible, seems the only way to fix this is to treat the <!-- wp:more ... --> block same as the <!--more--> tag: split the post at that place and remove the tag and the block.

Looking at 46471-2.diff, it seems to work properly (I know, parsing strings out of HTML with regex is...). Wondering if it would be a bit better to do a str_replace() for the block end delimiter. Makes the regex a tiny bit simpler and we need to run it only on the first part of the split post_content.

#8 @azaozz
21 months ago

  • Owner set to azaozz
  • Resolution set to fixed
  • Status changed from new to closed

In 45261:

Remove the core/more block delimiters when splitting post_content on the <!--more--> tag.

  • Parsing of blocks in the second half of post_content.
  • Outputting malformed HTML when the_content( null, true ) or <!--noteaser--> is used.

Props lukecarbis, garrett-eclipse, birgire.
Fixes #46471.

Note: See TracTickets for help on using tickets.