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.