ThemeShaper Forums » Development Talk


Custom Post Type Archives, Custom Menus and Body Classes

(10 posts)
  • Started 12 years ago by cannobbio
  • Latest reply from SocialBlogsite
  1. cannobbio

    I'm using WP 3.1 RC2 and Thematic revision 759 (latest). I'm working in spanish.
    I've created a CPT and used 'has_archive' => 'products' to generate the archive (new WP 3.1 feature).
    To show this "products" archive in the menu I had to create a custom link (there's no other way, or I'm missing something). So far so good, but when I click the "Products" button on the menu and the Custom Post Type Archive is displayed, the link on the menu shows that the "current_page_parent" is my "Blog" page (the page that holds the regular entries). Same happens when displaying a single product.

    I'm pointing out this fact to clarify mi doubts on this matter. Maybe I need to read some more...any help is appreciated.

    The Custom Post Type Archive for "Products" has this body classes (just as a regular archive):

    <body class="wordpress blogid-1 y2011 m01 d03 h16 archive not-singular loggedin windows chrome ch8-0">

    It should have the custom post type slug somewhere:

    <body class="wordpress blogid-1 y2011 m01 d03 h16 archive not-singular products loggedin windows chrome ch8-0">

    Custom Taxonomies work as expected:

    <body class="wordpress blogid-1 y2011 m01 d03 h17 archive not-singular taxonomy tax-brand brand-adidas loggedin windows chrome ch8-0">

    Well, please excuse my bad english and my bad questions...any help is welcome.

    Posted 12 years ago #
  2. i dont think you are mistaken. i don't think those have made it into the custom menus yet, unfortunately.

    Posted 12 years ago #
  3. cannobbio

    Haven't found a way to put the CPT name in the body classes yet but found a workarround to fix the current_page_parent issue in with custom menus and CPTs (

    // Menu Fix for CPT
    function remove_parent($var)
    	// check for current page values, return false if they exist.
    	if ($var == 'current_page_item' || $var == 'current_page_parent' || $var == 'current_page_ancestor'  || $var == 'current-menu-item') { return false; }
    	return true;
    function add_class_to_cpt_menu($classes)
    	// your custom post type name
    	if (get_post_type() == 'products')
    		// we're viewing a custom post type, so remove the 'current_page_xxx and current-menu-item' from all menu items.
    		$classes = array_filter($classes, "remove_parent");
    		// add the current page class to a specific menu item.
    		if (in_array('menu-item-xx', $classes)) $classes[] = 'current_page_parent';
    	return $classes;
    add_filter('nav_menu_css_class', 'add_class_to_cpt_menu');

    Comments are welcomed =)

    Posted 12 years ago #
  4. Hi cannobbio,

    Good news! I'll updating the dynamic_classes.php shortly to further support post types and taxonomies. The latest svn revisions of Thematic now support displaying post type and taxonomy information and links in the thematic_post_footer.

    Sorry it's taken a while to get this integrated into Thematic but these WP features have just started to get polished with WP 3.1 rc3.

    To show this "products" archive in the menu I had to create a custom link (there's no other way, or I'm missing something).

    - Try setting the argument

    show_in_nav_menus => true

    when registering post types and taxonomies to get them to be available in the appearance>menus section of the admin.

    Come to this thread: Thematic 0.9.8 beta testers wanted in the development talk forum and join the conversation.


    Posted 12 years ago #
  5. gene, i've got RC3 running and i've tried the show_in_nav_menus argument with no real luck. can't go back to check now b/c i'm swamped, but this definitely works for you to get a link to the post type archive?

    Posted 12 years ago #
  6. Hmmm. I just checked my WP trunk install and the show_in_nav_menus is working fine for me. Did you check in the "screen options" tab to se if all the metaboxes were selected and not hidden.

    Posted 12 years ago #
  7. cannobbio

    I'm sorry for the late reply...been very busy with work.
    Thank you both for your replies! Gonna check now what's going on the beta tester thread.

    The "show_in_nav_menus => true" argument works only for displaying Custom Taxonomies related to the Custom Post Type, but it doesn't list the "Products" page (custom post type archive) anywhere on the menu editor, that's why I ended up using a custom link.

    The latest svn revisions of Thematic now support displaying post type and taxonomy information and links in the thematic_post_footer.

    Yes, I'm using the latest SVN r762 and it works perfectly. I used the new code to create a Single Product DataSheet (summary of product characteristics):


    Posted 12 years ago #
  8. middlesister

    I have played around a bit with custom post types and for me show_in_nav_menus => true works fine for the individual posts, but it will not give you option to add a link to the archives of the custom post type.
    There is a ticket in wordpress addressing this - Like you said, hard-coding the link into the menu doesn't add the .current_page class. Lets hope this gets addressed in 3.2.

    In the meantime, I have added custom post css classes to both the body and post div with some filters:

    function childtheme_add_posttype_bodyclasses($c) {
    	global $post;
    	if ( is_archive() && is_post_type_archive() ) {
    		$c[] = 'post-type-archive';
    		$c[] = 'post-type-archive-' . sanitize_html_class( get_query_var( 'post_type' ) );
    	if (is_single()) {
    		$c[] = 'single-' . sanitize_html_class($post->post_type, $post->ID);
    		$post_format = get_post_format( $post->ID );
    		if ( $post_format && !is_wp_error($post_format) )
    			$c[] = 'single-format-' . sanitize_html_class( $post_format );
    			$c[] = 'single-format-standard'; // end cakra-addition
    	return $c;


    function childtheme_add_posttype_postclasses($c) {
    	global $post;
    	$c[] = $post->post_type;
    	$c[] = 'type-' . $post->post_type;
    	$post_format = get_post_format( $post->ID );
    	if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
    		if ( $post_format && !is_wp_error($post_format) )
    			$c[] = 'format-' . sanitize_html_class( $post_format );
    			$c[] = 'format-standard';
    	return $c;

    Most of the code is more or less taken straight from wordpress' post-template.php and simply adds the same classes that wordpress adds by default to the end of the thematic classes.
    I saw you managed to work around the issue with styling the menu anyway, but maybe these kan come in handy another time. :-)

    Posted 12 years ago #
  9. Goran

    This really is one of those little frustrating things I'm getting used to with Wordpress. 'show_in_nav_menus' defaults to true if 'public' is true anyway, which is something I guess that most people use, so that doesn't help.

    The only workaround I've found is to create a page that will have the same slug as the archive and in that case, the page won't get displayed when viewing it (the archive will), but it's possible to pick it in the menu.

    For fixing the active menu button, the fix is to modify the start_el function with the custom walker option and add current-menu-item to the class list.


    $classes[] = 'menu-item-' . $item->ID;


    if (basename($item->url) == MY_ARCHIVE_SLUG && get_post_type() == MY_POST_TYPE)
                $classes[] = 'current-menu-item';

    Obviously, if current-menu-item is getting styled differently then current-menu-parent / ancestor it will require more tinkering. I don't need it, so I didn't give it much thought.

    Also, whether this causes some problems in the future, I just don't know.

    Posted 12 years ago #
  10. I'd like to format each of the pages by it's name, BUT build the menus with WP nav items editor.

    THE PROBLEM is that I can't get the "post_name" from the nav_menu_item because IT DOESN'T HAVE ONE.

    How do I get post name related with that Menu Item?

    My function is

    function page_name_class( $css_class, $post ) {
    $css_class = array();
    $css_class[] = 'pagename_' . sanitize_title_with_dashes( $post->post_title );
    $css_class[] = 'menuorder-' . $post->menu_order;
    return $css_class;

    Posted 11 years ago #

RSS feed for this topic

Topic Closed

This topic has been closed to new replies.