Support » Fixing WordPress » Custom Taxonomy Template (Help Me Understand the Array)

  • Resolved Angie Meeker

    (@ameeker)


    I have a custom post type (totd) and a custom taxonomy (totd_cat) that has a custom rewrite (small-business-tips/category) with four terms (social, marketing, technology, operations). On the CPT template, the single CPT template, and the taxonomy templates, there is a menu to choose the terms of the taxonomy in order those posts. For the taxonomy template, I have taxonomy-totd_cat.php which has in it the code below, which current produces http://m.angiemeekerdesigns.com/small-business-tips/category/marketing/ (for example, that is one of the terms in the taxonomy). It is drawing from all of the posts in the post type, rather than just the term of the taxonomy chosen. I don’t understand how to get the template to show only the posts of the taxonomy term chosen. Also, I know the array is wrong, but I don’t know how to fix it. My custom post type template works perfectly using practically the same code, but without the is_tax array.

    /** Replace the standard loop with our custom loop */
    remove_action( 'genesis_loop', 'genesis_do_loop' );
    add_action( 'genesis_loop', 'totd_do_cat_loop');
    add_action( 'genesis_loop', 'totd_teasers_do_cat_loop');
    
    add_action('pre_get_posts', 'myprefix_query_offset', 1 );
    function myprefix_query_offset(&$query) {
    
        //First, define your desired offset...
        $offset = $query->get('offset');
    
        //Next, determine how many posts per page you want (we'll use WordPress's settings)
        $ppp = 10;
    
        //Next, detect and handle pagination...
        if ( $query->is_paged ) {
    
            //Manually determine page query offset (offset + current page (minus one) x posts per page)
            $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
    
            //Apply adjust page offset
            $query->set('offset', $page_offset );
    
        }
        else {
    
            //This is the first page. Just use the offset...
            $query->set('offset',$offset);
    
        }
    }
    
    add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
    function myprefix_adjust_offset_pagination($found_posts, $query) {
    
        //Define our offset again...
        $offset = $query->get('offset');
    
            //Reduce WordPress's found_posts count by the offset...
            return $found_posts - $offset;
        }
    
    add_action('genesis_loop', 'totd_do_cat_loop');
    function totd_do_cat_loop() {
    if ( !is_paged() ) {
    	global $wp_query;
    	// Set up your query here
    	$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    	$query = array(
    		'post_type' => 'tipoftheday',
    		'orderby'        => 'date',
    		'posts_per_page' => '1',
    		'tax_query' => array(
            array(
                'taxonomy' => 'totd_cat',
                'field' => 'slug',
                'terms' => array ('social', 'marketing', 'operations', 'technology')
            ))
    
    	);
    
    	$wp_query = new WP_Query( $query );
    
    	if( $wp_query->have_posts() ):
    		while( $wp_query->have_posts() ): $wp_query->the_post();
    			// Get the custom fields
    			        // Store the pre tips data
            $tips_data_pre = array(
                    'totd_tags' => get_field( 'totd_tags' ),
                    'tip_article_headline' => get_field( 'tip_article_headline' ),
                    'article_author' => get_field( 'article_author' ),
                    'article_author_link' => get_field( 'article_author_link' ),
            );
    
    // Only output if we have tips data
            if ($tips_data_pre['totd_tags'] != '' ||
                    $tips_data_pre['tip_article_headline'] != '' ||
                    $tips_data_pre['article_author'] != '' ||
                    $tips_data_pre['article_author_link'] != '') {
                   echo '<span class="date time published" title="%1$s">' , do_shortcode('[post_date]'),'</span>' ;
    
                    echo '<div class="tip-excerpt"><p><div class="entry-content">';
                   echo '<div class=h1 entry-title"><a href="'.get_permalink().'"title="'.get_the_title().'">' . get_the_title() . '</a></div>';
    						   echo the_excerpt();
                                    echo '<div class="entry-terms">' , do_shortcode('[post_terms taxonomy="totd_tags" before="See More Tips For: " taxonomy="totd_tags"] '),'</div>' ;
                                    echo '<div class="entry-terms">
                                                                                    <div class="share">Share This Tip:</div>
                                                                                            <div class="addthis_toolbox addthis_default_style">
                                                                                                    <a class="addthis_button_preferred_1"></a>
                                                                                                    <a class="addthis_button_preferred_2"></a>
                                                                                                    <a class="addthis_button_preferred_3"></a>
                                                                                                    <a class="addthis_button_preferred_4"></a>
                                                                                                    <a class="addthis_button_compact"></a>
                                                                                                    <a class="addthis_counter addthis_bubble_style"></a>
                                                                                            </div>
                                                                                            <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=manta"></script>
                                                                                    </div>
                                                                    </div></div>';
    
                    echo '</p>';
            }
    
    		endwhile;
    
    	endif;
    	// Reset the query
    	wp_reset_query();
    	}
    }
    
    add_action('genesis_loop', 'totd_teasers_do_cat_loop');
    function totd_teasers_do_cat_loop() {
    	global $wp_query;
    	// Set up your query here
    	$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 0;
    	$query = array(
    		'post_type' => 'tipoftheday',
    		'orderby'        => 'date',
    		'posts_per_page' => '10',
    		'offset'		=> '1',
    		'paged'  => $paged,
    	);
    
    	$wp_query = new WP_Query( $query );
    
    	if( $wp_query->have_posts() ):
    		while( $wp_query->have_posts() ): $wp_query->the_post();
    
    			// Get the custom fields
    			        // Store the pre tips data
            $tips_data_pre = array(
                    'totd_tags' => get_field( 'totd_tags' ),
                    'tip_article_headline' => get_field( 'tip_article_headline' ),
                    'article_author' => get_field( 'article_author' ),
                    'article_author_link' => get_field( 'article_author_link' ),
            );
    
    // Only output if we have tips data
            if ($tips_data_pre['totd_tags'] != '' ||
                    $tips_data_pre['tip_article_headline'] != '' ||
                    $tips_data_pre['article_author'] != '' ||
                    $tips_data_pre['article_author_link'] != '') {
    				echo '<div class="time-teaser">
    				<span class="day">',get_the_time( 'l' ),'</span>
    				<span class="month">',get_the_time( 'm/d/Y' ),'</span> </div>';
    
                    echo '<div class="tip-excerpt"><p><div class="entry-content">';
    echo '<div class=h2 entry-title"><a href="'.get_permalink().'"title="'.get_the_title().'">' . get_the_title() . '</a></div>';
                    $excerpt = get_the_excerpt();
      echo string_limit_words($excerpt,25); echo '<a class="moretag" href="'. get_permalink($post->ID) . '"> Continue Reading→</a>';
                                    echo '<div class="entry-terms">' , do_shortcode('[post_terms taxonomy="totd_tags" before="See More Tips For: " taxonomy="totd_tags"] '),'</div>' ;
                                    echo '<div class="entry-terms"></div>
                                                                    </div></div>';
    
                    echo '</p>';
            }
    
    		endwhile;
    		// Pagination! Woo!
    		genesis_posts_nav();
    	endif;
    	// Reset the query
    	wp_reset_query();
    }
    
    genesis();

    The part above that I think is most specific to what I’m looking at is

    if ( !is_paged() ) {
    	global $wp_query;
    	// Set up your query here
    	$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    	$query = array(
    		'post_type' => 'tipoftheday',
    		'orderby'        => 'date',
    		'posts_per_page' => '1',
    		'tax_query' => array(
            array(
                'taxonomy' => 'totd_cat',
                'field' => 'slug',
                'terms' => array ('social', 'marketing', 'operations', 'technology')
            ))
    
    	);
Viewing 15 replies - 1 through 15 (of 20 total)
  • Chip Bennett

    (@chipbennett)

    Theme Review Admin

    A couple questions:

    1. This is the taxonomy-totd_cat.php template file?
    2. If so, are your pre_get_posts and posts_found callbacks working? That would be extremely unusual, since by the time the template is loaded, those actions/filters are long-past

    Also, there is a lot of code here, most of which is probably not relevant to the question. Can you pare it down to the key sections of code, just for ease of clarity/legibility?

    Yes, that’s the taxonomy-totd_cat.php template.

    And yes, the pre_get_posts and posts_found work. For example, the terms – if I were to just leave one term in the array in the first loop, and then leave a different term in an is_tax array in the second loop, I could test that the template is still working as I need it to (or another example, take out the is_tax arrays all together and put in different post types for both loops).

    But, I can’t figure how to get the same template to show just the posts from the one term chosen.

    Chip Bennett

    (@chipbennett)

    Theme Review Admin

    Okay, let’s back up just a bit. I want to make sure I’m understanding what you’re wanting to do, and where it’s failing. Because that seems to be an awful lot of query manipulation for what’s actually getting rendered.

    It looks like you just want taxonomy-totd_cat.php to be used to display the taxonomy term archive index? If so, you shouldn’t need any of the query manipulation you’re doing.

    What happens if you just output a loop, with all of the various query manipulations removed?

    Christian Chung

    (@christian1012)

    'terms' => array ('social', 'marketing', 'operations', 'technology')

    This line is requesting all the posts tagged with any of the above. So they would all be in the WP_Query object. What Chip is saying is if you were to just use the main query object, you should have the corrects posts in the object, (ie, just the ones you want).

    Chip Bennett

    (@chipbennett)

    Theme Review Admin

    What @christian1012 said. That’s the TL;DR.

    I was going to get there, but I’m trying to do so in a way that helps you understand what’s happening with the query and template manipulations. 🙂

    I do, but the first post displays differently than the rest (not just styling, but different structure for the content) than the next 10 (hence the offset in pre_get_posts and found_posts – also to keep the pagination correct) and the two loops.

    If I go with a straight loop, won’t I lose all of that?

    Well, replacing it all with just straight loops seems to work, but I lose the # of posts and offsets for the first loop and second. If I can get that back (1 post for first loop, 10 for second with the second loop offset 1 post) while keeping the pagination (which at this point works), I guess I’m good to go.

    Sweet. Thanks guys. That did it. Added the posts per and the offset and I’m good to go.

    Ugh. Why did that seem so hard!

    Christian Chung

    (@christian1012)

    Why are you using two loops?

    Christian Chung

    (@christian1012)

    Good to hear it’s fixed. You can ignore my curiosity above if you like.

    No you can see –
    http://m.angiemeekerdesigns.com/small-business-tips/

    The first post has different structure than the following 10.

    Christian Chung

    (@christian1012)

    Just a suggestion:

    The way you have it coded above, you iterate over the object twice. Once for the first loop, and then again for the second. To cut down on resources, load times, and actual coding time, you may want to use a counter. Then you only have to iterate over the loop once.

    if ( have_posts() ) :
        // Set a counter
        $count = 0;
        while ( have_posts () ) : the_post();
            // Increment the counter
            $count++;
            // If not paged and it's the very first post
            if( !$paged && $count = 1 ) {
                // Do special stuff for first post.
            }
            else {
                // Do regular stuff for all other posts.
            }
        endwhile;
    endif;

    Chip Bennett

    (@chipbennett)

    Theme Review Admin

    So, the *right* way to do that in your template file would be:

    1) A *custom* loop for the first post
    2) Callbacks for pre_get_posts and found_posts, moved to functions.php

    By *custom* loop, I mean something like:

    $latest_totd = new WP_Query( /* args here */ );
    if ( $latest_totd->have_posts() ) : while ( $latest_totd->have_posts() ) : $latest_totd->the_post();
        // Custom, first-post loop markup here
    endwhile; endif;
    // IMPORTANT
    wp_reset_postdata();

    Then, just output your normal loop:

    if ( have_posts() ) : while ( have_posts() ) : the_post();
        // Normal loop markup here
    endwhile; endif;

    That’s all you need for your template file. The rest goes in functions.php.

    Your pre_get_posts callback:

    function totd_pre_get_posts( $query ) {
        // target the main query on the totd_cat tax template
        if ( $query->is_tax( 'totd_cat' ) && $query->is_main_query() ) {
            // apply offset here
            // Use your current code
        }
    }
    add_action( 'pre_get_posts', 'totd_pre_get_posts' );

    Then, your found_posts filter:

    function totd_found_posts( $found_posts, $query ) {
        // Same query conditionals
        if ( $query->is_tax( 'totd_cat' ) && $query->is_main_query() ) {
            // Put your found_posts callback stuff here
        }
    }
    add_filter( 'found_posts', 'totd_found_posts', 10, 2 );

    And you should be good to go.

    Christian Chung

    (@christian1012)

    Yes indeed, what Chip said above. Although he suggests using two loops as you did. I guess to each his own. But I absolutely agree on moving pre_get_posts and found_posts to functions.php.

    Chip Bennett

    (@chipbennett)

    Theme Review Admin

    I neglected to mention: if the first-post special markup is only intended for the latest post, and only display on the first page of the taxonomy archive index, you should wrap it in an is_paged() conditional:

    if ( ! is_paged() ) {
        $latest_totd = new WP_Query( /* args here */ );
        if ( $latest_totd->have_posts() ) : while ( $latest_totd->have_posts() ) : $latest_totd->the_post();
            // Custom, first-post loop markup here
        endwhile; endif;
        // IMPORTANT
        wp_reset_postdata();
    }

    And I do think that two queries are appropriate here. We’re literally pulling the latest post out of the normal query, and treating it in a special way.

Viewing 15 replies - 1 through 15 (of 20 total)
  • The topic ‘Custom Taxonomy Template (Help Me Understand the Array)’ is closed to new replies.