How to add a few more members-directory pages?
-
Hi there,
I am sure it’s easy enough, but I just seem to have a blockage.
I want to show a few more members loops depending on a users role. I have the functionality worked out. I use this in the members-loop for now:
<?php $included_users = implode(',',get_users('role=office&fields=ID')); ?> <?php d($included_users); ?> <?php //if ( bp_has_members( 'include=' . $included_users ) ) : ?> <?php if ( bp_has_members( bp_ajax_querystring( 'members' ) .'&include=' .$included_users ) ) : ?> <?php //if ( bp_has_members( bp_ajax_querystring( 'members' ).'&type=alphabetical' ) ) : ?>
But I would like to create another page for this loop, so that the original members-loop.php is untouched. Basically creating an offices-loop.php and calling it from offices-index.php with this code in it:
<div id="members-dir-list" class="members dir-list"> <?php bp_get_template_part( 'members/offices/office-loop' ); ?> </div><!-- #members-dir-list -->
I assume that would be the right approach? BUT how do I load offices-index.php? I created a new page called offices, but I just do not know how to get it to load offices-index.php.
Thanks,
Sascha
-
You could set up a new page via the WP dashboard, and make sure the slug is ‘offices-loop’. Then you’d just need to add a new file
page-offices-loop.php
to your theme’s directory. All your code can then go in that new file.The page would be accessible via the front-end using: example.com/offices-loop
I thought it’s simple. Just had a block. Tried to create a page-template, but that just did not work…
Will try that right now!
Thanks for the fast reply,
SaschaHmm, that works the same as the page template approach I made earlier.
The display is rather blank though, no footer/header etc. And I had a typo before in my code, so your approach highlighted that mistake!
Is there a way that I could just use a standard template and “inject” the buddypress members content there. Basically just like a copy and paste of the page-offices-loop.php into the wordpress text editor?
Sascha
You’ll need to add your BuddyPress header and footer to the page-office-loop.php file. For example:
<?php get_header( 'buddypress' ); ?> <!-- bits and bobs here --> <?php get_footer( 'buddypress' ); ?>
That works ok now. I basically used the page.php template and replaced the whole loop with the page-office-loop.php file contents and saved that as page-office-loop.php. Does still not look like the members page though.
Maybe take a look if you have a minute. One also shows up a search box while the other does not. Strange. I did NOT use <?php get_footer( ‘buddypress’ ); ?> or <?php get_header( ‘buddypress’ ); ?> as the page template already loads some header/footer.
Modified: http://2013d.landwire.net/offices-index/
Original – though I took members count out of tab: http://2013d.landwire.net/members/
SI think some of the visual differences could be due to CSS. Fundamentally each of these are different. Take the offices-index template for example. If you view the source you’ll see the body classes:
page page-id-1100 page-template-default masthead-fixed full-width singular no-js
Where as if you view the source of the members directory you should see body classes
directory members buddypress masthead-fixed full-width singular no-js
If the theme you’re using makes use of the body class when styling
body.page { // styles ... }
then that could be why it looks different?Thanks Henry, was just looking into the structure of the page too. CSS is a good point and the body classes too! I will get there from here I think. Thanks for your valuable input!
SaschaHenry, would just like your thought on the following.
I went down a different route with the above, not sure if that is recommended though:I created a shortcode like so, basically putting the whole new office-index.php into it. Then just put the shortcode into a page called “office” and it looks great out of the box – all formatting etc intact!
See: http://2013d.landwire.net/office/
You can compare all three now. There still all live.
Do you think it’s ok to do it like that?
function lw_office_directory( $atts ) { do_action( 'bp_before_directory_members_page' ); ?> <div id="buddypress"> <?php do_action( 'bp_before_directory_members' ); ?> <?php do_action( 'bp_before_directory_members_content' ); ?> <div id="members-dir-search" class="dir-search" role="search"> <?php bp_directory_members_search_form(); ?> </div><!-- #members-dir-search --> <?php do_action( 'bp_before_directory_members_tabs' ); ?> <form action="" method="post" id="members-directory-form" class="dir-form"> <div class="item-list-tabs" role="navigation"> <ul> <li class="selected" id="members-all"><a href="<?php bp_members_directory_permalink(); ?>"><?php printf( __( 'All Members', 'buddypress' )); ?></a></li> <?php if ( is_user_logged_in() && bp_is_active( 'friends' ) && bp_get_total_friend_count( bp_loggedin_user_id() ) ) : ?> <li id="members-personal"><a href="<?php echo bp_loggedin_user_domain() . bp_get_friends_slug() . '/my-friends/'; ?>"><?php printf( __( 'My Friends <span>%s</span>', 'buddypress' ), bp_get_total_friend_count( bp_loggedin_user_id() ) ); ?></a></li> <?php endif; ?> <?php do_action( 'bp_members_directory_member_types' ); ?> </ul> </div><!-- .item-list-tabs --> <div class="item-list-tabs" id="subnav" role="navigation"> <ul> <?php do_action( 'bp_members_directory_member_sub_types' ); ?> <li id="members-order-select" class="last filter"> <label for="members-order-by"><?php _e( 'Order By:', 'buddypress' ); ?></label> <select id="members-order-by"> <option value="active"><?php _e( 'Last Active', 'buddypress' ); ?></option> <option value="newest"><?php _e( 'Newest Registered', 'buddypress' ); ?></option> <?php if ( bp_is_active( 'xprofile' ) ) : ?> <option value="alphabetical"><?php _e( 'Alphabetical', 'buddypress' ); ?></option> <?php endif; ?> <?php do_action( 'bp_members_directory_order_options' ); ?> </select> </li> </ul> </div> <div id="members-dir-list" class="members dir-list"> <?php bp_get_template_part( 'members/offices/offices-loop' ); ?> </div><!-- #members-dir-list --> <?php do_action( 'bp_directory_members_content' ); ?> <?php wp_nonce_field( 'directory_members', '_wpnonce-member-filter' ); ?> <?php do_action( 'bp_after_directory_members_content' ); ?> </form><!-- #members-directory-form --> <?php do_action( 'bp_after_directory_members' ); ?> </div><!-- #buddypress --> <?php do_action( 'bp_after_directory_members_page' ); } add_shortcode('lw_office_directory', 'lw_office_directory');
Ok, Now I also learned about
ob_start(); echo 'hello world'; echo 'This is a WordPress shortcode'; $output_string = ob_get_contents(); ob_end_clean(); return $output_string;
So I added this and it works great for me! Maybe that will help someone encoutering the same challenge.
I think a shortcode is good way of doing it actually. You don’t need to create any new files that way.
Glad to see you got it working how you wanted it!
Yes, shortcode works great! Glad you like the approach!
My problem now:
How do I make sure the ajax call on changing “last active” “alphabetical” etc. only returns users of that role, that I am just looking at? As the ajax call seems to revert always to the roles chosen in members-loop.php. So if I restrict roles there, then the ajax call on “office” will respect that. So there must be some kind of “link” between the two, but I do not know how to change the ajax call.
http://2013d.landwire.net/offices/ -> only offices at first, then all roles on ajax call
http://2013d.landwire.net/members/ -> all roles
SaschaI think you could most probably exclude members of a certain role when on the office page. You’d use the
bp_ajax_querystring
filter. For example:function my_filter( $query = false, $object = false ) { if ( is_page( 'office' ) ) { // do some excluding } return $query; } add_filter( 'bp_ajax_querystring', 'my_filter', 20, 2 );
I haven’t tested that idea but think it is the right approach to take.
This is a slight issue with that.
is_page
doesn’t work in BP 1.9.2 if root profiles are enabled. If you have root profiles disabled (the default) then you’re fine.Not sure where I can see if I have root profiles enabled?
Anyway, the ajax filter get’s called, but the is_page (‘offices’) returns false I assume as it does not go into the if. On first load/page refresh the filter gets called and is_page(‘offices’) returns true. Then on ajax call the if returns false.
Could I use another if call? Like setting a global variable or something? Or is maybe I do have root profiles enabled, but I do not think so….
If you have links like this
example.com/members/username
then root profiles are disabled. If you have thisexample.com/username
then root profiles are enabled.Try this:
function my_filter( $query = false, $object = false ) { if ( ! is_page( 'office' ) ) return $query; $users = get_users( 'role=YOUR-ROLE-TO-EXCLUDE' ); $exclude = implode( ',', $users ); if ( $object != 'members' ) return $query; $args = wp_parse_args( $query ); if ( ! empty( $args['user_id'] ) ) return $query; if ( !empty( $args['exclude'] ) ) $args['exclude'] = $args['exclude'] . ',' . $exclude; else $args['exclude'] = $exclude; $query = build_query( $args ); return $query; } add_filter( 'bp_ajax_querystring', 'my_filter', 20, 2 );
Note: Change
YOUR-ROLE-TO-EXCLUDE
to the role you want to exclude. i.e. AuthorAdapted from here:
Exclude Users from Members directory on a BuddyPress based social network
Ok, will try that.
BTW: what is the difference between the following filters:
bp_legacy_theme_ajax_querystring and bp_ajax_querystring as per documentation here:
I guess I find the
To filter ajax:
bit odd. Maybe I should use that filter?
Ok, this explains the ajax is_page check not working:
Will try your last suggestion in a little while and report back.
SLooking at the code I would think it fires on all occasions. I will have at least 4 user roles that I need to filter: office, supplier, student, professional.
Is there any way that I can pass a parameter with the ajax query?
Ok, I am dispairing on this one. Tried globals, but then I read that globals are not accessible in AJAX requests. I guess the only option is to pass some parameter where the call is coming from. Is there a way to do this?
Is there a way to ask one of the core developers if what I am trying to achieve is at all possible? I guess it’s a common thing to group users by their role and then be able to resort them with ajax.
My code looks like this right now: (lots of d($variable), which is just showing me the variables in the console)
function lw_my_filter( $query = false, $object = false ) { d($query, 'QUERY'); d($object, 'OBJECT'); $test = 'Before if call'; d($test); global $lw_directory; d($lw_directory); d($GLOBALS['lw_directory'], 'GLOBAL'); if ( is_page( 'offices' ) ) { $GLOBALS['lw_directory'] = 'office'; $test2 = 'inside if call'; d($test2); $included_users = implode(',',get_users('role=office&fields=ID')); d($included_users); $querystring = 'include=' .$included_users; d($GLOBALS['lw_directory'], 'GLOBAL'); } else if ( $GLOBALS['lw_directory'] == 'office') { $included_users = implode(',',get_users('role=office&fields=ID')); d($included_users); $querystring = 'include=' .$included_users; d($GLOBALS['lw_directory'], 'GLOBAL'); } d($querystring); return $querystring; } add_filter( 'bp_ajax_querystring', 'lw_my_filter', 20, 2 );
Regarding the 4 user roles you need to filter
office, supplier, student, professional
There is a nifty little function called
array_merge
which you can use. You’d get your comma-sep list of users to exclude from the loop like this…$office = get_users( 'role=Office' ); $supplier = get_users( 'role=Supplier' ); $student = get_users( 'role=Student' ); $professional = get_users( 'role=Professional' ); $users = array_merge( $office, $supplier, $student, $professional ); $exclude = implode( ',', $users );
Sorry, maybe I was not clear.
I have the following pages loading directories:
http://www.example.com/offices
http://www.example.com/students
http://www.example.com/professionals
http://www.example.com/suppliersI then need to filter each ajax call to only show that particular user group currently shown in the directory. BUT if it is too difficult, I will just kick out that ajax filter.
I can only see the ajax filter work if there would be the option for instance to include/create a “$sub_object” or pass some other data in from the page that the filter is called from. Is that right?
Ah right. I see now. So you’ll need a separate page for each role.
Try this
function my_filter( $query = false, $object = false ) { if ( is_page( 'office' ) ) { $users = get_users( 'role=office' ); $exclude = implode( ',', $users ); if ( $object != 'members' ) return $query; $args = wp_parse_args( $query ); if ( ! empty( $args['user_id'] ) ) return $query; if ( !empty( $args['exclude'] ) ) $args['exclude'] = $args['exclude'] . ',' . $exclude; else $args['exclude'] = $exclude; $query = build_query( $args ); } return $query; } add_filter( 'bp_ajax_querystring', 'my_filter', 20, 2 );
If
is_page()
doesn’t work then that’ll be a problem.If it does work then you can do the same for the rest of the roles you need.
Nope, is_page does not work in ajax call. See earlier comment:
Ok, this explains the ajax is_page check not working:
Is that something that can be taken to core developers and asked if we can enhance the filter functionality? As said, it’s a pretty common thing to filter by different users I think.
Thanks for all your help anyway again,
Sascha@landwire I see! That explains it.
Is that something that can be taken to core developers and asked if we can enhance the filter functionality
You could always ask? Trac is the best place to do that: https://buddypress.trac.wordpress.org/
Ok, never know which place is best to ask a question like that.
Thanks!
- The topic ‘How to add a few more members-directory pages?’ is closed to new replies.