How To Customize The Post Date In GeneratePress

I have a number of posts that get thousands of readers a month and dozens of comments.

As more comments come in, I often update the content, or clarify things. Particularly if the theme or plugin they relate to changes.

The way that GeneratePress is typically setup, it only displays the published date, which is fine for news sites or static content, but it doesn't make sense for content that's regularly updated.

I made a bunch of changes to my Astra post meta customizer tutorial a few days ago, making sure it worked with the current theme version. But if you looked at the date and saw 14 October 2018, you'd think it was three and a half years old and probably out of date!

showing original published date

If you look in the code, GeneratePress has the published date on all pages. It also has the updated date, if it's been updated more than 30 minutes after publishing. You don't see the updated date, because it's hidden with CSS.

This was the code for the screenshot above:

code showing both update and published date

If you want to show the updated date if it exists, otherwise the publish date, the super simple way to do that is:

add_filter( 'generate_post_date_show_updated_only', '__return_true' );

Just add the code to the functions.php file of your child theme.

That will change the date to this:

Showing just the updated date

That doesn't work for my site either, because it looks like I've only just published it. That'd be a bit weird with the 30+ comments on it dating back to 2019!

That code works by showing only the updated date if it exists, otherwise showing the published date.

The good thing about doing it that way is you don't have to mess with the CSS code to display the updated date.

How to add text before the meta date in GeneratePress

To add text just before the meta date, connect a function to the filter generate_inside_post_meta_item_output. If the meta item is "date", return your text.

The code to do that is:

add_filter ( 'generate_inside_post_meta_item_output', 'custom_date_text', 10, 2 );

function custom_date_text( $nothing, $type ) {
  if ( 'date' !== $type ) {
    return null;
  }

  return "Text before date: ";
}

This will insert "Text before date: " (or whatever you put there) after <span class="posted-on"> and before <time>.

This will insert the same text, whether the date displayed is the published date or the updated date.

How to display different text for published and updated dates

If you want to display different text for the published date and updated date, use this code:

add_filter ( 'generate_inside_post_meta_item_output', 'custom_date_text', 10, 2 );

function custom_date_text( $nothing, $type ) {
  if ( 'date' !== $type ) {
    return null;
  }
  
  $updated_time = get_the_modified_time( 'U' );
  $published_time = get_the_time( 'U' ) + 1800;

  if ( $updated_time > $published_time ) {
    return "Last Updated: ";
  }

  return "Published: ";
}

The code that gets and compares the $updated_time and $published_time is the same as GeneratePress uses for its comparison.

If you don't want anything to display before one of them, return null rather than false, because the function return is echoed and you'll get some weirdness.

Use this code in conjunction with add_filter( 'generate_post_date_show_updated_only', '__return_true' ); to display the updated date correctly.

The end result is that my posts now display "Last Updated" and the updated date where it exists.

Showing the updated date with last updated text

The published date now doesn't render in the code either.

code showing updated date with published date not rendered

But let's say you wanted the published date to render as well.

Let's say you wanted to add text before both the published date and the updated date.

Unfortunately there's no easy way to do that in GeneratePress. You have to overwrite one of their functions. This should only be done if you keep an eye on things, because it has a much greater potential to break on a later update.

How to display published and updated date in GeneratePress with custom text

Overwrite the generate_posted_on() function with your own that sends the processing of the "date" item to your custom function. That custom function will be a replica of generate_do_post_meta_item($item) with your own custom text.

Both functions are in generatepress/inc/structure/post-meta.php. You'll find them around lines 413 and 162 respectively.

I wanted to show "Published: 5 July 2020" where there was no updated date and "Published: 5 July 2020, Updated: 10 April 2022" where there was an updated date.

The code to do all that is:

function generate_posted_on() {
  $items = generate_get_header_entry_meta_items();

  foreach ( $items as $item ) {
    if ( 'date' == $item ) {
      custom_generate_do_post_meta_item( $item );
    }
    else {
      generate_do_post_meta_item( $item );
    }
  }
}

