Archives for Custom Post Types (without Pages)

I’m basically looking to extend the default archives widget so that it not only displays a {month : year} list of the default Posts but also includes my new custom Post Type.

From this example I was able get the new {month : year} items appearing in the archive list but not clicking through to anything.

Read More

Then this example showed how to include items from Custom Post Types in the loop and allow them to click through and return the actual results.

However, the last problem I have is that when clicking on the {month : year} item in the list it also returns results from Page entries too. I need to know how to filter out Pages from my results so it is just Post Types.

The code I have in functions.php is:

/**
 * Add custom Post Types to the Archives.
 */
add_filter( 'getarchives_where' , 'ucc_getarchives_where_filter' , 10 , 2 );
function ucc_getarchives_where_filter( $where , $r ) {
  $args = array(
    'public' => true ,
    '_builtin' => false
  );
  $output = 'names';
  $operator = 'and';

  $post_types = get_post_types( $args , $output , $operator );
  $post_types = array_merge( $post_types , array( 'post' ) );
  $post_types = "'" . implode( "' , '" , $post_types ) . "'";

  return str_replace( "post_type = 'post'" , "post_type IN ( $post_types )" , $where );
}

/**
 * Add Custom Post Types to The Loop results.
 */
add_filter( 'request' , 'ucc_request_filter' );
function ucc_request_filter( $query ) {
   // Preview does not like having post_type set; feed is my personal preference.
  if ( empty( $query['preview'] ) && empty( $query['feed'] ) ) {
    $my_post_type = $query['post_type'];
    if ( empty( $my_post_type ) ) {
      $query['post_type'] = 'any';
    }
  }
  return $query;
}

Related posts

Leave a Reply

1 comment

  1. replace:

    return str_replace( "post_type = 'post'" , "post_type IN ( $post_types )" , $where );
    

    with:

    return str_replace( "post_type = 'post'" , "post_type = 'YOUR_CUSTOM_TYPE'" , $where );
    

    and change YOUR_CUSTOM_TYPE to your actual custom post type name.

    Update:

    If you want all types but pages then change your function abit to this:

    add_filter( 'getarchives_where' , 'ucc_getarchives_where_filter' , 10 , 2 );
    function ucc_getarchives_where_filter( $where , $r ) {
      $args = array(
        'public' => true ,
        '_builtin' => false
      );
      $output = 'names';
      $operator = 'and';
    
      $post_types = get_post_types( $args , $output , $operator );
      $post_types = array_merge( $post_types , array( 'post' ) );
      $post_types = "'" . implode( "' , '" , $post_types ) . "'";
      //if page is somewhere in the middle then remove it 
      $post_types = str_replace("'page',","",  $post_types);
        //if page is somewhere the last type then remove it 
      $post_types = str_replace("'page'","",  $post_types);
      return str_replace( "post_type = 'post'" , "post_type IN ( $post_types )" , $where );
    }
    

    and to get results in the loop use this:

    add_filter( 'pre_get_posts' , 'ucc_include_custom_post_types' );
    function ucc_include_custom_post_types( $query ) {
      global $wp_query;
    
      /* Don't break admin or preview pages. This is also a good place to exclude feed with !is_feed() if desired. */
      if ( !is_preview() && !is_admin() && !is_singular() ) {
        $args = array(
          'public' => true ,
          '_builtin' => false
        );
        $output = 'names';
        $operator = 'and';
    
        $post_types = get_post_types( $args , $output , $operator );
        $post_types = array_merge( $post_types , array( 'post' ) );
    
        //remove page form array:
        foreach($post_types as $key => $val){
            if ($val =='page'){
                unset($post_types[$key]);
            }
        }
    
        if ($query->is_feed) {
          /* Do feed processing here if you did not exclude it previously. This if/else
           * is not necessary if you want custom post types included in your feed.
           */
        } else {
          $my_post_type = get_query_var( 'post_type' );
          if ( empty( $my_post_type ) )
            $query->set( 'post_type' , $post_types );
        }
      }
    
      return $query;
    }