WordPress.org

Ready to get started?Download WordPress

Forums

Quick and dirrrty Canonical URLs for custom taxonomy posts (2 posts)

  1. design_dolphin
    Member
    Posted 4 years ago #

    What: Canonical URL
    How: The PHP code looks at the manually custom taxonomy path created in the code to the post.
    Where: Place the code between the head tags in the header.php. It will then automatically place the Canonical URL in the head of the XHTML document
    Who: Google. Yahoo and Live search are also planning to use it, AFAIK.
    Why: Silly rabbit, tricks are for kids, but seriously it's supposedly good SEO, but don't take my word for it.
    When: A Canonical URL link is shown in the head of the document when somebody views a post.

    Alfa code. Use at your own risk. Subject to peer review.

    You should be able to expand this code by using a variable for example to choose which custom taxonomy term you want to show, maybe something with custom fields or within a plugin, and override the default behavior. This would allow you to choose which custom taxonomy term you would want to show in the Canonical URL path in case you have more than one term for a post. As for now, it just picks one, it needs further testing if it always chooses the same term, or if this is subject to change. I have not found it to change (yet), but there could be use cases where this is not the case.

    <?php  if (is_single()) { ?>
    <?php  $title = $post->post_name; ?>
    <?php 
    
    		if ( in_category(enter parent category id 1) || post_is_in_descendant_category( enter parent category id 1 )) {
    			$terms = get_the_terms($post->ID, 'custom taxonomy name 1');
    			$count_terms = count($terms);
    
    			if ($terms > 0) {
    				foreach ($terms as $taxindex => $taxitem) {
    					$url = esc_attr(get_bloginfo('url') . '/' . $taxitem->taxonomy . '/' . $taxitem->slug. '/' . $title . '.html');
    					$canonical_url = '<link rel="canonical" href="' . $url . '">';
    				}
    
    			} else {
    				$canonical_url = "";
    			}
    
    		}
    
    		if ( in_category(enter parent category id 2) || post_is_in_descendant_category( enter parent category id 2 )) {
    			$terms = get_the_terms($post->ID, 'custom taxonomy name 2');
    
    			if ($terms > 0) {
    				$count_terms = count($terms);
    				foreach ($terms as $taxindex => $taxitem) {
    					$url = esc_attr(get_bloginfo('url') . '/' . $taxitem->taxonomy . '/' . $taxitem->slug . '/' . $title. '.html');
    					$canonical_url =   '<link rel="canonical" href="' . $url . '">';
    				}
    
    			} else {
    				$canonical_url = "";
    			}
    
    		}
    
    		?>
    <?php  echo $canonical_url  ?>
    <?php  } ?>

    You will also need this bit of code in the functions.php of your theme. This will allow you to enter the parent category in the sidebar code, and it should fetch the children categories automatically:

    /**
     * Tests if any of a post's assigned categories are descendants of target categories
     *
     * @param int|array $cats The target categories. Integer ID or array of integer IDs
     * @param int|object $_post The post. Omit to test the current post in the Loop or main query
     * @return bool True if at least 1 of the post's categories is a descendant of any of the target categories
     * @see get_term_by() You can get a category by name or slug, then pass ID to this function
     * @uses get_term_children() Passes $cats
     * @uses in_category() Passes $_post (can be empty)
     * @version 2.7
     * @link http://codex.wordpress.org/Function_Reference/in_category#Testing_if_a_post_is_in_a_descendant_category
     */
    function post_is_in_descendant_category( $cats, $_post = null )
    {
    	foreach ( (array) $cats as $cat ) {
    		// get_term_children() accepts integer ID only
    		$descendants = get_term_children( (int) $cat, 'category');
    		if ( $descendants && in_category( $descendants, $_post ) )
    			return true;
    	}
    	return false;
    }
  2. design_dolphin
    Member
    Posted 4 years ago #

    Update:

    My bad.

    $count_terms = count($terms); is superflous from a previous version of code.

    Please review code carefully before using just in case I overlooked something else.

Topic Closed

This topic has been closed to new replies.

About this Topic