使用带有 BuddyPress 的 S2member 时的有用功能和技巧

使用带有 BuddyPress 的 S2member 时的有用功能和技巧

Codex Home → Developer Resources → User Submitted Guides → Useful Functions and Hacks When Using S2member w/ BuddyPress
Useful Functions and Hacks When Using S2member w/ BuddyPress

Hey there guys, i』m working on a website where i』m integrating s2member functionality with buddypress. I thought some of the things I』ve come across may be useful to other people.
1. Filter Users Displayed in Members Directory by s2member role.
In your plugins/buddypress/bp-templates/bp-legacy/buddypress/members/ folder edit the file 「members-loop.php」. Just under
at the top 20 lines of the file we need to write some PHP code to build a comma separated list of ID』s based on the s2member role or roles that we want. In my case I wanted only members of 「s2member_level2″.
It is recommended to only ever edit a copy of template file that you have copied over to your theme or child theme otherwise your changes will be overwritten on updates.
$args = array('role' => 's2member_level2', 'fields' => array('id'));
// The User Query
$user_query = new WP_User_Query( $args );
$custom_ids = '';
for($i = 0;$i results); $i++){
$a = $user_query->results[$i]->id;
$custom_ids .= $a.",";
}

Now that we』ve made a comma separated string of ids ($custom_ids), we need to pass it to the members loop.
Change
if(bp_has_members( bp_ajax_querystring( 'members' ) ) ) :
to
if(bp_has_members('per_page=30&type=alphabetical&'.'include='.$custom_ids ) ) :
In my case I wanted to make sure at most 30 members showed up, and that they were in alphabetical order.
Done.
2. Importing s2member custom fields to buddypress fields
You may be asking; why??? Well, it turns out that when you have the s2member option to integrate with buddypress it doesn』t actually import it』d data to the buddypress tables. It just binds it』s self to the 『Base』 group, Which will show up by default in buddypress profiles. When it doesn』t import to the buddypress tables, it was very difficult for me to manipulate how the information showed up. Particularly the fact that I have the users give me their address information, and I don』t want that to even be an option to show in user profiles.
So instead of using s2member to integrate automatically, I wrote a function that would check a users information when they login. If they have certain information in s2member that is not in their BP Profile, it will add it automatically.
Option 1:
in functions.php add the code:
<?php

add_action('wp_head','s2_profile_field_update',10,2);
function s2_profile_field_update() {
global $current_user;
get_currentuserinfo();
if(current_user_is("s2member_level2")){
if(get_user_field("s2member_login_counter") id) == '' && get_user_field('nationality') != '') {
xprofile_set_field_data('Nationality', $current_user->id, get_user_field('nationality'));
}

if(xprofile_get_field_data('Age', $current_user->id) == '' && get_user_field('age') != '') {
xprofile_set_field_data('Age', $current_user->id, get_user_field('age'));
}

if(xprofile_get_field_data('School', $current_user->id) == '' && get_user_field('school') != '') {
xprofile_set_field_data('School', $current_user->id, get_user_field('school'));
}
}
}
}

?>
You can change Nationality to what ever the name is of the extended BP field (in users>profile fields).
And of course you can duplicate the if statements for how every many fields you want to import from s2memeber -> BP.
Also note that if(get_user_field("s2member_login_counter") < 1000) mean』s that this process will run for any user that logs in with membership role s2member_level2 and has logged in less than 1000 times. I used 1000 times because I want any member at this moment who logs in to have their profiles populated. In the future I will drop it down to 1 or 2.
Alternatively we could use a for loop in order to make any later changes a bit simpler:
// Function to populate BP Profile Fields w/ S2member Fields.
add_action('wp_head','s2_profile_field_update',10,2);
function s2_profile_field_update() {
global $current_user;

//Array of xprofile field names
$xprofile_fields = array('Nationality','Age','School');

//Array of s2member field slugs
$s2member_fields = array('nationality','age','school');

get_currentuserinfo();
if( current_user_is("s2member_level2") ) {
if(get_user_field("s2member_login_counter") < 1000)
{
for($i = 0; $i id) == '' && get_user_field($s2member_fields[i]) != '' )
{
xprofile_set_field_data($xprofile_fields[i], $current_user->id, get_user_field($s2member_fields[i]) );
}
}
}
}
}

