WordPress.org

Ready to get started?Download WordPress

Forums

Excluding categories from wp_get_archives (3 posts)

  1. oxfordian3
    Member
    Posted 2 years ago #

    I have been researching this for a while. I am trying to make most of my WP theme ignore posts of two categories (C1, C2). Using several techniques I am able to do this for most content.

    But I still have a problem with getting the standard Archives widget to omit the Posts with the excluded categories, as returned by wp_get_archives. The best technique seemed to be the customized functions.php technique described at:

    http://wordpress.org/support/topic/wp_get_archives-and-conditional-tags?replies=18

    which sets up:

    add_filter( 'getarchives_where', 'customarchives_where' );
    add_filter( 'getarchives_join', 'customarchives_join' );

    This actually does work at eliminating the Posts with the excluded categories.

    But there is a problem with this code -- the additional JOINS cause the resulting query to return one record PER CATEGORY when there are posts under multiple categories. That causes the Post-Count numbers to be incorrect in the widget display, showing numbers that are too big (the # post-categories, not the # posts).

    Anyone have an idea how this SQL can be adjusted to return the right # records -- 1 per post -- even when posts have multiple categories?

  2. oxfordian3
    Member
    Posted 2 years ago #

    I have built my own variation on the wp_get_archives customization in

    http://wordpress.org/support/topic/wp_get_archives-and-conditional-tags?replies=18

    This seems to get the job done, and gives back the correct # records (one per post) even if posts are assigned multiple categories:

    In this version, only the "getarchives_where" filter is defined (not the "getarchives_join").

    add_filter( 'getarchives_where', 'customarchives_where' );
    
    function customarchives_where( $x ) {
    
    	global $wpdb;
    
    	$s = $x;
    
    	$s =  $s . " AND $wpdb->posts.ID IN ";
    
    	$s = $s . "(";
    	$s = $s . "SELECT $wpdb->posts.ID FROM $wpdb->posts 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) WHERE $wpdb->term_taxonomy.taxonomy = 'category'";
    
    	$exclude = '1'; // category id or list of id's to exclude
    
    	$s = $s . " AND $wpdb->term_taxonomy.term_id NOT IN ($exclude)";
    	$s = $s . ")";
    
    	return $s;
    
    }

    It basically uses the same SQL logic, but constructs a different SQL that selects only from the posts table, and uses a subselect to do all the filtering. This ensures that it returns just one record per post.

  3. bgsteve
    Member
    Posted 2 years ago #

    Thanks oxfordian3. I appreciate you coming back on here to post the solution.

Topic Closed

This topic has been closed to new replies.

About this Topic