BP_Nouveau
Loads BuddyPress Nouveau Template pack functionality.
Description Description
See @link BP_Theme_Compat() for more.
Source Source
File: bp-templates/bp-nouveau/buddypress-functions.php
class BP_Nouveau extends BP_Theme_Compat {
/**
* Instance of this class.
*/
protected static $instance = null;
/**
* Return the instance of this class.
*
* @since 3.0.0
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
/**
* The BP Nouveau constructor.
*
* @since 3.0.0
*/
public function __construct() {
parent::start();
$this->includes();
$this->setup_support();
}
/**
* BP Nouveau global variables.
*
* @since 3.0.0
*/
protected function setup_globals() {
$bp = buddypress();
foreach ( $bp->theme_compat->packages['nouveau'] as $property => $value ) {
$this->{$property} = $value;
}
$this->includes_dir = trailingslashit( $this->dir ) . 'includes/';
$this->directory_nav = new BP_Core_Nav();
}
/**
* Includes!
*
* @since 3.0.0
*/
protected function includes() {
require $this->includes_dir . 'functions.php';
require $this->includes_dir . 'classes.php';
require $this->includes_dir . 'template-tags.php';
// Test suite requires the AJAX functions early.
if ( function_exists( 'tests_add_filter' ) ) {
require $this->includes_dir . 'ajax.php';
// Load AJAX code only on AJAX requests.
} else {
add_action( 'admin_init', function() {
if ( defined( 'DOING_AJAX' ) && true === DOING_AJAX ) {
require bp_nouveau()->includes_dir . 'ajax.php';
}
}, 0 );
}
add_action( 'bp_customize_register', function() {
if ( bp_is_root_blog() && current_user_can( 'customize' ) ) {
require bp_nouveau()->includes_dir . 'customizer.php';
}
}, 0 );
foreach ( bp_core_get_packaged_component_ids() as $component ) {
$component_loader = trailingslashit( $this->includes_dir ) . $component . '/loader.php';
if ( ! bp_is_active( $component ) || ! file_exists( $component_loader ) ) {
continue;
}
require( $component_loader );
}
/**
* Fires after all of the BuddyPress Nouveau includes have been loaded. Passed by reference.
*
* @since 3.0.0
*
* @param BP_Nouveau $value Current BP_Nouveau instance.
*/
do_action_ref_array( 'bp_nouveau_includes', array( &$this ) );
}
/**
* Setup the Template Pack features support.
*
* @since 3.0.0
*/
protected function setup_support() {
$width = 1300;
$top_offset = 150;
/** This filter is documented in bp-core/bp-core-avatars.php. */
$avatar_height = apply_filters( 'bp_core_avatar_full_height', $top_offset );
if ( $avatar_height > $top_offset ) {
$top_offset = $avatar_height;
}
bp_set_theme_compat_feature( $this->id, array(
'name' => 'cover_image',
'settings' => array(
'components' => array( 'xprofile', 'groups' ),
'width' => $width,
'height' => $top_offset + round( $avatar_height / 2 ),
'callback' => 'bp_nouveau_theme_cover_image',
'theme_handle' => 'bp-nouveau',
),
) );
}
/**
* Setup the Template Pack common actions.
*
* @since 3.0.0
*/
protected function setup_actions() {
// Filter BuddyPress template hierarchy and look for page templates.
add_filter( 'bp_get_buddypress_template', array( $this, 'theme_compat_page_templates' ), 10, 1 );
// Add our "buddypress" div wrapper to theme compat template parts.
add_filter( 'bp_replace_the_content', array( $this, 'theme_compat_wrapper' ), 999 );
// We need to neutralize the BuddyPress core "bp_core_render_message()" once it has been added.
add_action( 'bp_actions', array( $this, 'neutralize_core_template_notices' ), 6 );
// Scripts
add_action( 'bp_enqueue_scripts', array( $this, 'register_scripts' ), 2 ); // Register theme JS
remove_action( 'bp_enqueue_scripts', 'bp_core_confirmation_js' );
add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_styles' ) ); // Enqueue theme CSS
add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // Enqueue theme JS
add_filter( 'bp_enqueue_scripts', array( $this, 'localize_scripts' ) ); // Enqueue theme script localization
// Body no-js class
add_filter( 'body_class', array( $this, 'add_nojs_body_class' ), 20, 1 );
// Ajax querystring
add_filter( 'bp_ajax_querystring', 'bp_nouveau_ajax_querystring', 10, 2 );
// Register directory nav items
add_action( 'bp_screens', array( $this, 'setup_directory_nav' ), 15 );
// Register the Default front pages Dynamic Sidebars
add_action( 'widgets_init', 'bp_nouveau_register_sidebars', 11 );
// Register the Primary Object nav widget
add_action( 'bp_widgets_init', array( 'BP_Nouveau_Object_Nav_Widget', 'register_widget' ) );
// Set the BP Uri for the Ajax customizer preview
add_filter( 'bp_uri', array( $this, 'customizer_set_uri' ), 10, 1 );
/** Override **********************************************************/
/**
* Fires after all of the BuddyPress theme compat actions have been added.
*
* @since 3.0.0
*
* @param BP_Nouveau $this Current BP_Nouveau instance.
*/
do_action_ref_array( 'bp_theme_compat_actions', array( &$this ) );
}
/**
* Enqueue the template pack css files
*
* @since 3.0.0
*/
public function enqueue_styles() {
$min = bp_core_get_minified_asset_suffix();
$rtl = '';
if ( is_rtl() ) {
$rtl = '-rtl';
}
/**
* Filters the BuddyPress Nouveau CSS dependencies.
*
* @since 3.0.0
*
* @param array $value Array of style dependencies. Default Dashicons.
*/
$css_dependencies = apply_filters( 'bp_nouveau_css_dependencies', array( 'dashicons' ) );
/**
* Filters the styles to enqueue for BuddyPress Nouveau.
*
* This filter provides a multidimensional array that will map to arguments used for wp_enqueue_style().
* The primary index should have the stylesheet handle to use, and be assigned an array that has indexes for
* file location, dependencies, and version.
*
* @since 3.0.0
*
* @param array $value Array of styles to enqueue.
*/
$styles = apply_filters( 'bp_nouveau_enqueue_styles', array(
'bp-nouveau' => array(
'file' => 'css/buddypress%1$s%2$s.css', 'dependencies' => $css_dependencies, 'version' => $this->version,
),
) );
if ( $styles ) {
foreach ( $styles as $handle => $style ) {
if ( ! isset( $style['file'] ) ) {
continue;
}
$file = sprintf( $style['file'], $rtl, $min );
// Locate the asset if needed.
if ( false === strpos( $style['file'], '://' ) ) {
$asset = bp_locate_template_asset( $file );
if ( empty( $asset['uri'] ) || false === strpos( $asset['uri'], '://' ) ) {
continue;
}
$file = $asset['uri'];
}
$data = bp_parse_args(
$style,
array(
'dependencies' => array(),
'version' => $this->version,
'type' => 'screen',
),
'nouveau_enqueue_styles'
);
wp_enqueue_style( $handle, $file, $data['dependencies'], $data['version'], $data['type'] );
if ( $min ) {
wp_style_add_data( $handle, 'suffix', $min );
}
}
}
}
/**
* Register Template Pack JavaScript files
*
* @since 3.0.0
*/
public function register_scripts() {
$min = bp_core_get_minified_asset_suffix();
$dependencies = bp_core_get_js_dependencies();
$bp_confirm = array_search( 'bp-confirm', $dependencies );
unset( $dependencies[ $bp_confirm ] );
/**
* Filters the scripts to enqueue for BuddyPress Nouveau.
*
* This filter provides a multidimensional array that will map to arguments used for wp_register_script().
* The primary index should have the script handle to use, and be assigned an array that has indexes for
* file location, dependencies, version and if it should load in the footer or not.
*
* @since 3.0.0
*
* @param array $value Array of scripts to register.
*/
$scripts = apply_filters( 'bp_nouveau_register_scripts', array(
'bp-nouveau' => array(
'file' => 'js/buddypress-nouveau%s.js',
'dependencies' => $dependencies,
'version' => $this->version,
'footer' => true,
),
) );
// Bail if no scripts
if ( empty( $scripts ) ) {
return;
}
// Add The password verify if needed.
if ( bp_is_active( 'settings' ) || bp_get_signup_allowed() ) {
/**
* BP Nouveau is now directly using the `wp-admin/js/user-profile.js` script.
*
* Setting the user password is now more consistent with how WordPress handles it.
*
* @deprecated 5.0.0
*/
$scripts['bp-nouveau-password-verify'] = array(
'file' => 'js/password-verify%s.js',
'dependencies' => array( 'bp-nouveau', 'password-strength-meter' ),
'footer' => true,
);
}
foreach ( $scripts as $handle => $script ) {
if ( ! isset( $script['file'] ) ) {
continue;
}
$file = sprintf( $script['file'], $min );
// Locate the asset if needed.
if ( false === strpos( $script['file'], '://' ) ) {
$asset = bp_locate_template_asset( $file );
if ( empty( $asset['uri'] ) || false === strpos( $asset['uri'], '://' ) ) {
continue;
}
$file = $asset['uri'];
}
$data = bp_parse_args(
$script,
array(
'dependencies' => array(),
'version' => $this->version,
'footer' => false,
),
'nouveau_register_scripts'
);
wp_register_script( $handle, $file, $data['dependencies'], $data['version'], $data['footer'] );
}
}
/**
* Enqueue the required JavaScript files
*
* @since 3.0.0
*/
public function enqueue_scripts() {
wp_enqueue_script( 'bp-nouveau' );
if ( bp_is_register_page() || bp_is_user_settings_general() ) {
wp_enqueue_script( 'user-profile' );
}
if ( is_singular() && bp_is_blog_page() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
/**
* Fires after all of the BuddyPress Nouveau scripts have been enqueued.
*
* @since 3.0.0
*/
do_action( 'bp_nouveau_enqueue_scripts' );
}
/**
* Adds the no-js class to the body tag.
*
* This function ensures that the <body> element will have the 'no-js' class by default. If you're
* using JavaScript for some visual functionality in your theme, and you want to provide noscript
* support, apply those styles to body.no-js.
*
* The no-js class is removed by the JavaScript created in buddypress.js.
*
* @since 3.0.0
*
* @param array $classes Array of classes to append to body tag.
*
* @return array $classes
*/
public function add_nojs_body_class( $classes ) {
$classes[] = 'no-js';
return array_unique( $classes );
}
/**
* Load localizations for topic script.
*
* These localizations require information that may not be loaded even by init.
*
* @since 3.0.0
*/
public function localize_scripts() {
$params = array(
'ajaxurl' => bp_core_ajax_url(),
'confirm' => __( 'Are you sure?', 'buddypress' ),
'show_x_comments' => __( 'Show all %d comments', 'buddypress' ),
'unsaved_changes' => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
'object_nav_parent' => '#buddypress',
);
// If the Object/Item nav are in the sidebar
if ( bp_nouveau_is_object_nav_in_sidebar() ) {
$params['object_nav_parent'] = '.buddypress_object_nav';
}
/**
* Filters the supported BuddyPress Nouveau components.
*
* @since 3.0.0
*
* @param array $value Array of supported components.
*/
$supported_objects = (array) apply_filters( 'bp_nouveau_supported_components', bp_core_get_packaged_component_ids() );
$object_nonces = array();
foreach ( $supported_objects as $key_object => $object ) {
if ( ! bp_is_active( $object ) || 'forums' === $object ) {
unset( $supported_objects[ $key_object ] );
continue;
}
$object_nonces[ $object ] = wp_create_nonce( 'bp_nouveau_' . $object );
}
// Groups require some additional objects.
if ( bp_is_active( 'groups' ) ) {
$supported_objects = array_merge( $supported_objects, array( 'group_members', 'group_requests' ) );
}
// Add components & nonces
$params['objects'] = $supported_objects;
$params['nonces'] = $object_nonces;
// Used to transport the settings inside the Ajax requests
if ( is_customize_preview() ) {
$params['customizer_settings'] = bp_nouveau_get_temporary_setting( 'any' );
}
/**
* Filters core JavaScript strings for internationalization before AJAX usage.
*
* @since 3.0.0
*
* @param array $params Array of key/value pairs for AJAX usage.
*/
wp_localize_script( 'bp-nouveau', 'BP_Nouveau', apply_filters( 'bp_core_get_js_strings', $params ) );
}
/**
* Filter the default theme compatibility root template hierarchy, and prepend
* a page template to the front if it's set.
*
* @see https://buddypress.trac.wordpress.org/ticket/6065
*
* @since 3.0.0
*
* @param array $templates Array of templates.
*
* @return array
*/
public function theme_compat_page_templates( $templates = array() ) {
/**
* Filters whether or not we are looking at a directory to determine if to return early.
*
* @since 3.0.0
*
* @param bool $value Whether or not we are viewing a directory.
*/
if ( true === (bool) apply_filters( 'bp_nouveau_theme_compat_page_templates_directory_only', ! bp_is_directory() ) ) {
return $templates;
}
// No page ID yet.
$page_id = 0;
// Get the WordPress Page ID for the current view.
foreach ( (array) buddypress()->pages as $component => $bp_page ) {
// Handles the majority of components.
if ( bp_is_current_component( $component ) ) {
$page_id = (int) $bp_page->id;
}
// Stop if not on a user page.
if ( ! bp_is_user() && ! empty( $page_id ) ) {
break;
}
// The Members component requires an explicit check due to overlapping components.
if ( bp_is_user() && ( 'members' === $component ) ) {
$page_id = (int) $bp_page->id;
break;
}
}
// Bail if no directory page set.
if ( 0 === $page_id ) {
return $templates;
}
// Check for page template.
$page_template = get_page_template_slug( $page_id );
// Add it to the beginning of the templates array so it takes precedence over the default hierarchy.
if ( ! empty( $page_template ) ) {
/**
* Check for existence of template before adding it to template
* stack to avoid accidentally including an unintended file.
*
* @see https://buddypress.trac.wordpress.org/ticket/6190
*/
if ( '' !== locate_template( $page_template ) ) {
array_unshift( $templates, $page_template );
}
}
return $templates;
}
/**
* Add our special 'buddypress' div wrapper to the theme compat template part.
*
* @since 3.0.0
*
* @see bp_buffer_template_part()
*
* @param string $retval Current template part contents.
*
* @return string
*/
public function theme_compat_wrapper( $retval ) {
if ( false !== strpos( $retval, '<div id="buddypress"' ) ) {
return $retval;
}
// Add our 'buddypress' div wrapper.
return sprintf(
'<div id="buddypress" class="%1$s">%2$s</div><!-- #buddypress -->%3$s',
esc_attr( bp_nouveau_get_container_classes() ),
$retval, // Constructed HTML.
"\n"
);
}
/**
* Define the directory nav items
*
* @since 3.0.0
*/
public function setup_directory_nav() {
$nav_items = array();
if ( bp_is_members_directory() ) {
$nav_items = bp_nouveau_get_members_directory_nav_items();
} elseif ( bp_is_activity_directory() ) {
$nav_items = bp_nouveau_get_activity_directory_nav_items();
} elseif ( bp_is_groups_directory() ) {
$nav_items = bp_nouveau_get_groups_directory_nav_items();
} elseif ( bp_is_blogs_directory() ) {
$nav_items = bp_nouveau_get_blogs_directory_nav_items();
}
if ( empty( $nav_items ) ) {
return;
}
foreach ( $nav_items as $nav_item ) {
if ( empty( $nav_item['component'] ) || $nav_item['component'] !== bp_current_component() ) {
continue;
}
// Define the primary nav for the current component's directory
$this->directory_nav->add_nav( $nav_item );
}
}
/**
* We'll handle template notices from BP Nouveau.
*
* @since 3.0.0
*/
public function neutralize_core_template_notices() {
remove_action( 'template_notices', 'bp_core_render_message' );
}
/**
* Set the BP Uri for the customizer in case of Ajax requests.
*
* @since 3.0.0
*
* @param string $path the BP Uri.
* @return string the BP Uri.
*/
public function customizer_set_uri( $path ) {
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
return $path;
}
$uri = parse_url( $path );
if ( false === strpos( $uri['path'], 'customize.php' ) ) {
return $path;
} else {
$vars = bp_parse_args(
$uri['query'],
array(),
'customizer_set_uri'
);
if ( ! empty( $vars['url'] ) ) {
$path = str_replace( get_site_url(), '', urldecode( $vars['url'] ) );
}
}
return $path;
}
}
Changelog Changelog
| Version | Description |
|---|---|
| 3.0.0 | Introduced. |
Methods Methods
- __construct — The BP Nouveau constructor.
- add_nojs_body_class — Adds the no-js class to the body tag.
- customizer_set_uri — Set the BP Uri for the customizer in case of Ajax requests.
- enqueue_scripts — Enqueue the required JavaScript files
- enqueue_styles — Enqueue the template pack css files
- filter_registration_messages — Modify "registration disabled" message in Nouveau template pack.
- get_instance — Return the instance of this class.
- includes — Includes!
- localize_scripts — Load localizations for topic script.
- neutralize_core_template_notices — We'll handle template notices from BP Nouveau.
- register_scripts — Register Template Pack JavaScript files
- setup_actions — Setup the Template Pack common actions.
- setup_directory_nav — Define the directory nav items
- setup_globals — BP Nouveau global variables.
- setup_support — Setup the Template Pack features support.
- theme_compat_page_templates — Filter the default theme compatibility root template hierarchy, and prepend a page template to the front if it's set.
- theme_compat_wrapper — Add our special 'buddypress' div wrapper to the theme compat template part.