function custom_generate_do_post_meta_item( $item ) {
  if ( 'date' !== $item ) {
    return false;
  }

  $time_string = '<time class="entry-date published" datetime="%1$s"%5$s>%2$s</time>';

  $updated_time = get_the_modified_time( 'U' );
  $published_time = get_the_time( 'U' ) + 1800;
  $schema_type = generate_get_schema_type();

  if ( $updated_time > $published_time ) {
    if ( apply_filters( 'generate_post_date_show_updated_only', false ) ) {
      $time_string = '<time class="entry-date updated-date" datetime="%3$s"%6$s>%4$s</time>';
    } else {
      $time_string = '<strong>Published</strong>: ' . $time_string . ', <strong>Updated</strong>: <time class="updated" datetime="%3$s"%6$s>%4$s</time>';
    }
  } else {
    $time_string = '<strong>Published</strong>: <time class="entry-date published" datetime="%1$s"%5$s>%2$s</time>';
  }

  $time_string = sprintf(
    $time_string,
    esc_attr( get_the_date( 'c' ) ),
    esc_html( get_the_date() ),
    esc_attr( get_the_modified_date( 'c' ) ),
    esc_html( get_the_modified_date() ),
    'microdata' === $schema_type ? ' itemprop="datePublished"' : '',
    'microdata' === $schema_type ? ' itemprop="dateModified"' : ''
  );

  $posted_on = '<span class="posted-on">%1$s%4$s</span> ';

  if ( apply_filters( 'generate_post_date_link', false ) ) {
    $posted_on = '<span class="posted-on">%1$s<a href="%2$s" title="%3$s" rel="bookmark">%4$s</a></span> ';
  }

  echo apply_filters(
    'generate_post_date_output',
    sprintf(
      $posted_on,
      apply_filters( 'generate_inside_post_meta_item_output', '', 'date' ),
      esc_url( get_permalink() ),
      esc_attr( get_the_time() ),
      $time_string
    ),
    $time_string,
    $posted_on
  );

}

I know that can seem somewhat daunting, but most of it is a copy of the GeneratePress functions I mentioned above.

There are a few lines of code you can remove if you don't intend ever using the feature, such as:

if ( apply_filters( 'generate_post_date_show_updated_only', false ) ) {
  $time_string = '<time class="entry-date updated-date" datetime="%3$s"%6$s>%4$s</time>';
}

Because if you ever did use that conditional, you'd be better off using the method I discussed earlier in this tutorial.

The original generate_posted_on() function doesn't have the if/else code in the foreach. We need it so that we can send the date items to our custom function and process everything else in the standard GeneratePress code.

Usually you can't just overwrite a function from the parent theme in the child theme, but this particular function is wrapped in if ( ! function_exists( 'generate_posted_on' ) ) {}, which allows us to overwrite it in our child theme.

The only other change to the code is in:

if ( $updated_time > $published_time ) {
  if ( apply_filters( 'generate_post_date_show_updated_only', false ) ) {
    $time_string = '<time class="entry-date updated-date" datetime="%3$s"%6$s>%4$s</time>';
  } else {
    $time_string = '<strong>Published</strong>: ' . $time_string . ', <strong>Updated</strong>: <time class="updated" datetime="%3$s"%6$s>%4$s</time>';
  }
} else {
  $time_string = '<strong>Published</strong>: ' . $time_string;
}

Originally it was:

if ( $updated_time > $published_time ) {
  if ( apply_filters( 'generate_post_date_show_updated_only', false ) ) {
    $time_string = '<time class="entry-date updated-date" datetime="%3$s"%6$s>%4$s</time>';
  } else {
    $time_string = '<time class="updated" datetime="%3$s"%6$s>%4$s</time>' . $time_string;
  }
}

I rewrote the $time_string for updated to swap the order and add the Published and Updated text, wrapped in <strong> tags.

Because I wanted Published: before the date where there was no updated date, I had to add the extra else at the end of if ( $updated_time > $published_time ){}.

If you add "<strong>Published</strong>: " at the initial $time_string, before the updated/published comparison, it will display Published: twice on pages that have been updated.

I hope that all makes sense. Please let me know in the comments if you'd like clarification on any of these steps.

Mike Haydon

Thanks for checking out my WordPress and coding tutorials. If you've found these tutorials useful, why not consider supporting my work?

Buy me a coffee

Leave a Comment