Option 2: Suggested by @shanebp
Instead of checking for login count, and binding the function to 『wp_head』 which will run on every page load, it would be more resource efficient to bind the function to the 『wp_login』 action which will run once; when the user logs into the site. If you want to get really technical – which the computer engineer in me always does – you could argue that the process has been reduced from a time complexity of O(n) to O(n/n) = O(1) where n = the # of page loads from the user. A simple but substantial modification. Rock On @shanebp!
add_action('wp_login','s2_profile_field_update',10,2);
function s2_profile_field_update()
{
global $current_user;
get_currentuserinfo();
if( current_user_is("s2member_level2") )
{
if(xprofile_get_field_data('Nationality',$current_user->id) == '' && get_user_field('nationality') != '')
{
xprofile_set_field_data('Nationality', $current_user->id, get_user_field('nationality'));
}
}
}
I』ll post more as I gather it. But in the mean time I hope this helps some people.
M

移动设备 (Mobile)

移动设备 (Mobile)

Codex Home → Mobile
Mobile

BuddyPress should work on most mobile smartphone browsers in the same manner it works on desktop browsers. However, you can optimize the mobile experience in a few different ways.
Responsive Themes
Responsive web design or responsive themes are themes that shift its layout depending on the available screen size of the device someone has used to access a site. This makes the viewing experience greatly improved with minimal panning, zooming and scrolling.
BuddyPress works on most themes out of the box even with responsive themes. That being said, the template files for BuddyPress are not 100% responsive. Since every theme has it』s own varying CSS there would be no way to force a set responsiveness to the BuddyPress template files for every available theme. You can always add your own template files and CSS to BuddyPress to enhance the responsiveness.
There are many free and paid responsive WordPress themes available to install.
Web Apps
Web apps are applications that use a web browser as the client and are not installed locally. This has the advantage of supporting more devices especially when most smartphone mobile browsers support current advancements in web technology.
One of the characteristics of web apps is that there are no full page refreshes making it seem like everything happens in one window with a snappier response. Data is generally accessed from a REST API and then a javascript based web app updates the browser with returned data. BuddyPress currently has no official mobile web apps.
Mobile Plugins
There are a handful of WordPress plugins to switch out your theme to a fully responsive/web app type theme. These can be the best and easiest solution to format your site on the myriad of available devices. BuddyPress currently has no official mobile theme plugins.
Mobile Plugins:

WPTouch: 3rd Party Developer  https://wordpress.org/plugins/wptouch
BuddyMobile: 3rd Party Developer https://wordpress.org/plugins/buddymobile
Jetpack Mobile Theme: Automattic https://wordpress.org/plugins/jetpack
AppPresser: 3rd Party Developer https://wordpress.org/plugins/apppresser

Native Apps
Native apps are installed locally per device. Normally you would visit an App Store from one of the mobile OS venders to install apps. If you were to create a mobile app you would need to create a different native app for each smartphone vendor just like the mobile apps for WordPress. This can be seen as disadvantages for developers. BuddyPress currently has no official native apps.
Native Mobile Apps:

BuddyDroid: 3rd Party Developer https://play.google.com/store/apps/details?id=org.yuttadhammo.buddydroid

BuddyPress API
BuddyPress currently has no official API for external communication. There are a few 3rd Party API plugins. These may not be up to date or working. Use at your own discretion.
API Plugins:

JSON API for BuddyPress: 3rd Party Developer https://wordpress.org/plugins/json-api-for-buddypress
BuddyData: 3rd Party Developer https://github.com/modemlooper/BuddyData
BuddyPress API: 3rd Party Developer https://github.com/boonebgorges/buddypress-api

BuddyPress 用您的语言

BuddyPress 用您的语言

Codex Home → Getting Started → Customizing → BuddyPress in Your Language
BuddyPress in Your Language

Like WordPress, BuddyPress has the built in capability to be used in any language. The instructions below assume you have already configured WordPress in Your Language and Installing WordPress in Your Language.
Like WordPress, you don』t have to lift a finger to apply BuddyPress translations or translation updates. Most sites are now able to automatically apply these updates in the background. If your site is capable of one-click updates without entering FTP credentials, then your site should be able to automatically update translations.
Is your language missing?
BuddyPress translation packages are only updated if the translation is at 100% translated, if you do not see your language after updating your translations, please consider contributing to the the BuddyPress translation project, to get started see Translating WordPress and post any questions you have on the WordPress Polyglots blog.
Getting the language files
Go to https://translate.wordpress.org/projects/wp-plugins/buddypress and select your preferred language e.g. Hungarian
Select 『all current』 as 『.po』 and click 『export』 and save this file to a folder on your computer, do the same again this time selecting 『.mo』
Using the language files
Rename each file of the files to buddypress-language_COUNTRY.extension
eg.
wp-plugins-buddypress-stable-hu.po to buddypress-hu_HU.po and
wp-plugins-buddypress-stable-hu.mo to buddypress-hu_HU.mo
Using FTP upload both the .po and .mo files to /wp-content/languages/ of your WordPress instalation. If the /wp-content/languages/ folder does not exist, create it.

