Skip to:
Content
Pages
Categories
Search
Top
Bottom

How to add a few more members-directory pages?

  • @landwire

    Participant

    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

Viewing 25 replies - 1 through 25 (of 26 total)
  • @henrywright

    Moderator

    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

    @landwire

    Participant

    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,
    Sascha

    @landwire

    Participant

    Hmm, 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

    @henrywright

    Moderator

    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' ); ?>

    @landwire

    Participant

    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/
    S

    @henrywright

    Moderator

    I 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?

    @landwire

    Participant

    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!
    Sascha

    @landwire

    Participant

    Henry, 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');

    @landwire

    Participant

    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.

    @henrywright

    Moderator

    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!

    @landwire

    Participant

    Yes, shortcode works great! Glad you like the approach!


    @Henry

    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
    Sascha

    @henrywright

    Moderator

    I 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.

    @henrywright

    Moderator

    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.

    @landwire

    Participant

    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….

    @henrywright

    Moderator

    If you have links like this example.com/members/username then root profiles are disabled. If you have this example.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. Author

    Adapted from here:

    Exclude Users from Members directory on a BuddyPress based social network

    @landwire

    Participant

    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:

    bp_ajax_querystring()

    I guess I find the

    To filter ajax:

    bit odd. Maybe I should use that filter?

    @landwire

    Participant

    Ok, this explains the ajax is_page check not working:

    http://wordpress.stackexchange.com/questions/26472/is-page-conditional-not-working-inside-an-ajax-function

    Will try your last suggestion in a little while and report back.
    S

    @landwire

    Participant

    Looking 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?

    @landwire

    Participant

    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 );

    @henrywright

    Moderator

    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 );

    @landwire

    Participant

    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/suppliers

    I 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?

    @henrywright

    Moderator

    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.

    @landwire

    Participant

    Nope, is_page does not work in ajax call. See earlier comment:

    Ok, this explains the ajax is_page check not working:

    http://wordpress.stackexchange.com/questions/26472/is-page-conditional-not-working-inside-an-ajax-function

    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

    @henrywright

    Moderator

    @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/

    @landwire

    Participant

    Ok, never know which place is best to ask a question like that.
    Thanks!

Viewing 25 replies - 1 through 25 (of 26 total)
  • The topic ‘How to add a few more members-directory pages?’ is closed to new replies.
Skip to toolbar