1

I am building a template for archive page of custom post type's taxonomy.

Basically I have to show according to month like

August 2015
July 2015

To display above, I have used filter below:

add_filter( 'getarchives_where','abc_where',10,2);

add_filter('getarchives_join', 'custom_archives_join', 10, 2);

function custom_archives_join($x, $r) {
  global $wpdb;
  $cat_ID = $r['cat'];
  if (isset($cat_ID)) {
    return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
  } else {
    return $x;
  }
}

And while clicking on August 2015, it should display all post in particular CPT's taxonomy. But currently I am getting all posts.

Can anyone suggest me with this archive page for taxonomy of custom post type?

  • You will need to pass some kind of parameter to the archive page (probably in the URL) and then use that parameter in pre_get_posts to filter the posts. – Pieter Goosen Jul 21 '15 at 10:36
  • Can you please so me in example @PieterGoosen? – Blue Rose Jul 22 '15 at 3:11
  • Just one question, from your code it seems like you are using the build in taxonomy category and therefor using default categories – Pieter Goosen Jul 22 '15 at 5:34
  • As I clearly mentioned above its custom taxonomy and custom post type. Any help would be appreciated. thanks – Blue Rose Jul 22 '15 at 7:50
1

Before I start, you have a bug in your code which you should have picked up if you had debug turned on. You are first assigning $r['cat'] to a variable before even checking if $r['cat'] is set. Because cat is not a default, it may not be set, which will cause a PHP error when cat is not set. You can refactor your code to something like this: (Requires PHP5.3+. I also assumed that this worked as intended, so I have not changed anything)

add_filter('getarchives_join', function ( $x, $r ) 
{
  global $wpdb;

  // Set $cat_ID to the value of $r['cat'] if it is set, otherwise set to false
  $cat_ID = isset( $r['cat'] ) ? $r['cat'] : false;

  // If $cat_ID is false, return $x as is
  if ( !$cat_ID )
    return $x;

  // We have a value in $cat_ID, lets modify and return the required sql string
  return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";

}, 10, 2 );

Now that we got that out of the way, lets look at the real issue here. In order to get the correct posts on the archive page when an archive is selected, we need to

  • know where the request came from

  • filter the main query according to where the post came from to display the correct posts.

To tackle bullet point 1, we need some kind of referrer in order for us to know where the archive page request came from. This referrer will be our key which will enable us to display the correct posts according to term.

HTTP referrers is extremely unreliable as there are many client side factors that can alter or control the value of a referrer. The following section is a section I took from one of my previous answers as additional info to referrers, so you can take your time and read through the following

The problem with referrers is, they are set and controlled by user side. Referrers can be disabled or blocked (like users accessing a site behind a proxy). Just for interest sake, here is very interesting answer to the question In what cases will http referrer be empty taken from this post on SO

It will/may be empty when the enduser

  • entered the site URL in browser address bar itself.
  • visited the site by a browser-maintained bookmark.
  • visited the site as first page in the window/tab.
  • switched from a https URL to a http URL.
  • switched from a https URL to a different https URL.
  • has security software installed (antivirus/firewall/etc) which strips the referrer from all requests.
  • is behind a proxy which strips the referrer from all requests.
  • visited the site programmatically (like, curl) without setting the referrer header (searchbots!).

You would want to read the other answers there as well for extra insight

I sat with similar issue and was looking for a more reliable way to set and pass referrers, and this led to [this question]( Get default permalink structure from pretty URL's) and a wonderful answer by @gmazzap

As I hinted in comments, we will pass a value in the URL that we will use as a referrer to show the correct posts according to term in the archive page. To accomplish this, we need to filter the get_archives_link() function to add our referrer to the archive URL and also add our referrer to the list of query_vars so that we can read and use it.

First, add the query_vars, lets call it ref, which is short for referrer. ref will hold a custom value which will be equivelent to the term ID

add_filter( 'query_vars', function ( $vars )
{
    $vars[] = 'ref';

    return $vars;
});

Now the ref is readable, lets add it to our archive link in the get_archives_link() function through the get_archives_link filter: (This requires PHP 5.4+ due to short array syntax ([]))

add_filter( 'get_archives_link', function ( $link_html ) {

    if( is_tax() ) { // Adjust this to target specific taxonomies or taxonomy terms if needed

        preg_match ( "/href='(.+?)'/", $link_html, $url );

        $old_url = $url[1];
        $new_url = add_query_arg( ['ref' => get_queried_object_id()], $old_url );
        $link_html = str_replace( $old_url, $new_url, $link_html );

    }

    return $link_html;

});

You will now see that if you click on an archive link from a taxonomy page, you will see something the following being added to the URL, this will now be our referrer

 ?ref=1

where one is the ID of our term

The last part (2nd bullet point) is to filter our query accordingly. Here we need to

  • check if ref is set

  • if ref is set, get its value (Don't forget to sanitize to avoid data injection)

  • filter the main query accordingly

The final part of the code looks like this: (Requires at least PHP 5.4+ due to short array syntax)

add_action( 'pre_get_posts', function ( $q )
{
    // VERY VERY IMPORTANT: Check if `ref` is set as $_GET variable, get the value and validate as an integer
    $referrer = filter_var( INPUT_GET, 'ref', FILTER_VALIDATE_INT );

    if (    !is_admin() // Only target front end queries
         && $q->is_main_query() // Only target the main query
         && $q->is_date() // Only targets date archive pages, adjust as needed
         && $referrer // Only proceed if $referrer has a value
    ) {
        // To avoid bugs in a multi custom taxonomy install, check if the term is valid
        if ( term_exists( $referrer, 'CUSTOM_TAXONOMY_NAME' ) ) { // IMPORTANT: Use the correct taxonomy name here
            // Set our taxonomy term filter, again, set the correct taxonomy name
            $tax_query = [
                [
                    'taxonomy' => 'CUSTOM_TAXONOMY_NAME',
                    'terms' => $referrer,
                    'include_children' => false,
                ]
            ];
            $q->set( 'tax_query', $tax_query );
            $q->set( 'post_type', ['post', 'YOUR_CUSTOM_POST_TYPE'] ); // Adds custom post type to date archives
        }
    }
}, PHP_MAX_INT );

TAKE NOTE:

Most of the code above is untested, so it might be buggy. Also, most of the code requires PHP5.4+, this should be the minimum PHP version you have installed as all older versions have been EOL'ed and is therefor no longer supported. Although they still work, they do not get security updates, and this can cause serious harm to your site's overall security

  • wht about archive page? – Blue Rose Jul 22 '15 at 9:24
  • What about it? I have used is_date() to target date archives, this is how I have read and understood the question. – Pieter Goosen Jul 22 '15 at 9:42
  • See my update, I have included custom post types in date archive pages. Just change the post type name accordingly. Also, if you reply, please be very specific with your issues, wht about archive page, yes, what about it. I cannot know what you mean by that withoutnproper details – Pieter Goosen Jul 22 '15 at 10:11
  • Pieter Goosen why you have downvoted and edited my question.Plz don't do that :( – Blue Rose Jul 23 '15 at 2:27
  • Thanks for your answers. I got busy time and again so I wouldn't reply any soooner. It doesn't mean any ignorant. – Blue Rose Jul 25 '15 at 3:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.