Skip to content
Merged
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
62 changes: 46 additions & 16 deletions includes/class-post-date.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public static function init() {
add_filter( 'newspack_blocks_formatted_displayed_post_date', [ __CLASS__, 'filter_blocks_formatted_date' ], 10, 2 );
add_action( 'wp_enqueue_scripts', [ __CLASS__, 'enqueue_scripts' ] );
add_action( 'enqueue_block_editor_assets', [ __CLASS__, 'enqueue_editor_assets' ] );
add_action( 'newspack_theme_after_posted_on', [ __CLASS__, 'render_updated_date_classic' ] );
add_action( 'newspack_theme_posted_on', [ __CLASS__, 'render_updated_date_classic' ] );
add_filter( 'body_class', [ __CLASS__, 'add_body_show_updated' ] );
add_filter( 'newspack_theme_include_hidden_updated_time', [ __CLASS__, 'suppress_theme_hidden_updated_time' ] );
}

/**
Expand Down Expand Up @@ -257,6 +259,12 @@ public static function filter_get_the_date( $the_date, $format, $post ) {
return $the_date;
}

// Only convert dates in the loop to avoid affecting archive titles
// (e.g. "Daily Archives: 2 days ago") and other contexts.
if ( ! in_the_loop() ) {
return $the_date;
}

$time_ago = self::convert_to_time_ago( $post->post_date_gmt, self::get_time_ago_cutoff_days() );

return null !== $time_ago ? $time_ago : $the_date;
Expand All @@ -281,7 +289,7 @@ public static function filter_blocks_formatted_date( $date, $post ) {

/**
* Render updated date for classic (non-block) themes.
* Hooked to `newspack_theme_after_posted_on` which fires after `newspack_posted_on()`.
* Hooked to `newspack_theme_posted_on` which fires inside `newspack_posted_on()`.
*/
public static function render_updated_date_classic() {
if ( wp_is_block_theme() || ! is_singular() ) {
Expand All @@ -306,16 +314,46 @@ public static function render_updated_date_classic() {
}
}

/* translators: %s: Modified date. */
$label = sprintf( esc_html__( 'Updated %s', 'newspack-plugin' ), $modified_date );

printf(
'<span class="posted-on updated-date" data-newspack-modified><time class="entry-date updated" datetime="%1$s">%2$s</time></span>',
'<span class="updated-label">%1$s </span><time class="updated" datetime="%2$s">%3$s</time>',
esc_html__( 'Updated', 'newspack-plugin' ),
esc_attr( get_the_modified_date( DATE_W3C, $post ) ),
wp_kses_post( $label )
esc_html( $modified_date )
);
}

/**
* Add 'show-updated' body class when the updated date should display on classic themes.
*
* @param string[] $classes Body CSS classes.
* @return string[]
*/
public static function add_body_show_updated( $classes ) {
if ( wp_is_block_theme() || ! is_singular() ) {
return $classes;
}
if ( self::should_display_updated_date() ) {
$classes[] = 'show-updated';
}
return $classes;
}

/**
* Suppress the theme's hidden <time class="updated"> when the plugin handles it.
*
* @param bool $include Whether to include the hidden updated time.
* @return bool
*/
public static function suppress_theme_hidden_updated_time( $include ) {
if ( wp_is_block_theme() || ! is_singular() ) {
return $include;
}
if ( self::should_display_updated_date() ) {
return false;
}
return $include;
}

/**
* Register per-post meta for updated date toggles.
*/
Expand Down Expand Up @@ -382,17 +420,9 @@ public static function migrate_date_settings( $old_name, $old_theme ) {
}

/**
* Enqueue relative-time script and updated date styles on frontend.
* Enqueue relative-time script on frontend.
*/
public static function enqueue_scripts() {
// Inline styles for the classic theme updated date.
// Always enqueue on classic themes since per-post overrides can show the date even when sitewide is off.
if ( ! wp_is_block_theme() ) {
wp_register_style( 'newspack-post-date', false, [], NEWSPACK_PLUGIN_VERSION );
wp_enqueue_style( 'newspack-post-date' );
wp_add_inline_style( 'newspack-post-date', '.entry-meta .updated-date { margin-inline-start: 1em; }' );
}

if ( ! get_theme_mod( 'post_time_ago', false ) ) {
return;
}
Expand Down
6 changes: 4 additions & 2 deletions src/other-scripts/relative-time/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
return; // No Intl support.
}

const elements = document.querySelectorAll( '.wp-block-post-date time[datetime], time.entry-date[datetime], .comment-meta time[datetime]' );
const elements = document.querySelectorAll(
'.wp-block-post-date time[datetime], time.entry-date[datetime], time.updated[datetime], .comment-meta time[datetime]'
);
const now = Date.now();

elements.forEach( function ( el ) {
Expand All @@ -72,7 +74,7 @@
el.setAttribute( 'title', new Date( datetime ).toLocaleString( localeTag ) );
}

// Only replace text on publish dates, not modified date blocks.
// Skip block-theme modified dates (label is inside <time>). Classic-theme ones are fine.
if ( el.closest( '[data-newspack-modified]' ) || el.closest( '.wp-block-post-date__modified-date' ) ) {
return;
}
Expand Down
28 changes: 27 additions & 1 deletion tests/unit-tests/class-post-date-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,34 @@ public function test_get_the_date_filter_enabled() {
]
);

// Simulate being in the loop so the filter applies.
$original_in_the_loop = $GLOBALS['wp_query']->in_the_loop ?? null;

try {
$GLOBALS['wp_query']->in_the_loop = true;

$date = get_the_date( '', $post_id );
$this->assertStringContainsString( 'ago', $date, 'get_the_date should return relative date when feature is on.' );
} finally {
$GLOBALS['wp_query']->in_the_loop = $original_in_the_loop;
}
}

/**
* Test get_the_date filter skips conversion outside the loop (e.g. archive titles).
*/
public function test_get_the_date_filter_skips_outside_loop() {
set_theme_mod( 'post_time_ago', true );
set_theme_mod( 'post_time_ago_cut_off', 14 );

$post_id = static::factory()->post->create(
[
'post_date' => gmdate( 'Y-m-d H:i:s', time() - 2 * HOUR_IN_SECONDS ),
]
);

$date = get_the_date( '', $post_id );
$this->assertStringContainsString( 'ago', $date, 'get_the_date should return relative date when feature is on.' );
$this->assertStringNotContainsString( 'ago', $date, 'get_the_date should not convert to time-ago outside the loop.' );
}

/**
Expand Down
Loading