Support » Developing with WordPress » Year archive for custom post type

  • Resolved matthewmcvickar

    (@matthewmcvickar)


    I have a custom post type called press-release. I have an archive page for it at archive-press-release.php, and its URL is /press-releases/:

    register_post_type( 'press-release', array(
      // ...
      'has_archive' => 'press-releases',
      'rewrite' => array(
        'slug'       => 'press-releases',
        'with_front' => false
      )
      // ...
    )

    On the press releases archive page, there are links to filter the list by year, e.g., /press-releases/2019/, /press-releases/2020/. To support this, I added a rewrite rule like so:

    // Create a URL for filtering press releases by year.
    function press_releases_rewrite_rules() {
      add_rewrite_rule(
        'press-releases/([0-9]{4})/?$',
        array(
          'year'      => '$matches[1]',
          'post_type' => 'press-release',
        ),
        'top'
      );
    }
    add_action( 'init', 'press_releases_rewrite_rules', 11, 0 );

    I then flushed rewrite rules and tried my URLs, but it just goes to index.php. I tried creating date-press-release.php, then tried date.php, then tried archive.php, but the URL never lands on any of those templates either; it just falls back to index.php, (and with Query Monitor I can see that it ends up there without any query variables at all).

    What is the proper way to support this? I’ve had to resort to setting a different query variable for the year and then filtering pre_get_posts, but that feels like recreating built-in functionality.

Viewing 3 replies - 1 through 3 (of 3 total)
  • It is and it isn’t quite that simple.
    The standard rewrite rules check for dates as just numbers with nothing else. You are bypassing these rules because of your registration, yet where does your rule get put in the sequence of the rewrite rules?
    There is a very old plugin called Custom Post Archives which does this for you, but it uses ‘date’ keyword for the date archives. You should read the code.
    Oh, I just found this one: https://wordpress.org/plugins/custom-post-type-date-archives/

    Moderator bcworkz

    (@bcworkz)

    Re-creating built-in functionality is what you need to do since it’s not working the way you want đŸ™‚ Fiddling with query vars so it’s not seen as a date archive but a post type archive that would use your specific template is one way. Another way is to override whatever WP decides to use through the “template_include” filter. The path returned is the template used, regardless of query var values. I’ve not looked at the plugins Joy mentions, but it’s a good bet that they also use this filter.

    Thread Starter matthewmcvickar

    (@matthewmcvickar)

    Thank you both for the insight!

    I ended up doing this:

    // Create a URL for filtering press releases by year.
    function press_releases_rewrite_rules() {
      add_rewrite_rule(
        'press-releases/([0-9]{4})/?$',
        array(
          'year_filter' => '$matches[1]',
          'post_type'   => PRESS_RELEASE_POST_TYPE,
        ),
        'top'
      );
    }
    add_action( 'init', 'press_releases_rewrite_rules', 11, 0 );
    
    // Register the 'year_filter' query variable so we can filter by it.
    function register_year_filter_query_var( $vars ) {
      $vars[] = 'year_filter';
      return $vars;
    }
    add_filter( 'query_vars', 'register_year_filter_query_var' );
    
    // Alter WP query to support year filter for press releases and media coverage.
    function add_year_filter_to_media_coverage_and_press_releases( $query ) {
      // Exit if this is the admin, not the main query, or not a press release query.
      if ( is_admin()
        || ! $query->is_main_query() 
        || empty( get_query_var( 'post_type' ) )
        || PRESS_RELEASE_POST_TYPE !== get_query_var( 'post_type' ) ) {
        return;
      }
    
      if ( ! empty( get_query_var( 'year_filter' ) ) ) {
        set_query_var( 'year', get_query_var( 'year_filter' ) );
      }
    }
    add_filter( 'pre_get_posts', 'add_year_filter_to_media_coverage_and_press_releases' );
Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Year archive for custom post type’ is closed to new replies.