将自定义过滤器添加到循环中并在您的插件中使用它们

将自定义过滤器添加到循环中并在您的插件中使用它们

Codex Home → BuddyPress Plugin Development → Add custom filters to loops and enjoy them within your plugin
Add custom filters to loops and enjoy them within your plugin

BuddyPress uses loops to display the content of its components. In this article you will focus on how to 「rearrange」 the content displayed in four of its major components : Members, Groups, Blogs and finally Activity. You will achieve this thanks to the type or action argument of the init functions of each of these loops :

Loops
Init functions
Locations

Members
bp_has_members( array( $arguments ) )
/bp-activity/bp-activity-template.php

Groups
bp_has_groups( array( $arguments ) )
/bp-groups/bp-groups-template.php

Blogs
bp_has_blogs( array( $arguments ) )
/bp-blogs/bp-blogs-template.php

Activity
bp_has_activities( array( $arguments ) )
/bp-activity/bp-activity-template.php

To let members of a BuddyPress powered community change the way items of loops are displayed, BuddyPress uses select boxes that includes the different types to reorder the members, groups or blogs and filter the activity stream to only keep the desired action (or activity type). These select boxes are generally available from the directory page of the component, and in the specific case of the activity component : in single group and member home page.
In the following tutorial, you will first extend the available filters of the Members, Groups and Blogs loops, then you will remember how to add custom actions (or activity types) to the Activity component for your plugin, finally you will build a great feature thanks to a very interesting Activity Meta Query.
Here』s your roadmap

Add a custom filter to the Members, Groups and Blogs loops
Extend the activity types to register your plugin ones
Build a new great feature thanks to the 『favorite an activity』 functionality
Additional resources

In additional resources, you will find an example of plugin that includes all the codes that this tutorial contains. If you wish, you can activate the plugin in a local dev environment to follow the different steps of this article.
Add a custom filter to the Members, Groups and Blogs loops
To illustrate the process, you are going to use a built in filter type that is not activated by default in loops : the 「random」 order one. This screenshot shows the result of your first lines of code for the Members component.
The random filter in Members directory
If you dive into BuddyPress /bp-templates/bp-legacy/buddypress folder, you will find 3 templates that are used to display the directory pages for the 3 components you』re dealing with in this first step:

Templates
Hooks
Lines

/bp-templates/bp-legacy/buddypress/members/index.php
do_action( 'bp_members_directory_order_options' );
44

/bp-templates/bp-legacy/buddypress/groups/index.php
do_action( 'bp_groups_directory_order_options' );
44

/bp-templates/bp-legacy/buddypress/blogs/index.php
do_action( 'bp_blogs_directory_order_options' );
42

