Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/wp-content/themes/twentytwentyone/inc/template-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,39 @@ function twenty_twenty_one_continue_reading_link_excerpt() {
// Filter the excerpt more link.
add_filter( 'excerpt_more', 'twenty_twenty_one_continue_reading_link_excerpt' );

/**
* Checks whether the current post sets its own text for the more link.
*
* @return bool True if the post content has a `<!--more Custom text-->` tag.
*/
function twenty_twenty_one_has_custom_more_text() {
return 1 === preg_match( '/<!--more(.+?)-->/', (string) get_post_field( 'post_content', get_the_ID() ), $matches ) && '' !== trim( $matches[1] );
}

/**
* Creates the continue reading link.
*
* @since Twenty Twenty-One 1.0
*
* @param string $more_link_element Read More link element.
* @param string $more_link_text Read More text.
* @return string|void The link markup, or nothing in the admin.
*/
function twenty_twenty_one_continue_reading_link() {
if ( ! is_admin() ) {
return '<div class="more-link-container"><a class="more-link" href="' . esc_url( get_permalink() ) . '#more-' . esc_attr( get_the_ID() ) . '">' . twenty_twenty_one_continue_reading_text() . '</a></div>';
function twenty_twenty_one_continue_reading_link( $more_link_element = '', $more_link_text = '' ) {
if ( is_admin() ) {
return;
}

$link_text = twenty_twenty_one_continue_reading_text();
if ( twenty_twenty_one_has_custom_more_text() ) {
$link_text = esc_html( $more_link_text ) . the_title( ' <span class="screen-reader-text">', '</span>', false );
}

return '<div class="more-link-container"><a class="more-link" href="' . esc_url( get_permalink() ) . '#more-' . esc_attr( get_the_ID() ) . '">' . $link_text . '</a></div>';
}

// Filter the content more link.
add_filter( 'the_content_more_link', 'twenty_twenty_one_continue_reading_link' );
add_filter( 'the_content_more_link', 'twenty_twenty_one_continue_reading_link', 10, 2 );

if ( ! function_exists( 'twenty_twenty_one_post_title' ) ) {
/**
Expand Down
110 changes: 110 additions & 0 deletions tests/phpunit/tests/theme/twentyTwentyOneContinueReadingLink.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

/**
* @group themes
*
* @covers ::twenty_twenty_one_continue_reading_link
*/
class Tests_Theme_TwentyTwentyOneContinueReadingLink extends WP_UnitTestCase {

/**
* The names of the globals these tests overwrite.
*
* @var string[]
*/
private array $global_names = array( 'post', 'more' );

/**
* The values of those globals before the current test ran, keyed by name.
*
* A name is absent when the global was not set.
*
* @var array<string, mixed>
*/
private array $original_globals = array();

public function set_up() {
parent::set_up();

// `backupGlobals` is disabled for the suite, so these have to be restored by hand.
foreach ( $this->global_names as $global_name ) {
if ( array_key_exists( $global_name, $GLOBALS ) ) {
$this->original_globals[ $global_name ] = $GLOBALS[ $global_name ];
}
}

$template_functions = WP_CONTENT_DIR . '/themes/twentytwentyone/inc/template-functions.php';
if ( ! file_exists( $template_functions ) ) {
$this->markTestSkipped( 'The Twenty Twenty-One theme is not installed.' );
}
require_once $template_functions;
}

public function tear_down() {
foreach ( $this->global_names as $global_name ) {
if ( array_key_exists( $global_name, $this->original_globals ) ) {
$GLOBALS[ $global_name ] = $this->original_globals[ $global_name ];
} else {
unset( $GLOBALS[ $global_name ] );
}
}

parent::tear_down();
}

private function set_up_post( string $content ): void {
$post_id = self::factory()->post->create( array( 'post_content' => $content ) );

$GLOBALS['post'] = get_post( $post_id );
setup_postdata( $GLOBALS['post'] );
}

/**
* @ticket 52683
*/
public function test_uses_custom_more_text_when_set() {
$this->set_up_post( 'Teaser<!--more Read the full story-->Rest' );

$link = twenty_twenty_one_continue_reading_link( '', 'Read the full story' );

$this->assertStringContainsString( '>Read the full story <span class="screen-reader-text">', $link );
$this->assertStringNotContainsString( 'Continue reading', $link );
}

/**
* @ticket 52683
*/
public function test_uses_theme_text_without_custom_more_text() {
$this->set_up_post( 'Teaser<!--more-->Rest' );

$link = twenty_twenty_one_continue_reading_link( '', twenty_twenty_one_continue_reading_text() );

$this->assertStringContainsString( 'Continue reading', $link );
$this->assertStringContainsString( 'class="more-link"', $link );
}

/**
* @ticket 52683
*/
public function test_escapes_custom_more_text() {
$this->set_up_post( 'Teaser<!--more Tom & Jerry-->Rest' );

$link = twenty_twenty_one_continue_reading_link( '', 'Tom & Jerry' );

$this->assertStringContainsString( 'Tom &amp; Jerry', $link );
}

/**
* @ticket 52683
*/
public function test_the_content_shows_custom_more_text() {
add_filter( 'the_content_more_link', 'twenty_twenty_one_continue_reading_link', 10, 2 );
$GLOBALS['more'] = 0;
$this->set_up_post( 'Teaser<!--more Read the full story-->Rest' );

$content = get_the_content( twenty_twenty_one_continue_reading_text() );

$this->assertStringContainsString( 'Read the full story', $content );
$this->assertStringContainsString( 'more-link-container', $content );
}
}
Loading