Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm using this in functions.php to output my page <title>:

/**
 * Creates a nicely formatted and more specific title element text
 * for output in head of document, based on current view
 *
 * @param string $title Default title text for current view
 * @param string $sep Optional separator
 * @return string Filtered title
 */
function sitename_wp_title( $title, $sep ) {
    global $paged, $page;

    if ( is_feed() )
        return $title;

    // Adds the site name
    $title .= get_bloginfo( 'name' );

    // Adds the site description for the front page
    $site_description = get_bloginfo( 'description', 'display' );
    if ( $site_description && ( is_front_page() ) )
        $title = "$title $sep $site_description";

    // Adds a page number if necessary
    if ( $paged >= 2 || $page >= 2 )
        $title = "$title $sep " . sprintf( __( 'Page %s' ), max( $paged, $page ) );

    return $title;
}
add_filter( 'wp_title', 'sitename_wp_title', 10, 2 );

I'd like to include the top level category name on sub pages.

For example currently with a site structure of this:

  • Home
  • About
  • Work
    • Large
    • Small
  • Contact

Posts in the "Large" category will output a page title like this:

<title>$postname | $blog_name</title>

I'd like the output to be:

<title>$postname | Work | $blog_name</title>

So the top-level category name is added, but not the secondary level category (Large).

share|improve this question

1 Answer 1

up vote 2 down vote accepted

Create a helper function to get all parent categories (each post can be in multiple categories):

function parent_cat_names( $sep = '|' )
{
    if ( ! is_single() or array() === $categories = get_the_category() )
        return '';

    $parents = array ();

    foreach ( $categories as $category )
    {
        $parent = end( get_ancestors( $category->term_id, 'category' ) );

        if ( ! empty ( $parent ) )
            $top = get_category( $parent );
        else
            $top = $category;

        $parents[ $top->term_id ] = $top;
    }

    return esc_html( join( $sep, wp_list_pluck( $parents, 'name' ) ) );
}

Add the parent term with …

if ( '' !== $parent_cats = parent_cat_names( $sep ) )
    $title .= "$parent_cats $sep ";
share|improve this answer
    
Doesn't seem to cause any change for me. –  AlecRust Jun 2 '13 at 22:41
    
@AlecRust See my update. –  toscho Jun 2 '13 at 23:38
    
Many thanks. This is now giving me <title>$postname | $blog_nameWork</title>. So the output is correct but incorrectly ordered. –  AlecRust Jun 3 '13 at 20:12
    
@AlecRust You have to use it before get_bloginfo( 'name' );. –  toscho Jun 3 '13 at 20:14
    
That worked great, after modifying the last line to $title .= "$parent_cats $sep "; many thanks for your help. –  AlecRust Jun 3 '13 at 22:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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