会员类型

会员类型

Codex Home → Developer Resources → Member Types
Member Types

BuddyPress 2.2 introduced the concept of member types. This functionality is outlined below.
Registering member types
BuddyPress itself does not register any member types. Plugins and themes can register member types using the bp_register_member_type() or the bp_register_member_types() function:
function bbg_register_member_types() {
bp_register_member_type( 'student', array(
'labels' => array(
'name' => 'Students',
'singular_name' => 'Student',
),
) );
}
add_action( 'bp_register_member_types', 'bbg_register_member_types' );

The first parameter of bp_register_member_type() is a string identifier for the member type, used internally by BP as the canonical name of the type. This name should be unique. The second parameter is a list of generic config arguments.
As of BP 2.2, only the 『labels』 parameter is supported. Future versions of BuddyPress will add additional parameters for better customization and development.
Registering a member type will also enable a meta box so administrators can set a member』s type when editing a user』s 「Extended Profile」 in the WP admin dashboard.
Member Specific Directory
BuddyPress 2.3 introduces the member-type-specific directories. It adds the new 『has_directory』 argument for bp_register_member_type() allowing developers to specify whether a list of members matching a given type 『foo』 should be available at http://example.com/members/type/foo/. A slug can be passed to 『has_directory』 to customize the URL used for the member type』s directory.
function bbg_register_member_types_with_directory() {
bp_register_member_type( 'student', array(
'labels' => array(
'name' => 'Students',
'singular_name' => 'Student',
),
'has_directory' => 'custom-name'
) );
}
add_action( 'bp_register_member_types', 'bbg_register_member_types_with_directory' );

