Skip to:
Content
Pages
Categories
Search
Top
Bottom

How to get a section identifier in the body tag?

  • @peterverkooijen

    Participant

    Regular WordPress pages have something like this in the body tag:

    page-template-contact-php

    In this case, the template page contact.php. I can use that in CSS to set the Contact menu button to ‘current/active page’.

    The members, groups and blogs sections in Buddypress all have only this in the body tag:

    class=”directory”

    How can I add a section identifier to that body tag? So I get something like this:

    class=”directory members”

    Which piece of code adds the class to the regular WordPress pages? Could I use a modified version of the code for Buddypress sections? Can I fix it in the template or do I have to hack core files?

    Or are there other ways to set a menu button to active? I’ve looked at Javascripts, but couldn’t get anything to work. I prefer a CSS solution.

Viewing 19 replies - 1 through 19 (of 19 total)
  • @r-a-y

    Keymaster

    You can create your own css class function to do this… similar to how WP’s Thematic, Sandbox and Hybrid themes have their own css class output function.

    Here’s a few lines to get you started:

    global $bp;
    echo $bp->current_component; //outputs current component

    echo '<br />'; // redundant line break! don't worry about this line!

    echo $bp->current_action; // outputs current action

    Hope that helps!

    [EDIT]

    For directories… you’ll have to check if the page is either BP_MEMBERS_SLUG, BP_GROUPS_SLUG, BP_BLOGS_SLUG.

    eg. if ( bp_is_page( BP_MEMBERS_SLUG ) ) echo ' members';

    @peterverkooijen

    Participant

    Thanks r-a-y!

    I’m not really a coder, but Sandbox has a lot of information on the topic.

    I’ll look into it when I have time and will report back…

    @peterverkooijen

    Participant

    The default templates have body_class() in the body tag. The function body_class() is in post-template.php in the wp-includes folder:

    function body_class( $class = '' ) {
    // Separates classes with a single space, collates classes for body element
    echo 'class="' . join( ' ', get_body_class( $class ) ) . '"';
    }

    Function get_body_class() is in the same file:

    /**
    * Retrieve the classes for the body element as an array.
    *
    * @since 2.8.0
    *
    * @param string|array $class One or more classes to add to the class list.
    * @return array Array of classes.
    */
    function get_body_class( $class = '' ) {
    global $wp_query, $wpdb, $current_user;

    $classes = array();

    if ( 'rtl' == get_bloginfo('text_direction') )
    $classes[] = 'rtl';

    if ( is_front_page() )
    $classes[] = 'home';
    if ( is_home() )
    $classes[] = 'blog';
    if ( is_archive() )
    $classes[] = 'archive';
    if ( is_date() )
    $classes[] = 'date';
    if ( is_search() )
    $classes[] = 'search';
    if ( is_paged() )
    $classes[] = 'paged';
    if ( is_attachment() )
    $classes[] = 'attachment';
    if ( is_404() )
    $classes[] = 'error404';

    if ( is_single() ) {
    $wp_query->post = $wp_query->posts[0];
    setup_postdata($wp_query->post);

    $postID = $wp_query->post->ID;
    $classes[] = 'single postid-' . $postID;

    if ( is_attachment() ) {
    $mime_type = get_post_mime_type();
    $mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
    $classes[] = 'attachmentid-' . $postID;
    $classes[] = 'attachment-' . str_replace($mime_prefix, '', $mime_type);
    }
    } elseif ( is_archive() ) {
    if ( is_author() ) {
    $author = $wp_query->get_queried_object();
    $classes[] = 'author';
    $classes[] = 'author-' . sanitize_html_class($author->user_nicename , $author->user_id);
    } elseif ( is_category() ) {
    $cat = $wp_query->get_queried_object();
    $classes[] = 'category';
    $classes[] = 'category-' . sanitize_html_class($cat->slug, $cat->cat_ID);
    } elseif ( is_tag() ) {
    $tags = $wp_query->get_queried_object();
    $classes[] = 'tag';
    $classes[] = 'tag-' . sanitize_html_class($tags->slug, $tags->term_id);
    }
    } elseif ( is_page() ) {
    $classes[] = 'page';

    $wp_query->post = $wp_query->posts[0];
    setup_postdata($wp_query->post);

    $pageID = $wp_query->post->ID;

    $classes[] = 'page-id-' . $pageID;

    if ( $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' LIMIT 1", $pageID) ) )
    $classes[] = 'page-parent';

    if ( $wp_query->post->post_parent ) {
    $classes[] = 'page-child';
    $classes[] = 'parent-pageid-' . $wp_query->post->post_parent;
    }
    if ( is_page_template() ) {
    $classes[] = 'page-template';
    $classes[] = 'page-template-' . str_replace( '.php', '-php', get_post_meta( $pageID, '_wp_page_template', true ) );
    }
    } elseif ( is_search() ) {
    if ( !empty($wp_query->posts) )
    $classes[] = 'search-results';
    else
    $classes[] = 'search-no-results';
    }

    if ( is_user_logged_in() )
    $classes[] = 'logged-in';

    $page = $wp_query->get('page');

    if ( !$page || $page < 2)
    $page = $wp_query->get('paged');

    if ( $page && $page > 1 ) {
    $classes[] = 'paged-' . $page;

    if ( is_single() )
    $classes[] = 'single-paged-' . $page;
    elseif ( is_page() )
    $classes[] = 'page-paged-' . $page;
    elseif ( is_category() )
    $classes[] = 'category-paged-' . $page;
    elseif ( is_tag() )
    $classes[] = 'tag-paged-' . $page;
    elseif ( is_date() )
    $classes[] = 'date-paged-' . $page;
    elseif ( is_author() )
    $classes[] = 'author-paged-' . $page;
    elseif ( is_search() )
    $classes[] = 'search-paged-' . $page;
    }

    if ( !empty($class) ) {
    if ( !is_array( $class ) )
    $class = preg_split('#s+#', $class);
    $classes = array_merge($classes, $class);
    }

    return apply_filters('body_class', $classes, $class);
    }

    So I guess I could just add this to the code:

    if ( bp_is_page( BP_MEMBERS_SLUG ) )
    $classes[] = 'members';

    Etc.

    Should I copy this function to functions.php in the template, perhaps rename it, and add the lines for ‘members’ and ‘groups’ etc.?

    Or should I aim for a shorter function that only adds something to what this code generates? Would that be possible?

    Trying the blunt approach first…

    Edit: I’ve tried with that BP_MEMBERS_SLUG line added directly to post-template.php, with $bp in global, but nothing shows up in the body tag. :-(

    What am I missing? Is Buddypress bypassing post-template.php anyway? The only class is “directory”.

    @peterverkooijen

    Participant

    What are these lines supposed to do?

    global $bp;
    echo $bp->current_component; //outputs current component

    echo '<br />'; // redundant line break! don't worry about this line!

    echo $bp->current_action; // outputs current action

    I see nothing like that in the functions in post-template.php or Sandbox’ function.php.

    Edit: Class on Members and Groups stays at “directory” because it is set in bp-themes, not bphome. It is set with this line:

    <?php if ( bp_is_directory() ) : ?> class="directory"<?php endif; ?>

    Replacing it with the function copied from Sandbox…

    @peterverkooijen

    Participant

    Adding this to sandbox_body_class() produces the required result:

    if ( bp_is_page( BP_MEMBERS_SLUG ) )
    $c[] = 'members';

    @r-a-y

    Keymaster

    I guess I shouldn’t have led you down the Sandbox road!

    I should have said look at those functions as a structure… don’t use it literally as most of that code is WP-specific only.

    As for these lines:

    global $bp;
    echo $bp->current_component; //outputs current component
    echo $bp->current_action; // outputs current action

    They are BP-specific and will let you determine what type of BP page you’re on (except for directories)… try it by putting the lines in the header.php of your BP member theme.

    I would use the lines in your new CSS class function like this:

    function bp_body_class( $print = true ) {
    global $bp;

    if ( bp_is_page( BP_MEMBERS_SLUG ) )
    $c[] = 'members';

    //more conditionals here

    $c[] = $bp->current_component; //outputs current component
    $c[] = $bp->current_action; // outputs current action

    // Separates classes with a single space, collates classes for BODY
    $c = join( ' ', apply_filters( 'body_class', $c ) ); // Available filter: body_class

    // And tada!
    return $print ? print($c) : $c;
    }

    Something to that effect in your bp theme’s functions.php file.

    That’s basically 90% of the function right there.

    @peterverkooijen

    Participant

    Thanks again r-a-y!

    I did use Sandbox as an example, just to get something working quick. I had already taken most of the code out, but with your latest suggestions I can clean it up even further. :-)

    @peterverkooijen

    Participant

    Now trying to add something like this, to cut down the number of different classes I have to cover in my CSS:

    if ( $bp->current_component( 'activity' ) )
    $c[] = 'members';

    That doesn’t work. Other variations I could try?

    @r-a-y

    Keymaster

    don’t use brackets… use == instead.

    eg. if ( $bp->current_component == 'activity' )

    @peterverkooijen

    Participant

    Wow, thanks again r-a-y, that actually works!

    And it doesn’t replace ‘activity’ in the class, just adds ‘members’, which is probably a good thing.

    Learned a new trick I can abuse all over the place. :-)

    @r-a-y

    Keymaster

    You can change $c[] = ‘members’ to whatever you want!

    if ( $bp->current_component ==  'activity' )
    $c[] = 'my-damn-activity';

    Totally up to you!

    @peterverkooijen

    Participant

    This also works! :-)

    if ( $bp->current_component == 'activity' || 'profile' || 'wire' || 'messages' || 'friends')
    $c[] = 'members';

    But why does this line also add a ‘members’ tag to the groups directory home page body class?! And the blogs directory… :-(

    @peterverkooijen

    Participant

    How is current_component identified? This is like herding cats.

    Is there a way to make the tags mutually exclusive; if $c[] is ‘members’, it is NOT ‘groups’ or ‘blogs’ etc.?

    @peterverkooijen

    Participant

    I think I finally got what I wanted using all these combined:

    $c[] = $bp->current_component; //outputs current component
    $c[] = $bp->current_action; // outputs current action

    if ( $bp->current_component == 'activity' || $bp->current_component == 'profile' || $bp->current_component == 'wire' || $bp->current_component == 'messages' || $bp->current_component == 'friends')
    $c[] = 'members';

    if ( bp_is_page( BP_MEMBERS_SLUG ) )
    $c[] = 'members';

    The shorter version from two posts ago apparently does not work.

    If I leave anything out, something breaks; I get a ‘members’ tag on ‘groups’ and ‘blogs’ or no tags or whatever. Why, I have no clue…

    Is there a way to exclude or remove a tag? I don’t want two buttons on the navigation highlighted on the groups members section, for example.

    @r-a-y

    Keymaster

    Since you’re using conditionals, I would comment out the following in your body class function:

    $c[] = $bp->current_component; //outputs current component
    $c[] = $bp->current_action; // outputs current action

    To know what component or action you’re on, I would output that info in your bp member theme header.php.

    global $bp;
    echo 'type: '.$bp->current_component; //outputs current component
    echo '<br />';
    echo 'action:'.$bp->current_action; // outputs current action

    Then you can clearly define your conditionals in your body class function… the rest is up to you!

    @peterverkooijen

    Participant

    How do I get the correct body tag in the signup/register page?

    Is it a ‘component’? An ‘action’? It doesn’t behave as a custom page either…?

    This does not work:

    if ( is_page('register') )
    $c[] = 'members';

    @r-a-y

    Keymaster
    if ( $bp->current_component == BP_REGISTER_SLUG && $bp->current_action == '' ) {
    ...
    }

    But you shouldn’t really need to define this since the register page template is already accessible on your main WP theme (depending if you’ve copied the bp_show_register_page() function from the original bphome theme).

    @peterverkooijen

    Participant

    Can’t get BP_REGISTER_SLUG to work. Are you sure it exists?

    I don’t have bp_show_register_page() in my register.php template file, if that’s what you mean. It has bp_core_signup_do_signup().

    I’ve customized a lot. It would be hell to trace back where it got lost. I’m looking for a blunt solution – botte bijl in Dutch. Something straightforward that just works.

    Isn’t there a php solution to add something to the body class (in header.php) from a template file like register.php?

    Edit: Oops, think I see the problem. The header still had wp_body_class() instead of my custom_body_class().

    Edit2: Now remember that was deliberate. I needed a custom_body_class for bpmember, but my custom function messed up regular wp-pages, so in bphome I used wp_body_class. So why doesn’t /register have any usable tags? Very confused…

    Will this be easier in version 1.1 as well? :-)

    @peterverkooijen

    Participant

    I’m upgrading to 1.1.3, so I have to redo this mess again. I had it sorta working on 1.0, but it doesn’t work anymore.

    r-a-y’s earlier solutions are over my head. I have no idea what conditionals are. I’m also trying to avoid having to add yet more lines to the header. I’d like to keep the template files script-free as much as possible. It should be possible to do with just a function called in the body tag.

    Has anyone else figured this out?

Viewing 19 replies - 1 through 19 (of 19 total)
  • The topic ‘How to get a section identifier in the body tag?’ is closed to new replies.
Skip to toolbar