So all you need to do in order to set the 「random」 filter is to add an action to these three hooks. Let』s init your plugin』s class and write the lines that will render the above screenshot』s result.
?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465setup_actions();    }     /**     * Actions     *     * @uses bp_is_active()     * @uses is_multisite()     */    private function setup_actions() {        /**         * Adds the random order to the select boxes of the Members, Groups and Blogs directory pages         */        // Members component is core, so it will be available        add_action( 'bp_members_directory_order_options', array( $this, 'random_order' ) );         // You need to check Groups component is available        if( bp_is_active( 'groups' ) )            add_action( 'bp_groups_directory_order_options',  array( $this, 'random_order' ) );         // You need to check WordPress config and that Blogs Component is available        if( is_multisite() && bp_is_active( 'blogs' ) )            add_action( 'bp_blogs_directory_order_options',   array( $this, 'random_order' ) );    }     /**     * Displays a new option in the Members/Groups & Blogs directories     *     * @return string html output     */    public function random_order() {        ?>                prefix}bp_activity MySQL table */        'bp_plugin',        /* your component's activity type :        - same value as the "type" field you will use in the {$wpdb->prefix}bp_activity MySQL table        - it will be used in the value attribute of the plugin option in the activity selectbox        */        'bpplugin_action',        /* your component's caption :        - it will be displayed to the user in the activity selectbox        */        __( 'BP Plugin Action' )    );}
Once you』ve added these lines, when opening the Activity Administration screen, you will find your plugin』s filter inside the available choices of the select box as shown in the following screen capture.
BP Plugin Action filter in Activity Administration screen
Back to front end! You can take a new swim into the BuddyPress /bp-templates/bp-legacy/buddypress folder to find the key actions to hook to in order to add your custom activity type(s).

Templates
Hooks
Lines

/bp-templates/bp-legacy/buddypress/activity/index.php
do_action( 'bp_activity_filter_options' );
110

/bp-templates/bp-legacy/buddypress/members/single/activity.php
do_action( 'bp_member_activity_filter_options' );
55

/bp-templates/bp-legacy/buddypress/groups/single/activiy.php
do_action( 'bp_group_activity_filter_options' );
20

Before rushing into the process of using these hooks, you are going to build a transition function to get the list of activity types you』ve created. As you have only one activity type so far, you may think it』s not necessary but i personaly consider it as a good way to not forget the Administration screens of the Activity component. Moreover, you will soon add a new activity type for the final step. You need to edit your plugin』s class by adding a new function to list the activity actions.
?1234567891011121314151617181920212223/** * Building an array to loop in from the display function * * Using bp_activity_get_types() will list all registered activity actions * but you need to get the ones for your plugin, and this particular function * directly returns an array of key => value. As you need to filter activity * with your component id, the global buddypress()->activity->actions will be * more helpful. * * @uses buddypress() * @return array the list of your plugin actions. */private function list_actions() {     $bp_activity_actions = buddypress()->activity->actions;     $bp_plugin_actions = array();     if( !empty( $bp_activity_actions->bp_plugin ) )        $bp_plugin_actions = array_values( (array) $bp_activity_actions->bp_plugin );     return $bp_plugin_actions;}
Now you can use the 3 hooks previously identified by adding some code into the setup_actions() function of your plugin』s class, just after the code that hooks 'bp_register_activity_actions'.
?12345678// Adds a new filter into the select boxes of the Activity directory page,// of group and member single items activity screensadd_action( 'bp_activity_filter_options',        array( $this, 'display_activity_actions' ) );add_action( 'bp_member_activity_filter_options', array( $this, 'display_activity_actions' ) ); // You need to check Groups component is availableif( bp_is_active( 'groups' ) )    add_action( 'bp_group_activity_filter_options', array( $this, 'display_activity_actions' ) );
You will also need to create the function display_activity_actions() to build the different new options that will populate the select boxes. This function will use the transition function to get the activity types of your plugin.
?123456789101112131415161718/*** Displays new actions into the Activity select boxes* to filter activities* - Activity Directory* - Single Group and Member activity screens** @return string html output*/public function display_activity_actions() {    $bp_plugin_actions = $this->list_actions();     if( empty( $bp_plugin_actions ) )        return;     foreach( $bp_plugin_actions as $type ):?>        <option value="">    <?php endforeach;}
Now you can check the result of your work by displaying the Activity Directory, a member』s home page and a group』s home page. Here』s a screenshot for the Activity Directory.
BP Plugin action filter in Activity Directory
As you can see, the new option is available, and you can filter the activities to only get the activities that will be generated by your plugin. You only need to build the functions that will actually write new activities as explained in the codex article 『Posting Activity from Plugins』.
Build a new great feature thanks to the favorite an activity functionality
In BuddyPress, there』s a feature to let members favorite some activities so that they can easily find the activities they are really interested in from the 「My Favorites」 tab of the Activity directory or from the one of their profile home page. And reading the above lines gave you a great idea! You think the community would really appreciate to quickly see what are the most favorited activities by all members. In a way and thanks to this new feature, members would be able to easily know what are the ones they should absolutely read. And you will see that displaying these most favorite activities in the different screens will have different new powerful meanings.
First, let』s extend the register_activity_actions() function of your class to add a new very particular activity type. It actually won』t behave like a regular one. Its goal won』t be to display a particular type of activities as any type can be favorited. Using this new filter will perform two other things : only the favorited activities will be displayed and this display will be ordered regarding the number of times an activity has been favorited. So for this reason, you will not make this filter available from the Administration screen of Activities.
?12345/* Activity Administration screen does not use bp_ajax_querystringMoreover This action type is reordering instead of filtering so you will onlyuse it on front end */if( !is_admin() )    bp_activity_set_action( 'bp_plugin', 'activity_mostfavs', __( 'Most Favorited' ) );
That』s all we have to do to add this new type to the select boxes as your function list_actions() will automatically returns it to the function display_activity_actions(). You now need to handle this new filter type by intercepting it when the init function of the Activity loop will be run. If you open the template /bp-templates/bp-legacy/buddypress/groups/single/activity-loop.php, you』ll notice that the loop is using a function as an argument of this init function :

bp_ajax_querystring() plays a key role in the way that BuddyPress gets user inputs in order to render the appropriate display of the Activity loop. Just before returning these inputs, the function offers a filter so that you can get them and eventually edit them. You are going to use this filter, but not too early to let BuddyPress actually build the loop arguments, so you will choose a priority greater than 10, let』s say 12. You need to edit the constructor of your class so that it includes a new call to the function that will contain all your filters. This is the new constructor of your plugin :
?123456789101112class BP_Loop_Filters {     /**     * Constructor     */    public function __construct() {        $this->setup_actions();        // simply add the following line to your constructor        $this->setup_filters();    } }
Once the constructor edited, you will create the setup_filters() function and begin it by adding the 'bp_ajax_querystring' filter at a priority of 12. You also need to inform WordPress that your function is expecting to receive the two arguments available for this filter : the querystring and the object it relates to. That』s why there is the number 2 after the priority argument.
?123456/** * Filters */private function setup_filters() {    add_filter( 'bp_ajax_querystring', array( $this, 'activity_querystring_filter' ), 12, 2 );}
The filter is in place, it』s now time you take care of building the function that will make eveything possible for your need. This is activity_querystring_filter() :
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748/** * Builds an Activity Meta Query to retrieve the favorited activities * * @param  string $query_string the front end arguments for the Activity loop * @param  string $object       the Component object * @uses   wp_parse_args() * @uses   bp_displayed_user_id() * @return array()|string $query_string new arguments or same if not needed */public function activity_querystring_filter( $query_string = '', $object = '' ) {    if( $object != 'activity' )        return $query_string;     // You can easily manipulate the query string    // by transforming it into an array and merging    // arguments with these default ones    $args = wp_parse_args( $query_string, array(        'action'  => false,        'type'    => false,        'user_id' => false,        'page'    => 1    ) );     /* most favorited */    if( $args['action'] == 'activity_mostfavs' ) {        unset( $args['action'], $args['type'] );         // on user's profile, shows the most favorited activities for displayed user        if( bp_is_user() )            $args['user_id'] = bp_displayed_user_id();         // An activity meta query 🙂        $args['meta_query'] = array(            array(                /* this is the meta_key you want to filter on */                'key'     => 'favorite_count',                /* You need to get all values that are >= to 1 */                'value'   => 1,                'type'    => 'numeric',                'compare' => '>='            ),        );         $query_string = empty( $args ) ? $query_string : $args;    }     return apply_filters( 'bp_plugin_activity_querystring_filter', $query_string, $object );}
Let』s take a minute to understand what happens in it. The 2 arguments are waiting for the filter values and default to an empty string. Then, the very first thing to do is to make sure the activity loop is about to be run as BuddyPress also uses this function for the Members, Groups, legacy user group forums, Blogs and private messages. In other words, if 'activity' is not the value of the object argument, then just return the current query string without editing it.
The query string you will receive is actually a query string! so the arguments will look like 'arg1=1&arg2=2'. I advise you to use the function wp_parse_args() to quicky get an array of arguments : that will be a lot more easy to manipulate. Now you can check the action or type argument (which are carrying the same values) to see if it matches your most favorited activity type. If so, you can unset this values to include all types of activities.
If you are in a user』s profile, let』s only keep the activities for the user displayed to be consistent as the most favorited activity type will also be available in the select box of member』s home page. And, this is my favorite part, you will build an Activity Meta Query to include all the activities that have a meta value over 1 for the meta key 'favorite_count'.
If you want to know more about Meta Queries, you』ll find in additional resources a link to the article dealing with Group Meta Queries and a link to the WordPress codex on the WP_Meta_Query class. Finally you simply need to replace the value of the query string with your $args array.
So far, you are getting the favorited activities by all users when the Most Favorited filter is selected by the member, you need to bring the final touch, the one that often makes the difference for your plugin. You need to edit the order of the loop so that it will display the favorited activities from the more favorited one to the less favorited one. To achieve that step, you will need to put your ninja warrior suit on! Let』s add a new filter into the setup_filters() function of your class.
This is your new setup_filters() function :
?1234567/** * Filters */private function setup_filters() {    add_filter( 'bp_ajax_querystring',              array( $this, 'activity_querystring_filter' ), 12, 2 );    add_filter( 'bp_activity_get_user_join_filter', array( $this, 'order_by_most_favorited' ),     10, 6 );}
This filter will get the query that is sent to the Activity loop to first edit the field it』s ordered by. Then as the bp_activity_meta table will be joined in the query thanks to your Activity Meta Query. Let』s enjoy it to the max, by also adding a new field that will alias the meta value field for the favorite_count meta key. Doing so the global $activities_template will include this value and it will be very easy to get it for each entry of the loop. The function order_by_most_favorited() will get the 6 arguments available for the 'bp_activity_get_user_join_filter' filter. The most important is the first one as it』s the sql query. Others are part of this query to help you edit the main query.
?123456789101112131415161718192021222324252627282930313233343536/** * Ninja Warrior trick to reorder the Activity Loop * regarding the activities favorite count * * @param  string $sql        the sql query that will be run * @param  string $select_sql the select part of the query * @param  string $from_sql   the from part of the query * @param  string $where_sql  the where part of the query * @param  string $sort       the sort order (leaving it to DESC will be helpful!) * @param  string $pag_sql    the offset part of the query * @return string $sql        the current or edited query */public function order_by_most_favorited( $sql = '', $select_sql = '', $from_sql = '', $where_sql = '', $sort = '', $pag_sql = '' ) {        preg_match( '/'favorite_count' AND CAST((.*) AS/', $where_sql, $match );         if( !empty( $match[1] ) ) {                $new_order_by = 'ORDER BY '. $match[1] .' + 0';            $new_select_sql = $select_sql . ', '. $match[1] .' AS favorite_count';             $sql = str_replace(                array( $select_sql, 'ORDER BY a.date_recorded' ),                array( $new_select_sql, $new_order_by ),                $sql            );             /**             * To help you build the pattern to search for             * you can use the var_dump function to see the             * query that will be performed             * var_dump( $sql );             */         }         return $sql;}
As you can see, you need to get the table name that the Activity Meta Query will build to use it to define you new ORDER BY clause and to include your favorite_count alias field into the SELECT clause.
The very last step is to finally display the favorite count into the entry template of the Activity component. If you explore the BuddyPress /bp-templates/bp-legacy/buddypress folder, in the activity/entry.php template, you will find the 'bp_activity_entry_meta' hook which can be a nice place to add your mention about the number of times the activity has been favorited. So to insert this mention, you simply need to edit your plugin』s setup_actions() function to add an action to this hook and build the function that will be run.
?1234567891011121314151617181920212223242526272829303132private function setup_actions() {    /**     * previous steps code     */    if( bp_is_active( 'activity' ) ) {         /**         * previous steps code         */         // You're going to output the favorite count after action buttons        add_action( 'bp_activity_entry_meta', array( $this, 'display_favorite_count' ) );    } } /** * Displays a mention to inform about the number of times the activity * was favorited. * * @global BP_Activity_Template $activities_template * @return string html output */public function display_favorite_count() {    global $activities_template;     $fav_count = !empty( $activities_template->activity->favorite_count ) ? $activities_template->activity->favorite_count : 0;     if( !empty( $fav_count ) ):?>        <a name="favorite-">    <?php endif;}
If you observe the result of a 「Most favorited」 filter into the main Activity Directory, you will see that only the favorited activities are displayed ordered by the number of times they had been favorited.
Most Favorited in Activity directory
If you do the same on the user』s profile home page, the filter will inform on his activities : the ones that has been favorited by him or other users. So it can be interested for a user to see the interest of his activities for the community.
Most favorited in member』s home page
If you display this filter into a group home page, it will list the group activities that were favorited by its own members in case of a non public group and potentially all community members for a public group.
Most favorited in a group home page

Additional resources

All the codes of this tutorial packaged in a plugin
The Members Loop in BuddyPress Codex
The Groups Loop in BuddyPress Codex
The Blogs Loop in BuddyPress Codex
The Activity Loop in BuddyPress Codex
WP_Meta_Query in WordPress codex
Group Meta Queries: Usage Example in BuddyPress Codex
Posting Activity from Plugins in BuddyPress Codex
bp_ajax_querystring in BuddyPress codex

bp_activity_set_action()

bp_activity_set_action()

Codex Home → Developer Resources → Function Examples → bp_activity_set_action()
bp_activity_set_action()

bp_activity_set_action() is used to set activity actions. bp_activity_set_action() should only be invoked through the 『bp_register_activity_actions』 action.
Usage
function custom_plugin_register_activity_actions() {
// Your plugin is creating a custom BuddyPress component
$component_id = 'plugin_component_id';
// You can also use one of the BuddyPress component
// $component_id = buddypress()->activity->id;

bp_activity_set_action(
$component_id,
'plugin_action',
__( 'Did a plugin action', 'plugin-domain' ),
'plugin_format_activity_action_plugin_action',
__( 'Plugin actions', 'plugin-domain' ),
array( 'member' )
);
}
add_action( 'bp_register_activity_actions', 'custom_plugin_register_activity_actions' );

Parameters

$component_id

The unique string ID of the component the activity action is attached to. Possible values can be one of the BuddyPress optional components or an optional component the plugin is creating :

'activity'
'blogs'
'friends'
'groups'
'members'
'xprofile'
'plugin_component'

$type

A string that describes the action type and that is used in the front-end and in the Activity Administration screens as the value of the activity dropdown filters. For instance the Activity component has two actions :

'activity_update'
'activity_comment'

$description

A string that describes the action description and that is used in the Activity Administration screens as the label of the activity dropdown filters. For instance the corresponding descriptions of the two action types of the Activity component are :

__( 'Posted a status update', 'buddypress' )
__( 'Replied to a status update', 'buddypress' )

$format_callback

A callable function for formatting the action string. For instance the corresponding callback functions of the two action types of the Activity component are :

'bp_activity_format_activity_action_activity_update'
'bp_activity_format_activity_action_activity_comment'

$label

A string that describes the action label of the activity front-end dropdown filters. For instance the corresponding labels of the two action types of the Activity component are :

__( 'Updates', 'buddypress' )
__( 'Activity Comments', 'buddypress' )

$context

An optional array that describes the Activity stream contexts where the filter should appear. Possible values are :

'activity': to display the action into the dropdown filters of the Activity directory.
'member': to display the action into the dropdown filters of the Member』s activity page (by default the home page).
'member_groups': to display the action into the dropdown filters of the Member』s groups activity page.
'group': to display the action into the dropdown filters of the group』s activity page (by default the home page).

$position

An optional integer that describes the position of the action when listed in dropdown filters. Actions are first sorted by their attached components. This argument will sort the list of actions for each component.

Return value
Boolean: true on success, false otherwise.
Source File
bp_activity_set_action() is located in bp-activity/bp-activity-functions.php
Change Log

2.2.0: It will be possible to sort the activity actions within their attached component.
2.1.0: Activity dropdown filters are dynamically generated instead of hardcoded into templates. See function bp_activity_show_filters()
2.0.0: activity action strings are generated dynamically, rather than stored statically. This means that the data is always up-to-date for a better compatibility with multilingual sites
Since 1.1.0

Notes
Since BuddyPress 2.1.0 custom templates or BuddyPress themes can use the function bp_activity_show_filters() instead of hardcoding the options into the following templates :

activityindex.php: use
groupssingleactivity.php: use
memberssingleactivity.php: use

网站礼仪规则

网站礼仪规则

Codex Home → Site Etiquette
Site Etiquette

What follows are the 「rules of etiquette」 for BuddyPress.org, and can be summed up as 「being cool」 which is a good way to be anyhow, particularly if you appreciate the Fonz.
1. Be cool. This means respect the other users of this site and mind what you say. If you wouldn』t walk into your grandmothers house and say to her bridge club what you feel you want to say here, probably filter it down and sensor yourself just a smidge. Not that we can』t take the heat (or gramma can』t either), but it just isn』t productive.
2. Stay on topic. Naturally conversations die off and people run out of things to say. When that happens, hop onto your activity stream and start shouting to the world there instead. The forums are explicitly for supporting and helping develop BuddyPress, and anything else gets in the way of that.
3. Moderators on duty. If things get out of hand, we have a volunteer staff of gentle giants that can still be angered. They』re like hybrid Terminator/Frankenstein/Zombies that, while kind and mild mannered, are chomping at the bit to mark you as a spammer.
4. Do not feed the animals. If someone is bullying you or someone else around or just starting fires randomly, ignore them and ping one of the moderators. These forums are meant to be fun for people of all ages and skill levels; so be kind, rewind.
5. No put downs. Or else you won』t get milk at lunch. If you do get milk, and if the arrow on your carton is pointing at someone, that means you love them. And yes, if it』s pointing at yourself, that means you love yourself.
We want everyone to feel welcome, comfortable, and appreciated. In order to do that it seems we』ve gotten to the point where it will pay to have some loose rules to refer people to if things go awry. If you do your best to follow this guide, there will be cake.

来自插件的模板重载

来自插件的模板重载

Codex Home → BuddyPress Plugin Development → Template Overload from a Plugin
Template Overload from a Plugin

Note: overloading and / or adding templates from plugins can be quite complex. For more detailed discussion and examples, please see:

Upgrading older plugins that bundle custom templates for BP 1.7
Using BP Theme Compat in Plugins
Theme Compatibility & Template Files

The purpose of this page is to provide a simple example of overloading an existing template part. The example shown will allow you to overload the member-header.php file which creates the BuddyPress profile page header section (avatar, messaging buttons, profile navigation menu etc.) for profile pages where cover images are not used. If you are using cover images on the users profile then the file to overload is cover-image-header.php. Both of these files are located in plugins/buddypress/bp-templates/bp-legacy/members/single.
If you』re using BP 1.7 or greater and not using the bp-default theme, you can use this approach…
It consists of 2 files and a template folder structure:

loader.php
bp-tol.php
templates/members/single/member-header-tol.php

loader.php
/*
Plugin Name: BP Template Overload
Plugin URI: http://philopress.com
Description: Load templates from a plugin
Version: 1.0
Author: shanebp
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/

if ( !defined( 'ABSPATH' ) ) exit;

function bp_tol_init() {

define( 'BP_TOL_DIR', dirname( __FILE__ ) );

require( BP_TOL_DIR . '/bp-tol.php' );

}
add_action( 'bp_include', 'bp_tol_init' );

bp-tol.php
// register the location of the plugin templates
function bp_tol_register_template_location() {
return BP_TOL_DIR . '/templates/';
}

// replace member-header.php with the template overload from the plugin
function bp_tol_maybe_replace_template( $templates, $slug, $name ) {

if( 'members/single/member-header' != $slug )
return $templates;

return array( 'members/single/member-header-tol.php' );
}

function bp_tol_start() {

if( function_exists( 'bp_register_template_stack' ) )
bp_register_template_stack( 'bp_tol_register_template_location' );

// if viewing a member page, overload the template
if ( bp_is_user() )
add_filter( 'bp_get_template_part', 'bp_tol_maybe_replace_template', 10, 3 );

}
add_action( 'bp_init', 'bp_tol_start' );

member-header-tol.php
Make a copy of
buddypress/bp-templates/bp-legacy/buddypress/members/single/member-header.php
rename it and make some small change so that it』s obvious that it』s being loaded.
Then save it in the folder structure shown above.

That』s it !
And you can overload member-header-tol.php by placing a copy in your child-theme directory: [theme]/buddypress/members/single/member-header-tol.php

BP PHPDoc 内联文档

BP PHPDoc 内联文档

Codex Home → Developer Resources → BP PHPDoc Inline Documentation
BP PHPDoc Inline Documentation

Introduction
BuddyPress strives for the most complete internal documentation possible. When contributing patches to BuddyPress, you are highly encouraged to document your code using our standards. We also welcome patches that provide new documentation, or correct/amend existing documentation.

Standards
BuddyPress』s documentation is based on WordPress』s PHP Documentation Standards. Familiarize yourself with that document before continuing with this guide.
There are a number of ways in which BuddyPress』s standards differ from WordPress』s. They are listed below. For any aspect of inline PHP documentation not specifically discussed here, you can assume that we are doing things the WordPress way.

BuddyPress-specific standards

Short description For consistency, short descriptions should be written as imperatives: 「Fetch a piece of metadata about a group」 rather than 「Fetches a piece of metadata….」