How to get a section identifier in the body tag?
-
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.
-
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 actionHope 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';
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…
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”.
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 actionI 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…
Adding this to sandbox_body_class() produces the required result:
if ( bp_is_page( BP_MEMBERS_SLUG ) )
$c[] = 'members';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 actionThey 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.
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.
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?
don’t use brackets… use == instead.
eg.
if ( $bp->current_component == 'activity' )
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.
You can change $c[] = ‘members’ to whatever you want!
if ( $bp->current_component == 'activity' )
$c[] = 'my-damn-activity';Totally up to you!
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…
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.?
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.
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 actionTo 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 actionThen you can clearly define your conditionals in your body class function… the rest is up to you!
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';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).
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?
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?
- The topic ‘How to get a section identifier in the body tag?’ is closed to new replies.