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

Fixes:
- 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.

git-svn-id: https://develop.svn.wordpress.org/trunk@45261 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz 2019-04-24 05:40:01 +00:00
parent e13ef071ff
commit 361333e7e2
2 changed files with 185 additions and 0 deletions

View File

@ -314,7 +314,13 @@ function get_the_content( $more_link_text = null, $strip_teaser = false, $post =
$page_no = $elements['page'];
$content = $elements['pages'][ $page_no - 1 ];
if ( preg_match( '/<!--more(.*?)?-->/', $content, $matches ) ) {
if ( has_block( 'more', $content ) ) {
// Remove the core/more block delimiters. They will be left over after $content is split up.
$content = preg_replace( '/<!-- \/?wp:more(.*?) -->/', '', $content );
}
$content = explode( $matches[0], $content, 2 );
if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) ) {
$more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) );
}

View File

@ -175,4 +175,183 @@ EOF;
kses_remove_filters();
}
/**
* Ensure the_content handles a More block on a singular page.
*
* @ticket 46471
*
* @group blocks
*/
public function test_the_content_should_handle_more_block_on_singular() {
$post_content = <<<EOF
<!-- wp:paragraph -->
<p>Teaser part.</p>
<!-- /wp:paragraph -->
<!-- wp:more {"customText":"Read More"} -->
<!--more Read More-->
<!-- /wp:more -->
<!-- wp:paragraph -->
<p>Second block.</p>
<!-- /wp:paragraph -->
EOF;
$post_id = self::factory()->post->create( compact( 'post_content' ) );
$expected_without_teaser = <<<EOF
<span id="more-{$post_id}"></span>
<p>Second block.</p>
EOF;
$expected_with_teaser = <<<EOF
<p>Teaser part.</p>
<span id="more-{$post_id}"></span>
<p>Second block.</p>
EOF;
$this->go_to( get_permalink( $post_id ) );
$this->assertTrue( is_singular() );
$this->assertTrue( have_posts() );
$this->assertNull( the_post() );
// Without the teaser.
$actual = get_echo( 'the_content', array( null, true ) );
$this->assertSame( strip_ws( $expected_without_teaser ), strip_ws( $actual ) );
// With the teaser.
$actual = get_echo( 'the_content', array( null, false ) );
$this->assertSame( strip_ws( $expected_with_teaser ), strip_ws( $actual ) );
}
/**
* Ensure the_content handles a More block when using the noteaser text tag on a singular page.
*
* @ticket 46471
*
* @group blocks
*/
public function test_the_content_should_handle_more_block_when_noteaser_on_singular() {
$post_content = <<<EOF
<!-- wp:paragraph -->
<p>Teaser part.</p>
<!-- /wp:paragraph -->
<!-- wp:more -->
<!--more-->
<!--noteaser-->
<!-- /wp:more -->
<!-- wp:paragraph -->
<p>Second block.</p>
<!-- /wp:paragraph -->
EOF;
$post_id = self::factory()->post->create( compact( 'post_content' ) );
$expected = <<<EOF
<span id="more-{$post_id}"></span>
<!--noteaser-->
<p>Second block.</p>
EOF;
$this->go_to( get_permalink( $post_id ) );
$this->assertTrue( is_singular() );
$this->assertTrue( have_posts() );
$this->assertNull( the_post() );
$actual = get_echo( 'the_content', array( null, true ) );
$this->assertSame( strip_ws( $expected ), strip_ws( $actual ) );
$actual = get_echo( 'the_content', array( null, false ) );
$this->assertSame( strip_ws( $expected ), strip_ws( $actual ) );
}
/**
* Ensure the_content displays the teaser part with a read more link
* for a More block on a non-singular page.
*
* @ticket 46471
*
* @group blocks
*/
public function test_the_content_should_handle_more_block_when_non_singular() {
$post_content = <<<EOF
<!-- wp:paragraph -->
<p>Teaser part.</p>
<!-- /wp:paragraph -->
<!-- wp:more {"customText":"Read More"} -->
<!--more Read More-->
<!-- /wp:more -->
<!-- wp:paragraph -->
<p>Second block.</p>
<!-- /wp:paragraph -->
EOF;
$post_id = self::factory()->post->create( compact( 'post_content' ) );
$expected = <<<EOF
<span id="more-{$post_id}"></span>
<p>Second block.</p>
EOF;
$this->go_to( home_url() );
$this->assertFalse( is_singular() );
$this->assertTrue( have_posts() );
$this->assertNull( the_post() );
foreach ( array( true, false ) as $strip_teaser ) {
$actual = get_echo( 'the_content', array( null, $strip_teaser ) );
$this->assertContains( 'Teaser part', $actual );
$this->assertContains( 'Read More</a>', $actual );
$this->assertNotContains( '<!--more-->', $actual );
$this->assertNotContains( 'wp:more', $actual );
$this->assertNotContains( 'wp:paragraph', $actual );
}
}
/**
* Ensure the_content displays the teaser part with a read more link for a More block
* when using the noteaser text tag on a non-singular page.
*
* @ticket 46471
*
* @group blocks
*/
public function test_the_content_should_handle_more_block_when_noteaser_on_non_singular() {
$post_content = <<<EOF
<!-- wp:paragraph -->
<p>Teaser part.</p>
<!-- /wp:paragraph -->
<!-- wp:more -->
<!--more-->
<!--noteaser-->
<!-- /wp:more -->
<!-- wp:paragraph -->
<p>Second block.</p>
<!-- /wp:paragraph -->
EOF;
$post_id = self::factory()->post->create( compact( 'post_content' ) );
$this->go_to( home_url() );
$this->assertFalse( is_singular() );
$this->assertTrue( have_posts() );
$this->assertNull( the_post() );
foreach ( array( true, false ) as $strip_teaser ) {
$actual = get_echo( 'the_content', array( null, $strip_teaser ) );
$this->assertContains( 'Teaser part', $actual );
$this->assertContains( '(more&hellip;)</span></a>', $actual );
$this->assertNotContains( '<!--more-->', $actual );
$this->assertNotContains( '<!--noteaser-->', $actual ); // We placed the noteaser tag below the more tag.
$this->assertNotContains( 'wp:more', $actual );
$this->assertNotContains( 'wp:paragraph', $actual );
}
}
}