Note that plugins registering member types must do so at the new hook 『bp_register_member_types』 in order to be able to customize the 『has_directory』 value (from its default of true). bp_has_members() automatically detects the presence of a member type in a URL. When no member type of the form example.com/members/type/foo/ is found, URLs of the form example.com/members/?member_type=foo will be detected.
Querying by member type
A common task is to retrieve a list of members of a given type (or set of types). bp_has_members() and BP_User_Query accept a 'member_type' parameter, which can be a single member type or an array/comma-separated list of member types. This will filter query results to those members matching the type. Example:
// Fetch all students and teachers.
$member_args = array(
'member_type' => array( 'student', 'teacher' ),
);
if ( bp_has_members( $member_args ) ) { // ...

Fetching and setting individuals』 member types
When BuddyPress detects that member types have been registered, it will display a Member Type metabox on the user』s Community Profile in Dashboard > Users. Administrators can use this interface to view or change a user』s member type.
BuddyPress also provides simple functions for fetching and setting member types programatically. To get the member type of a user, use bp_get_member_type():
// Get the member type of user 5412.
$member_type = bp_get_member_type( 5412 );

Set a user』s member type using bp_set_member_type():
// Set the member type of user 5412 to 'student'.
$member_type = bp_set_member_type( 5412, 'student' );

使用 bp_parse_args() 过滤 BuddyPress 模板循环

使用 bp_parse_args() 过滤 BuddyPress 模板循环

Codex Home → Developer Resources → Using bp_parse_args() to filter BuddyPress template loops
Using bp_parse_args() to filter BuddyPress template loops

Prologue
In the past, it has been extremely difficult to filter any BuddyPress template loop.
For example, let』s say I wanted all activity loops to show the last five entries instead of the default of 20. It was possible, but basically you』d either have to requery the activity loop to grab the last five entries and override the 'bp_has_activities' filter or override the activity SQL statement using the 'bp_activity_paged_activities_sql' filter.
Both methods are totally not cool.
Introducing bp_parse_args()!
The introduction of the bp_parse_args() function in BuddyPress 2.0 makes this way simpler. Let』s take a look at the bp_has_activities() loop with the bp_parse_args() function:
https://buddypress.trac.wordpress.org/browser/tags/2.0/bp-activity/bp-activity-template.php#L525
Once you』ve analyzed that a bit, let』s move on to the specific usage of bp_parse_args() in the bp_has_activities() loop:
?1$r = bp_parse_args( $args, $defaults, 'has_activities' );
In particular:

The first argument, $args, are the parameters for the activity loop initially passed by bp_has_activities().
The second argument, $defaults, are some default parameters for the activity loop that are used if the $args variable does not contain them.
The third argument, 'has_activities', is a unique identifier used for this instance of bp_parse_args(). More on this later.

Now that you know how bp_parse_args() is used in bp_has_activites(), let』s analyze the bp_parse_args() function and how we can use this to our advantage.
bp_parse_args() in depth
The bp_parse_args() function can be found here:
https://buddypress.trac.wordpress.org/browser/branches/2.0/bp-core/bp-core-functions.php#L205
In this function, there are two filters:

'bp_before_{$filter_key}_parse_args' – Allows you to filter the initial arguments, $args.
'bp_after_{$filter_key}_parse_args' – Allows you to filter the arguments after $args has been merged with $defaults.

You』re probably wondering what $filter_key is. $filter_key is the third argument from bp_parse_args().
In our case, it is 'has_activities'.
So if I wanted to filter the activity loop parameters, the filters would look like this:

'bp_before_has_activities_parse_args'
'bp_after_has_activities_parse_args'

Now that we』ve taken a look at the bp_parse_args() function and how it applies filters to the arguments. Let』s actually write our override filter!
Filtering bp_parse_args()
Let』s go back to the original issue. I want to filter all activity loops to show only the last five entries instead of the default of 20.
Using the 'bp_after_has_activities_parse_args' filter that we』ve determined above, let』s write our override function:
?1234567// Fetch only the last five entries for all activity loopsfunction my_bp_activities_per_page_5( $retval ) {    $retval['per_page'] = 5;     return $retval;}add_filter( 'bp_after_has_activities_parse_args', 'my_bp_activities_per_page_5' );
So what did we just do? We』re overriding the 'per_page' parameter so only the last five entries are fetched instead of the default of 20. It』s as simple as that!
Note that this overrides all activity loops across BuddyPress. What if I only wanted to fetch the last five entries only on a user』s activity page? Easy, just add your conditionals:
?123456789function my_bp_activities_per_page_5_on_user_activity( $retval ) {    // only fetch the last five entries if we're on a user's activity page    if ( bp_is_user_activity() ) {        $retval['per_page'] = 5;    }     return $retval;}add_filter( 'bp_after_has_activities_parse_args', 'my_bp_activities_per_page_5_on_user_activity' );
You can get uber-creative by filtering all the other parameters in the activity loop:
https://buddypress.trac.wordpress.org/browser/tags/2.2.1/src/bp-activity/bp-activity-template.php#L442
Conclusion
Now that you know how to use the bp_parse_args() function, you should be able to easily filter any BuddyPress template loop!
For convenience, here are the other template loops using bp_parse_args():

Blogs – https://buddypress.trac.wordpress.org/browser/tags/2.2.1/src/bp-blogs/bp-blogs-template.php#L366
Groups – https://buddypress.trac.wordpress.org/browser/tags/2.2.1/src/bp-groups/bp-groups-template.php#L431
Members – https://buddypress.trac.wordpress.org/browser/tags/2.2.1/src/bp-members/bp-members-template.php#L461
Message Threads – https://buddypress.trac.wordpress.org/browser/tags/2.2.1/src/bp-messages/bp-messages-template.php#L372
Notifications – https://buddypress.trac.wordpress.org/browser/tags/2.2.1/src/bp-notifications/bp-notifications-classes.php#L556
XProfile – https://buddypress.trac.wordpress.org/browser/tags/2.0/bp-xprofile/bp-xprofile-template.php#L169

模板中的活动下拉过滤器

模板中的活动下拉过滤器

Codex Home → BuddyPress Theme Development → Activity dropdown filters in templates
Activity dropdown filters in templates

Activity dropdown filters are used in order to let a user filter the activity stream in three main contexts: the activity directory, the single member activity page and the single group activity page.
The Activity directory dropdown filters.

Version 2.1 of BuddyPress introduced the template tag bp_activity_show_filters() to dynamically generate the options of the activity dropdown filters. While the BP Theme compatibility templates are using this function, the BP-Default templates are not since Core Team has decided that no further development on the theme template files will be made. The goal of this article is to show you how you can enjoy this new template tag within your BP-Default child theme.
Use bp_activity_show_filters() within your BP-Default child theme
The three templates that are containing an activity dropdown filters are:

Activity directory: activity/index.php
Single Member activity page: members/single/activity.php
Single Group activity page: groups/single/activity.php

Let』s look at the activity directory template, focusing on the select tag having the css id 「activity-filter-by」:

As you can see, this part is checking if the component is active before displaying its actions which are then hardcoded in the template. If you are using, at least, BuddyPress 2.1 you can edit the templates to use the template tag bp_activity_show_filters() instead of the hardcoded options (except for the first one). Once done, the activity/index.php and members/single/activity.php will have a select tag looking like this:

For the groups/single/activity.php template, the only difference is that the bp_activity_show_filters() template tag is including a context parameter set to 『group』 like this:

Why using bp_activity_show_filters() within your theme』s templates
As soon as you are using at least version 2.1 of BuddyPress, you should consider using this new template tag as it will be used by BuddyPress to create new activity actions for its current (and future) components. BuddyPress plugins might also progressively rely on this template tag as setting activity actions have been greatly improved thanks to the function bp_activity_set_action().

Related Resources

bp_activity_set_action() codex page
Posting activities from plugins, section 「Fully enjoy bp_activity_set_action()」

自定义 BuddyPress 头像

自定义 BuddyPress 头像

Codex Home → BuddyPress Theme Development → User Submitted Guides → Customizing BuddyPress Avatars
Customizing BuddyPress Avatars

The BuddyPress core allows for a number of ways for you to customize the size and appearance of user avatars. In this tutorial we』ll show you which files to edit in order to make changes to avatars. We』ll also walk through several example customizations.
Default BuddyPress Avatar Sizes
Before customizing avatars, it』s important to know the default values. BuddyPress essentially has two sets of avatar sizes:

Thumb – defaults to 50px square
Full – defaults to 150px square

Examples of the 50px thumbnails can be seen in activity stream entries as well as the members/groups directory pages. The full size is used for the avatar displayed on user profile pages.

How to Change BuddyPress Avatar Sizes
BuddyPress allows for changing the default avatar sizes using a constant. These constants are set up in /bp-core/bp-core-avatars.php. If you want to change their values, you will need to create and/or edit your bp-custom.php file. Here are the available options:
define ( 'BP_AVATAR_THUMB_WIDTH', 50 );
define ( 'BP_AVATAR_THUMB_HEIGHT', 50 );
define ( 'BP_AVATAR_FULL_WIDTH', 150 );
define ( 'BP_AVATAR_FULL_HEIGHT', 150 );
define ( 'BP_AVATAR_ORIGINAL_MAX_WIDTH', 640 );
define ( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE', $max_in_kb );

Let』s walk through a few examples. Perhaps you want to increase avatar sizes across the board. Paste the defines for the thumb and full avatar sizes into your bp-custom.php file and change the values to whatever size you want.
define ( 'BP_AVATAR_THUMB_WIDTH', 80 );
define ( 'BP_AVATAR_THUMB_HEIGHT', 80 );
define ( 'BP_AVATAR_FULL_WIDTH', 250 );
define ( 'BP_AVATAR_FULL_HEIGHT', 250 );
?>

You can also change the size of the original image that BuddyPress stores, as well as limit the file size the users can upload. This is a good idea if you don』t want users to upload insanely large files as avatars. Add this to your bp-custom.php file and change the values to suit your needs. These are example values:
define ( 'BP_AVATAR_ORIGINAL_MAX_WIDTH', 800 );
define ( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE', 200 );

How to Change the Default BuddyPress Avatar
The default avatar is the one that appear when a user has not yet uploaded his own avatar. If you』re not a fan of the mystery man, here are the constants that you can use to define your own:
define ( 'BP_AVATAR_DEFAULT', $img_url );
define ( 'BP_AVATAR_DEFAULT_THUMB', $img_url );

Change the the constant to include the URL for the location of your new default avatars and add this to your bp-custom.php file.
define ( 'BP_AVATAR_DEFAULT', 'http://example.com/default-avatar.jpg' );
define ( 'BP_AVATAR_DEFAULT_THUMB', 'http://example.com/default-avatar-thumb.jpg' );

To use a default avatar without Gravatar you should also add:
add_filter( 'bp_core_fetch_avatar_no_grav', '__return_true' );

To continue using Gravatar you should add:
add_filter( 'bp_core_avatar_default', function() {
return BP_AVATAR_DEFAULT;
} );

How to Customize BuddyPress Avatars With CSS
When using CSS to manipulate BuddyPress avatars, the most important thing to remember is that you always want to size down from the full or the thumbnail size. If you use CSS to try to size avatars up to a larger size, you will get fuzzy, distorted avatars.
The default BuddyPress theme adds 『avatar『 class to BuddyPress avatars. You can target this class within your BuddyPress child theme in order to make customizations to avatars. For example, let』s say that you want to make all the avatars circles. You might add something like this to your theme』s stylesheet:
img.avatar {
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
-webkit-box-shadow: 0 1px 0 #fff;
-moz-box-shadow: 0 1px 0 #fff;
box-shadow: 0 1px 0 #fff;
}

All of your BuddyPress avatars will now be circular:

Using Firebug you can determine even more specific classes to target. For example, if you only wanted to change the shape of the main avatar on user profile pages, you could target it using the div#item-header-avatar img.avatar selector instead.
If you implement circular avatars, you may also want to change the shape of the crop pane that is displayed when users are uploading and cropping a new avatar. This CSS, added to your child theme, will change the crop pane to be a circle so that users can accurately preview the new avatar:
#avatar-crop-pane { border-radius: 50%; }

The result will look something like this:

Please note that these examples are applicable to a child theme of the default BuddyPress theme. If you』re working with another theme, the classes may be different but the process is the same.
How to Disable Avatar Uploads
Disabling avatar upload for your BuddyPress site is very easy. Navigate to Dashboard >> Settings >> BuddyPress >> Optionss tab and uncheck the box that says 「Allow registered members to upload avatars」.

Disabling uploads will still allow for Gravatars. Support for this service is built in, so your users can still have avatars. While disabling avatar upload limits users』 ability to customize their profiles, the advantage for you is that Gravatar hosts all of the avatars.

bp_activity_add()

bp_activity_add()

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

bp_activity_add() is used to insert new activity items into the database.
Usage
$activity_id = bp_activity_add( $args );

Parameters

$args
An array that describes the activity item that you』re creating. Possible values:

'id'
(optional) Pass a numerical id to update an existing activity item
'action'
An HTML string summarizing the activity item, which is used by the template when displaying the activity item. Usually contains links to related users, groups, etc. E.g., 'Bill created the group TMNT'
'content'
(optional) The string content of the activity item. In the case of a blog post, for example, you might use an excerpt from the post content. In some cases, it』s appropriate for activity items not to have any content for this field – e.g., when a user creates a new group.
'component'
A string denoting the unique 「component」 that this activity item is associated with. BuddyPress components are 『groups』, 『members』, etc. If you are writing a BuddyPress plugin, you might consider having a single component name for all activity in your plugin.
'type'
A string denoting the specific kind of activity being created. This should be more specific than 'component'. For example, when creating a group, BuddyPress posts an activity item with the component 『groups』 and the type 『created_group』. 'type' is used for filtering, as in the 「New Groups」, 「New Blog Posts」, etc dropdown on Activity directories.
'primary_link'
(optional) The primary URL associated with the activity item. BuddyPress uses this value when creating activity RSS feeds, to tell the feed reader where to find the original item. If you omit this value, the fallback value is the permalink page for the single activity item.
'user_id'
(optional) The unique numeric id of the user associated with the activity item. In BuddyPress, the primary use of this value is to filter which items appear on the Activity tab of an individual member』s profile. If the value is omitted, it will default to the id of the currently logged-in user. Note that you can pass 0 for items that may be associated with no user at all.
'item_id'
(optional) The numeric ID of the primary item associated with this activity item. For example, when recording the creation of a group, BuddyPress sets the 'item_id' to the numeric id of the newly created group. This value can be used for filtering.
'secondary_item_id'
(optional) A second numeric ID for further filtering. For example, when recording a new blog comment, BuddyPress sets the 'item_id' to the ID of the blog, and the 'secondary_item_id' to the ID of the comment.
'recorded_time'
(optional) The time the activity is recorded. Should be in GMT, MySQL format. (In PHP, date( 'Y-m-d H:i:s', $time ).) Defaults to the current time.
'hide_sitewide'
(optional) 'hide_sitewide' is used in a few different ways:

To prevent duplicate entries when viewing the sitewide activity stream. For instance, when a new friendship is established, two activity items are created: one with 'user_id' set to the user who sent the request and 'item_id' set to recipient, and the other one vice versa. We need both items so that both users see the item on their own profiles, but it』s not desirable to see both of them on the sitewide stream, so the second one is marked 'hide_sitewide' => true.
To prevent activity items from hidden or private groups from appearing in sitewide activity streams. That is, when an activity item is posted to a non-public group, 'hide_sitewide' is set to false. Then, when viewing the group』s activity stream (which is accessible only to members), BP includes 'hide_sitewide' items; in contrast, the sitewide stream excludes these items.

Thus, 'hide_sitewide' is used simultaneously for preventing duplicates and for privacy. Please be sure you understand the way that 'hide_sitewide' works before attempting to use it for the purposes of privacy in your own plugins.
'is_spam'
(optional) Set to true to mark an item as spam.

Return value
New database row activity ID
Source File
bp_activity_add() is located in bp-activity/bp-activity-functions.php

仅在您的插件需要时才将脚本或样式排入队列

仅在您的插件需要时才将脚本或样式排入队列

Codex Home → BuddyPress Plugin Development → Enqueueing Scripts or Styles only when your plugin needs it
Enqueueing Scripts or Styles only when your plugin needs it

Using Javascipt or CSS in BuddyPress plugins are interesting ways to take care of the user experience. I think, as a plugin author, you need to have two concerns :

you might not be the only one to use Javascript, other plugins can be activated in the community website,
your CSS rules might not get along with the activated theme

As a result, i advise you to :

enqueue your Javascript or CSS only when your plugin needs it,
allow the theme to override your CSS rules

To illustrate an usage example, you can test the following tutorial. It comes with a BuddyPress plugin 「boilerplate」 (BuddyPlug) that you will find in the additional resources and will help you to achieve this 「roadmap」:
Steps

Choose the best hook to enqueue your scripts
Build your own conditional tags
Allow the theme to override your stylesheet
Additionnal resources

Choose the best hook to enqueue your scripts
Depending on the context, BuddyPress offers two hooks to rely on in order to safely load your scripts. The first one is bp_enqueue_scripts for enqueueing your script on the front end, here』s an example on how to use it from your plugin』s class:
class BuddyPlug {

/* focusing on bp_enqueue_script */

private function __construct() {
$this->setup_globals();
$this->setup_hooks();
}

private function setup_globals() {
// let's define some globals to easily build the url to your scripts
$this->version = '1.0.0';
$this->file = __FILE__;

// url to your plugin dir : site.url/wp-content/plugins/buddyplug/
$this->plugin_url = plugin_dir_url( $this->file );

// url to your plugin's includes dir : site.url/wp-content/plugins/buddyplug/includes/
$this->includes_url = trailingslashit( $this->plugin_url . 'includes' );

// url to your plugin's js dir : site.url/wp-content/plugins/buddyplug/includes/js/
$this->plugin_js = trailingslashit( $this->includes_url . 'js' );

// url to your plugin's css dir : site.url/wp-content/plugins/buddyplug/includes/css/
$this->plugin_css = trailingslashit( $this->includes_url . 'css' );

$this->component_id = 'buddyplug';
$this->component_slug = 'buddyplug';
}

private function setup_hooks() {
// As soon as WordPress meets this hook, your cssjs function will be called
add_action( 'bp_enqueue_scripts', array( $this, 'cssjs' ) );
}

public function cssjs() {
// Your css file is reachable at site.url/wp-content/plugins/buddyplug/includes/css/buddyplug.css
wp_enqueue_style( 'buddyplug-css', $this->plugin_css . 'buddyplug.css', false, $this->version );
// Your script file is reachable at site.url/wp-content/plugins/buddyplug/includes/js/script.js
wp_enqueue_script( 'buddyplug-js', $this->plugin_js . 'script.js', array( 'jquery' ), $this->version, true );
}
}

As you can see, your function cssjs() waits for bp_enqueue_scripts before using the two WordPress functions to load your style (wp_enqueue_style()) and your script (wp_enqueue_script()). At this point, your stylesheet and your javascript will load everywhere on the front end of the site.
The second one is bp_admin_enqueue_scripts for enqueueing your script within the WordPress Administration screens. If for instance your plugin is using a settings page, it can be interesting to load some extra javascript. Concerning CSS, a good practice, in this area, is to use the WordPress Administration markup so that your plugin administration pages are styled the same way than the other part of the Administration. That』s why, the following example does not enqueue a stylesheet:
class BuddyPlug {

/* focusing on bp_admin_enqueue_scripts */

private function setup_hooks() {
add_action( 'bp_enqueue_scripts', array( $this, 'cssjs' ) );

// As soon as WordPress Administration meets this hook, your admin_scripts function will be called
if( is_admin() )
add_action( 'bp_admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
}

public function admin_scripts() {
// Your script file is reachable at site.url/wp-content/plugins/buddyplug/includes/js/admin.js
wp_enqueue_script( 'buddyplug-admin-js', $this->plugin_js .'admin.js', array( 'jquery' ), $this->version, 1 );
}
}

In the above code, your function admin_scripts() waits for bp_admin_enqueue_scripts before enqueueing your script (wp_enqueue_script()). At this point, your javascript will be loaded in every Administration screens.
Build your own conditional tags
Your plugin do not need to play on every page of the community site. To avoid any troubles with other plugins, it』s best you add some control on where your scripts are loaded. The 「where」 are the areas your BuddyPress plugin creates. For instance, it could be:

A new component, using the BP_Component API
An extension of a core component
A new group extension, using the BP_Group_Extension API
Your plugin』s setting page in the Administration

The core file /buddypress/bp-core/bp-core-template.php contains some useful functions to help you identify your plugin』s areas before enqueueing your javascript or your css. When creating a new component, you can build a directory page, in this case your first conditional tags will be:
function buddyplug_is_current_component() {
/*
buddyplug_get_component_id() is a function that returns your component id ($this->component_id in BuddyPlug class)
for instance the activity component id is 'activity'.
In this example the function simply returns 'buddyplug'
I advise you to observe how the component.php file of the BuddyPlug plugin
is creating its component
*/
return bp_is_current_component( buddyplug_get_component_id() );
}

function buddyplug_is_directory() {
if( buddyplug_is_current_component() && bp_is_directory() )
return true;

return false;
}

So in order to only load script in your directory pages you simply need to check for buddyplug_is_directory() before enqueueing your script. If you use the BuddyPlug plugin, it will show you the result of these two functions, here is a screen capture to illustrate.
Loading Javascript in a directory page.
 
If you simply check for buddyplug_is_current_component(), then your script will also load on the plugin』s tab in the members profiles.
Loading Javascript for member's profile.
 
Your plugin can also extend the settings component to add a new tab to it to let the member customize its behavior. The following code creates a new conditional tag that you will be able to use to be sure your script is loaded in this area
function buddyplug_is_user_settings() {
/*
buddyplug_get_component_slug() is a function that simply returns the slug of the plugin ($this->component_slug in BuddyPlug class)
in this case it's 'buddyplug'
it means the sub navigation added to the settings component is reachable at
site.url/members/userlogin/settings/buddyplug
I advise you to have a look at the setup_settings_bp_nav() function in the component.php file
of the BuddyPlug plugin to see how the sub navigation is created.
*/
if( bp_is_settings_component() && bp_is_current_action( buddyplug_get_component_slug() ) )
return true;

return false;
}

Here』s a screen capture of this particular tab:
Loading JS in a Tab added to settings component
 
If you are using the Group Extension API, you can build some new conditional tags to check if the Group main tab, the Group admin edit tab, or the creation step of your plugin are loaded.
/**
* The Group Main tab for your plugin
*/
function buddyplug_is_group_front() {
if( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( buddyplug_get_component_slug() ) )
return true;

return false;
}

/**
* The Group creation step for your plugin
*/
function buddyplug_is_group_create() {
if( bp_is_group_creation_step( buddyplug_get_component_slug() ) )
return true;

return false;
}

/**
* The Group Admin Edit tab for your plugin
*/
function buddyplug_is_group_edit() {
if( bp_is_group_admin_page() && bp_is_action_variable( buddyplug_get_component_slug(), 0 ) )
return true;

return false;
}

/**
* Are we in your plugin's group area ?
*/
function buddyplug_is_group_area() {
if( buddyplug_is_group_front() || buddyplug_is_group_create() || buddyplug_is_group_edit() )
return true;

return false;
}

This is a screen capture that illustrates the buddyplug_is_group_edit() conditional tag
Loading JS in Group Admin Edit tab
 
Now, as an example, let』s imagine you wish to only load your script when on any of the area your plugin』s has created on the front end, then your function cssjs() in the BuddyPlug class could be :
public function cssjs() {
if( ( bp_is_active( $this->component_id ) && buddyplug_is_component_area() ) || ( bp_is_active( 'groups' ) && buddyplug_is_group_area() ) ) {
// Your css file is reachable at site.url/wp-content/plugins/buddyplug/includes/css/buddyplug.css
wp_enqueue_style( 'buddyplug-css', $this->plugin_css . 'buddyplug.css', false, $this->version );
// Your script file is reachable at site.url/wp-content/plugins/buddyplug/includes/js/script.js
wp_enqueue_script( 'buddyplug-js', $this->plugin_js . 'script.js', array( 'jquery' ), $this->version, true );
}
}

Note that we check if the groups component is active using the BuddyPress function bp_is_active().
As the last step of this part, you need to also make sure the javascript your plugin is using for its settings page is only loaded on this particular page. To do so you could use the $_GET['page'] variable or use the WordPress get_current_screen() function, or when the 1.9 version will be released simply check for the bp_admin_enqueue_scripts argument. See the following example:
class BuddyPlug {

/* focusing on bp_admin_enqueue_scripts */

private function setup_hooks() {
if( is_admin() ) {
add_action( bp_core_admin_hook(), array( $this, 'admin_menus' ) );
add_action( 'bp_admin_enqueue_scripts', array( $this, 'admin_scripts' ), 10, 1 );
}
}

/**
* Creates the admin pages
*/
public function admin_menus() {

$this->hook_suffixes[] = add_submenu_page(
$this->settings_page,
__( 'BuddyPlug Options', 'buddyplug' ),
__( 'BuddyPlug Options', 'buddyplug' ),
'manage_options',
'buddyplug',
'buddyplug_admin_settings'
);

/*
Using an array can help you get the screen ids of each of your
administration menus...
$this->hook_suffixes[] = add_menu_page()
*/
}

/**
* Eqnueues script
*/
public function admin_scripts( $hook = '' ) {
if( empty( $hook ) )
$hook = bp_core_do_network_admin() ? str_replace( '-network', '', get_current_screen()->id ) : get_current_screen()->id;

/* only loads the script if you are in one of your plugin's Administration screen
if( in_array( $hook, $this->hook_suffixes ) ) {
wp_enqueue_script( 'buddyplug-admin-js', $this->plugin_js .'admin.js', array( 'jquery' ), $this->version, 1 );
}

}

}

Example of use of a JS in your plugin』s settings page
Allow the theme to override your stylesheet
Finally, like BuddyPress does (see first link of the Additional resources section), you definatively should allow the theme to override the main css of your plugin. The very great reason is that, this way, the community Administrator will be able to add the final touch to your plugin that will make it look perfect in his theme
class BuddyPlug {

/* focusing on allowing theme to override the plugin's css file on front end */

public function cssjs() {

//Search in theme's folder
$css_datas = (array) $this->css_datas();

// before enqueueing the best style
wp_enqueue_style( $css_datas['handle'], $css_datas['location'], false, $this->version );

}

/**
* The theme can override plugin's css
*/
public function css_datas() {
$file = 'css/buddyplug.css';

// Check child theme
if ( file_exists( trailingslashit( get_stylesheet_directory() ) . $file ) ) {
$location = trailingslashit( get_stylesheet_directory_uri() ) . $file ;
$handle = 'buddyplug-child-css';

// Check parent theme
} elseif ( file_exists( trailingslashit( get_template_directory() ) . $file ) ) {
$location = trailingslashit( get_template_directory_uri() ) . $file ;
$handle = 'buddyplug-parent-css';

// use our style
} else {
$location = $this->includes_url . $file;
$handle = 'buddyplug-css';
}

return array( 'handle' => $handle, 'location' => $location );
}

}

Additional resources

wp_enqueue_script() in WordPress Codex
wp_enqueue_style() in WordPress Codex
Add BuddyPress styles to a theme
You can learn more about BP_Component from its Codex page
You can learn more about BP_Group_Extension from its Codex page
You can download the BuddyPlug example plugin from his github repository

群组元查询:使用示例

群组元查询:使用示例

Codex Home → BuddyPress Plugin Development → Group Meta Queries: Usage Example
Group Meta Queries: Usage Example

Since version 1.8, it is possible to filter groups by Metadata. For instance you can add a meta_query parameter to the bp_has_groups() function. To make this possible, BuddyPress uses a built-in WordPress class : WP_Meta_Query (you will find a link to its WordPress codex page at the bottom of this article).
This feature can help plugin developers to extend the way groups are filtered, or query groups to search for a particular group meta your plugin is using. For example, if a plugin is adding a groupmeta to groups when its group component is activated, it can use a group meta query to list all the groups that activated their component.
To illustrate an usage example, you can test the following tutorial. Its goal is to add a new option to the select boxes (Order by filters) that are available on the Groups directory page and on the member』s profile group page. This option will list the groups that the community Administrator featured. This is your roadmap:
Steps

Create a new meta box in the Edit Group Administration screen
Filter bp_ajax_querystring to eventually extend the groups query
Pause: the meta_query parameter in details
Add your new option to select boxes
Additional resources

Create a new meta box in the Edit Group Administration screen
For the purpose of this example, you will need to first create the Administration part to let the community Administrator feature the groups of his choice from the Group Administration screen. To do so, from the functions.php of your active theme, you can add these first lines.
//it's important to check if the Groups component is active
if( bp_is_active( 'groups' ) ) :
/**
* This is a quick and dirty class to illustrate "bpgmq"
* bpgmq stands for BuddyPress Group Meta Query...
* The goal is to store a groupmeta in order to let the community administrator
* feature a group.
* Featured groups will be filterable from the groups directory thanks to a new option
* and to a filter applied on bp_ajax_query_string()
*
* This class is an example, it would be much better to use the group extension API
*/
class bpgmq_feature_group {

public function __construct() {
$this->setup_hooks();
}

private function setup_hooks() {
// in Group Administration screen, you add a new metabox to display a checkbox to featured the displayed group
add_action( 'bp_groups_admin_meta_boxes', array( $this, 'admin_ui_edit_featured' ) );
// Once the group is saved you store a groupmeta in db, the one you will search for in your group meta query
add_action( 'bp_group_admin_edit_after', array( $this, 'admin_ui_save_featured'), 10, 1 );
}

/**
* registers a new metabox in Edit Group Administration screen, edit group panel
*/
public function admin_ui_edit_featured() {
add_meta_box(
'bpgmq_feature_group_mb',
__( 'Featured Group' ),
array( &$this, 'admin_ui_metabox_featured'),
get_current_screen()->id,
'side',
'core'
);
}

/**
* Displays the meta box
*/
public function admin_ui_metabox_featured( $item = false ) {
if( empty( $item ) )
return;

// Using groups_get_groupmeta to check if the group is featured
$is_featured = groups_get_groupmeta( $item->id, '_bpgmq_featured_group' );
?>

<input type="checkbox" id="bpgmq-featured-cb" name="bpgmq-featured-cb" value="1" >

id, 'bpgmq_featured_admin' );
}

function admin_ui_save_featured( $group_id = 0 ) {
if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) || empty( $group_id ) )
return false;

check_admin_referer( 'bpgmq_featured_save_' . $group_id, 'bpgmq_featured_admin' );

// You need to check if the group was featured so that you can eventually delete the group meta
$was_featured = groups_get_groupmeta( $group_id, '_bpgmq_featured_group' );
$to_feature = !empty( $_POST['bpgmq-featured-cb'] ) ? true : false;

if( !empty( $to_feature ) && empty( $was_featured ) )
groups_update_groupmeta( $group_id, '_bpgmq_featured_group', 1 );
if( empty( $to_feature ) && !empty( $was_featured ) )
groups_delete_groupmeta( $group_id, '_bpgmq_featured_group' );
}

}

/**
* Let's launch !
*
* Using bp_is_active() in this case is not needed
* But i think it's a good practice to use this kind of check
* just in case 🙂
*/
function bpgmq_feature_group() {
if( bp_is_active( 'groups') )
return new BPGMQ_Feature_Group();
}

add_action( 'bp_init', 'bpgmq_feature_group' );

Once done, if you go in the Groups Administration screen and choose to edit a particular group, you should see a new meta box on the right as shown on this screen capture :
The featured box on the right.
What have you just achieved ?
You』ve created a class that will add a groupmeta named 「_bpgmq_featured_group」 (line 67 of the above code) if the community Administrator activated the checkbox. Now you can use this groupmeta in order to only display/get the featured groups.
Filter bp_ajax_querystring to eventually extend the groups query
In order to do this, you need to add a new hook in your setup_hooks() function (line 18 of the above code). Add this code under line 22:
/* The groups loop uses bp_ajax_querystring( 'groups' ) to filter the groups
depending on the selected option */
add_filter( 'bp_ajax_querystring', array( $this, 'filter_ajax_querystring' ), 20, 2 );

As explained in the comments, this will filter the bp_ajax_querystring() function so that you can extend it to include your meta_query. Note that 「20」 tells WordPress to run this filter at a greater priority than the default one (10). Doing so, you make sure BuddyPress first applies the needed filters before yours. 「2」 tells WordPress your filter waits for 2 arguments. Now, you need to actually create the filter_ajax_querystring() function in your class without forgetting to return a value as a WordPress filter requires one. So after the admin_ui_save_featured() function, but before the end of your class, add these lines:
public function filter_ajax_querystring( $querystring = '', $object = '' ) {

/* bp_ajax_querystring is also used by other components, so you need
to check the object is groups, else simply return the querystring and stop the process */
if( $object != 'groups' )
return $querystring;

// Let's rebuild the querystring as an array to ease the job
$defaults = array(
'type' => 'active',
'action' => 'active',
'scope' => 'all',
'page' => 1,
'user_id' => 0,
'search_terms' => '',
'exclude' => false,
);

$bpgmq_querystring = wp_parse_args( $querystring, $defaults );

/* if your featured option has not been requested
simply return the querystring to stop the process
*/
if( $bpgmq_querystring['type'] != 'featured' )
return $querystring;

/* this is your meta_query */
$bpgmq_querystring['meta_query'] = array(
array(
'key' => '_bpgmq_featured_group',
'value' => 1,
'type' => 'numeric',
'compare' => '='
)
);

// using a filter will help other plugins to eventually extend this feature
return apply_filters( 'bpgmq_filter_ajax_querystring', $bpgmq_querystring, $querystring );
}

What have you just achieved ?
Each time BuddyPress uses the function bp_ajax_querystring() to filter its components, your filter_ajax_querystring() function will be run. As you are targeting the groups loop, the first thing you need to do is to stop the process and return the original ajax query string if the you are not in a groups loop. Hopefully, line 5 of the above code is doing so! If you actually are in a groups loop, then you need to parse the query string in order to build an array that will be easier to manipulate (see line 8 to 19). You will be able to check for the 「type」 argument to make sure the selected option is 「featured」. If not, you need to stop the process and return the original query string (see line 24 to 25). The user requested the 「featured」 groups, it is time you build the object of this tutorial : the Group meta query (see line 27 to 35). Finally, it is a good practice to eventually let other plugins extend your code, that』s why i encourage you to use the apply_filters() function and to include your value and the original one in arguments (line 38).
Pause: the meta_query parameter in details
Your meta_query is a multidimensional array. Each array has a goal. In your case you only need one array as you want to query the group by one Metadata (groupmeta). But if you need to do so on more than one Metadata, then you need a first array to tell BuddyPress what will be the relation to apply. Should the query be filtered by first AND second groupmeta or by first OR second groupmeta. Then as you have a second groupmeta, you need to build a third array to configure the second one. And so on, if you have more than 2 Metadatas to filter the groups with. Your meta_query parameter could have looked this way :
$bpgmq_querystring['meta_query'] = array(
array(
'relation' => 'OR', // Optional, defaults to "AND"
),
array(
'key' => '_bpgmq_featured_group',
'value' => 1,
'type' => 'numeric',
'compare' => '='
),
array(
'key' => '_second_groupmeta',
'value' => 'group',
'compare' => 'LIKE'
)
);

Add your new option to select boxes
Back to your 「featured」 functionality. Your last touch will be to add a featured option to the select box (Order by) of the Groups directory page and the one of the member』s profile group page. If you omit the second one, then you would create a confusion for the user. As BuddyPress is using cookies to remember the way the group was last filtered, if the filter was 「featured」 in Groups directory, then in member』s profile group page the groups will be filtered this way too, but the wrong value would be set in the select box as no correspondence would have been found. So it』s important, you add your option in the two areas. First you need to add these lines in the setup_hooks() function of your class:
/* finally you create your options in the different select boxes */
// you need to do it for the Groups directory
add_action( 'bp_groups_directory_order_options', array( $this, 'featured_option' ) );
// and for the groups tab of the user's profile
add_action( 'bp_member_group_order_options', array( $this, 'featured_option' ) );

Finally, do not forget to add the featured_option() function to your class. So before the end of it insert these lines:
public function featured_option() {
?>

<?php
}

Once done, if you go in the Groups directory or in the member』s profile groups page, you should see a new option in the 「Order by」 select boxes as shown on this screen capture :
The Order By select boxes
What have you just achieved ?
I think you almost built a plugin It might be a good idea to improve this code by using the BP_Group_Extension API.

Additional resources

You can learn more about WP_Meta_Query and its arguments from the WordPress Codex
You can learn more about BP_Group_Extension from its Codex page
You can find the complete class in this gist

在不同的上下文中使用用户的 ID

在不同的上下文中使用用户的 ID

Codex Home → Developer Resources → Playing with the user』s ID in different contexts
Playing with the user』s ID in different contexts

BuddyPress Core is first taking care of the members. As a result, when you write a BuddyPress plugin, there is a very good chance that you』ve got to play with the finest element identifying the users : their ID.
There are two scenarios: the logged in user and the user whose profile is displayed. Thankfully, BuddyPress provides you with two interesting functions to get the user ID for these scenarios. Then there are other specific cases in which you must handle these two main functions with caution. Fortunately again, BuddyPress provides other functions to avoid some 「unwanted」 behaviors.
Steps

Explore the two main functions to get the user』s ID
Discover other useful functions when playing inside some BuddyPress loops
Additionnal resources

Explore the two main functions to get the user』s ID
The function bp_loggedin_user_id() will return you the current logged in user ID that has been set thanks to the BP_Core class using the WordPress function wp_get_current_user().
The function bp_displayed_user_id() will return the ID of the displayed user that has been set thanks to the bp_core_set_uri_globals() function when a profile page is requested. This also means that you can simply know if you are on a profile page by checking if the bp_displayed_user_id() function is not empty. The function bp_is_user(), informing you that you』ve reached a profile page is actually using this check.
When the two are equal, it means that the logged in user is visiting one of his profile pages, the BuddyPress function bp_is_my_profile() is using this equality to inform you if that』s the case.
Let』s begin an example to illustrate the use of the two functions. In the member』s header there』s a template tag BuddyPress is using to display the latest activity the displayed user posted : bp_activity_latest_update(). Like most of BuddyPress template tags, you can filter the returned value to eventually extend it in your plugin. Here, you will simply print user IDs. In the functions.php of your active theme (or in your plugin), you can write :
function bp_plugin_filter_latest_update( $update = '' ) {

$update .= ' logged_in: ' . bp_loggedin_user_id() .' | displayed: ' . bp_displayed_user_id() . '';

return $update;
}

add_filter( 'bp_get_activity_latest_update', 'bp_plugin_filter_latest_update', 10, 1 );

Here』s a screen capture of the result of this 「great extension」
bp_loggedin_user_id() Vs bp_displayed_user_id()
 
As you can see, if your goal is to display information about the user displayed, as shown in this case, you should definitively use bp_displayed_user_id() to avoid having the information of the logged in user on each profile ;). You can also see that 「imath」 is the logged in user as the two functions return the same result. In a user』s profile the bp_loggedin_user_id() will be useful to add some interaction with the user displayed. For instance, the 「Add Friend」 functionality is using the logged in user ID to check if the current user is friend with the displayed user.
Discover other great functions when extending some BuddyPress loops
To go straight to the point, let』s edit our previous code by adding a filter to the bp_member_latest_update() template tag. This function is doing the same thing than the one you saw in first step, except that it runs inside the members loop.
function bp_plugin_filter_latest_update( $update = '' ) {
// In step 1, you saw that bp_displayed_user_id() was the best function to use
// when displaying information about the user in his profile page
$update .= ' displayed: ' . bp_displayed_user_id() . '';

return $update;
}

add_filter( 'bp_get_activity_latest_update', 'bp_plugin_filter_latest_update', 10, 1 );
add_filter( 'bp_get_member_latest_update', 'bp_plugin_filter_latest_update', 10, 1 );

Take a few seconds to check the result of this code in the three parts of this screen capture.
bp_displayed_user_id() and the members loop
 
As you can see, while bp_displayed_user_id() works fine in the member』s header, it is empty in the members loop. So we need to call two functions to the rescue! The first one is a template tag specific to the member component: bp_get_member_user_id() and the second one is the function, you discovered earlier, to check you are on a user』s profile page: bp_is_user(). So, you need to edit the filter this way:
function bp_plugin_filter_latest_update( $update = '' ) {
if( bp_is_user() ) {
$user_id = 'displayed: '. bp_displayed_user_id();
} else {
$user_id = 'get_member_user: '. bp_get_member_user_id();
}
$update .= ' ' . $user_id . '';

return $update;
}

add_filter( 'bp_get_activity_latest_update', 'bp_plugin_filter_latest_update', 10, 1 );
add_filter( 'bp_get_member_latest_update', 'bp_plugin_filter_latest_update', 10, 1 );

If you check the result of this code, you will surely wonder why i』ve changed the color of the ID to red as it seems to solve the issue in the members loop and in the member』s header. To understand why, you simply need to activate the friends navigation of the user』s profile, and here』s what you』ll see:
Members loop in member』s profile : friends
 
「mathieu」, 「imath」 and 「Moi」 have the same ID! Actually, only 「mathieu」 has the good ID as you are visiting his profile. In the friends tab, although you are on a user』s profile, you also are in a members loop displaying user』s friends. So you need to adapt your code to this particular case by also checking the bp_get_member_user_id() before using bp_displayed_user_id().
function bp_plugin_filter_latest_update( $update = '' ) {
if( bp_is_user() && ! bp_get_member_user_id() ) {
$user_id = 'displayed: '. bp_displayed_user_id();
} else {
$user_id = 'get_member_user: '. bp_get_member_user_id();
}
$update .= ' ' . $user_id . '';

return $update;
}

add_filter( 'bp_get_activity_latest_update', 'bp_plugin_filter_latest_update', 10, 1 );
add_filter( 'bp_get_member_latest_update', 'bp_plugin_filter_latest_update', 10, 1 );

Now you can check again: the logged in user』s profile, another profile, the friends tab of a user』s profile and the main members loop, each user has the good ID in the different areas! Bravo
The Activity and the Group members loop also offer their specific functions to get the good user ID in their context :

Activity loop : bp_get_activity_user_id()
Group members loop : bp_get_group_member_id()

Additional resources

wp_get_current_user() in WordPress Codex
the Members loop
the Group Members loop
the Activity loop

WordPress 博客

WordPress 博客

Codex Home → BuddyPress Components and Features → WordPress Blogs
WordPress Blogs

Some of the most powerful features of BuddyPress relate to how it enhances your multisite network. Creating a network allows your members to start their own full-powered public or private WordPress blogs. Members can track new posts and comments from public blogs across the network of sites as they are posted in the sitewide activity stream, in the blog owner』s activity stream, and in the blogs directory page. These features help facilitate content discovery and social interaction on your network.
Note: When you are using multisite and blog creation is enabled for users, there』ll be an option for 「I want to create a blog」 when a user registers in your site.
Configuring Site Tracking
In order to use all of the network features of BuddyPress you must first enable the 『Site Tracking』 component under the Components tab in the BuddyPress section of your Network Admin Settings.
Also make sure to check that your 『Site Tracking』 page has been correctly associated under the Pages tab in the BuddyPress section of your Network Admin Settings.
Using Site Tracking
By default the blogs directory page lists the public blogs in your network in the order of the most recently updated to the least recently updated. You can re-order the list by either newest to oldest or alphabetically by selecting either option from the 『Sort Order』 drop down menu. Use the 『Visit Site』 button to visit the homepage of any site from the list. In addition to the site title and 『Visit Site』 button each site shows the time of the last update and a direct link to the site』s latest post.
With 『Site Tracking』 enabled, the Activity Streams of your primary site will also include activities completed on any site on your network which has not enabled privacy for their blog.
Blog Privacy
When a blog selects 「discourage search engines…」 as a privacy setting, the blog won』t show up in activity directories, etc.