WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Assigning Category Hierarchy to Posts by ID not alphabetically (21 posts)

  1. elbego
    Member
    Posted 1 year ago #

    Ok - this is starting to hurt my brain now...

    My Post Cats are set up like this:

    China (top level)

    -News
    - -Shanghai
    -- Tianjin

    -Photos
    -- Shanghai
    -- Tianjin

    -Testimonials
    -- Shanghai
    -- Tianjin

    etc..

    All is fine except for the posts in the Testimonials > Shanghai category won't display essential page elements correctly (category lists, top level category title etc...), simply because 'Testimonials' is alphabetically after 'Shanghai' and therefore assigns the 'Shanghai' category as the posts main category. And this goes for any sub category whose name starts with alphabetical prominence.

    This occurs in my archive.php and single.php

    How can I get wordpress to ignore the alphabetical hierarchy and use category ID for prominence?

    Cheers.

  2. elbego
    Member
    Posted 1 year ago #

    could it be altered using: wp_set_post_categories?

  3. elbego
    Member
    Posted 1 year ago #

    Surely someone else had experienced this?! It comes up time after time!

  4. keesiemeijer
    moderator
    Posted 1 year ago #

    Can we have a link to the page where this is happening?

  5. elbego
    Member
    Posted 1 year ago #

    Can't link to page but here's the code

    This outputs correctly for this category hierarchy:

    UK > Luxury Training > Restaurant (outputs: UK > Luxury > Restaurant)

    But not for:

    UK > Luxury Training > Universities (outputs: UK > Luxury > UK)

    the order that the categories are assigned changes depending on alphabetical order??

    <?php  // Output post parent category name                                  
    
    								  $category = get_the_category();
                                      $parent = get_cat_name($category[0]->category_parent);
                                      if (!empty($parent)) {
                                      echo $parent;
                                      } else {
                                      echo $category[0]->cat_name;
                                      }
                                     ?> News :
                                    <?php 
    
    								  $category = get_the_category();
    								  $firstCategory = $category[0]->cat_name; echo $firstCategory;?> <br />
    								<?php if (has_term('luxury-training', 'category')) {
    								  $secondCategory = $category [1]->cat_name; echo  $secondCategory;
    								} ?>
                               </h3>
    
                             </div>
                           <?php if (has_term('luxury-training', 'category')) {?>
                             <h2> Visit the <a href="/<?php echo $category [1]->slug; ?>">   <?php echo $category [1]->cat_name; ?> </a> training page</h2>                       <?php } ?>
                       	</div>
  6. keesiemeijer
    moderator
    Posted 1 year ago #

    From the code I can't really tell what it is you want to do. Show all parent category names for the 'luxury-training' category and the 'luxury-training' category itself?

  7. elbego
    Member
    Posted 1 year ago #

    Sorry - it's not very clear!

    OK - this is in single.php

    I want to output the top level, then second level, then if the current post is in the category 'Luxury-training' output the third level

    Then, again, if post is in the 'Luxury-training' cat - output also the third level again into link tag that links to a page of same slug as the category (bit in the h2 tag).

    Hope that makes sense!

  8. elbego
    Member
    Posted 1 year ago #

    Like this:

    UK News : Luxury Training
    Universities
    Visit the Universities training page

  9. elbego
    Member
    Posted 1 year ago #

    Thanks for taking the time!

  10. keesiemeijer
    moderator
    Posted 1 year ago #

    Just to be clear do all posts only have only one top level category? Or can they have multiple top level cats. What should happen if they do?

  11. elbego
    Member
    Posted 1 year ago #

    they only have one Top level... i.e. UK or Europe etc...

  12. keesiemeijer
    moderator
    Posted 1 year ago #

    Try it with this for posts with the 'luxury-training' category.

    <?php
    $html = '';
    $terms = array();
    $cat_id = 4; // 'luxury-training' category ID
    $seperator = ' ';
    
    if ( has_term( $cat_id, 'category' ) ) {
    
    	$ancestors = get_ancestors( $cat_id, 'category' );
    
    	// does it have a top level category
    	if ( !empty( $ancestors ) ) {
    
    		$top_level_cat_id = end( $ancestors );
    
    		// top level category and 'luxury-training' category
    		$html .= get_cat_name( $top_level_cat_id ) . ' ' . 'News: ';
    		$html .= $seperator . get_cat_name( $cat_id );
    
    		$child_cats = get_categories( 'child_of='.$cat_id );
    
    		// child categories of 'luxury-training' category
    		if ( $child_cats ) {
    			foreach ( $child_cats as $cat ) {
    				$html .= $seperator . '<a href="' . get_category_link( $cat->term_id ) . '">' . $cat->name .'</a>';
    			}
    		}
    
    	}
    } else {
    	// do stuff for posts that don't have the 'luxury-training' category
    }
    echo $html;
    ?>

    Change the category ID in $cat_id = 4; // 'luxury-training' category ID

  13. elbego
    Member
    Posted 1 year ago #

    Wow! Thanks very much for your time on this!

    Good guess on the ID - it's actually 40!

    This works to a point but outputs all sub categories of Luxury Training rather than just the sub categories that the current post is in.

  14. keesiemeijer
    moderator
    Posted 1 year ago #

    Ah, try it with this [untested]:

    <?php
    $html = '';
    $terms = array();
    $cat_id = 40; // 'luxury-training' category ID
    $seperator = ' ';
    $post_terms = wp_get_post_categories( $post->ID, array( 'fields' => 'ids' ) );
    
    if ( $post_terms && has_term( $cat_id, 'category' ) ) {
    
    	$ancestors = get_ancestors( $cat_id, 'category' );
    
    	// does it have a top level category
    	if ( !empty( $ancestors ) ) {
    
    		$top_level_cat_id = end( $ancestors );
    
    		// top level category and 'luxury-training' category
    		$html .= get_cat_name( $top_level_cat_id ) . ' ' . 'News: ';
    		$html .= $seperator . get_cat_name( $cat_id );
    
    		$child_cats = get_categories( 'child_of='.$cat_id );
    
    		// child categories of 'luxury-training' category
    		if ( $child_cats ) {
    			foreach ( $child_cats as $cat ) {
    				if ( in_array( $cat->term_id, $post_terms ) )
    					$html .= $seperator . '<a href="' . get_category_link( $cat->term_id ) . '">' . $cat->name .'</a>';
    			}
    		}
    
    	}
    } else {
    	// do stuff for posts that don't have the 'luxury-training' category
    }
    echo $html;
    ?>
  15. elbego
    Member
    Posted 1 year ago #

    Beautiful - you nailed it... many thanks! Now to work out how you did it...

    Is it the fields => 'ids' that dicates the category output order?

  16. keesiemeijer
    moderator
    Posted 1 year ago #

    I'm glad it works.

    The fields => 'ids' argument only gets the term IDs and not the full term objects (smaller query on the database).

    Don't you need to show terms if a post doesn't have the term 'luxury-training'?

    // do stuff for posts that don't have the 'luxury-training' category
  17. elbego
    Member
    Posted 1 year ago #

    Yes - thats perfect thanks again. :)

  18. elbego
    Member
    Posted 1 year ago #

    Still struggling with this - I'm trying to have the option that if a post only has the category of Luxury-training and no sub cat of that it outputs separate code, I've tried this but it fails to output anything

    // child categories of 'luxury-training' category
                                        if ( !empty ( $child_cats ) ) {
                                            foreach ( $child_cats as $cat ) {
                                                if ( in_array( $cat->term_id, $post_terms ) )
                                                    $html .= $seperator . '<a href="' . get_category_link( $cat->term_id ) . '">' . $cat->name .'</a></h3></div>
    												<h2>Visit the <a href="/' . $cat->slug  . '">' . $cat->name .'</a> training page</h2></div>';
    										}
    									}
    									elseif ( empty ( $child_cats ) ) {
    											 $html .= $seperator .'<h3></div><h2>Visit the <a href="/' . $cat->slug  . '">' . $cat->name .'</a> training page</h2></div>';                                   }
  19. elbego
    Member
    Posted 1 year ago #

    sorry about the layout - not sure why its misbehaving!

  20. keesiemeijer
    moderator
    Posted 1 year ago #

    Try it with this:

    <?php
    $html = '';
    $terms = array();
    $cat_id = 40; // 'luxury-training' category ID
    $seperator = ' ';
    $post_terms = wp_get_post_categories( $post->ID, array( 'fields' => 'ids' ) );
    
    if ( $post_terms && has_term( $cat_id, 'category' ) ) {
    
    	$ancestors = get_ancestors( $cat_id, 'category' );
    
    	// does it have a top level category
    	if ( !empty( $ancestors ) ) {
    
    		$top_level_cat_id = end( $ancestors );
    
    		// top level category and 'luxury-training' category
    		$html .= get_cat_name( $top_level_cat_id ) . ' ' . 'News: ';
    		$html .= $seperator . get_cat_name( $cat_id );
    
    		$child_cats = get_categories( 'child_of='.$cat_id );
    
    		if ( $child_cats ) {
    
    			$no_children = true;
    			// child categories of 'luxury-training' category
    			foreach ( $child_cats as $cat ) {
    				if ( in_array( $cat->term_id, $post_terms ) ) {
    					// post has child categories of the 'luxury-training' category
    					$html .= $seperator . '<a href="' . get_category_link( $cat->term_id ) . '">' . $cat->name .'</a>';
    					$no_children = false;
    				}
    			}
    			if ( !$no_children ) {
    				// post has no child categories of the 'luxury-training' category
    			}
    
    		} else {
    			// no child categories found for 'luxury-training' category
    		}
    
    	}
    } else {
    	// do stuff for posts that don't have the 'luxury-training' category
    }
    echo $html;
    ?>

    And put the separate code here:

    // post has no child categories of the 'luxury-training' category
  21. elbego
    Member
    Posted 1 year ago #

    That's sorted it!

    I am in your debt.

Topic Closed

This topic has been closed to new replies.

About this Topic