[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/ -> bp-core-template-loader.php (source)

   1  <?php
   2  /**
   3   * BuddyPress Template Functions.
   4   *
   5   * This file contains functions necessary to mirror the WordPress core template
   6   * loading process. Many of those functions are not filterable, and even then
   7   * would not be robust enough to predict where BuddyPress templates might exist.
   8   *
   9   * @package BuddyPress
  10   * @subpackage TemplateFunctions
  11   * @since 1.7.0
  12   */
  13  
  14  // Exit if accessed directly.
  15  defined( 'ABSPATH' ) || exit;
  16  
  17  /**
  18   * Get a BuddyPress template part for display in a theme.
  19   *
  20   * @since 1.7.0
  21   * @since 7.0.0 Added $args parameter.
  22   *
  23   * @param string      $slug Template part slug. Used to generate filenames,
  24   *                          eg 'friends' for 'friends.php'.
  25   * @param string|null $name Optional. Template part name. Used to generate
  26   *                          secondary filenames, eg 'personal' for 'activity-personal.php'.
  27   * @param array       $args Optional. Extra args to pass to locate_template().
  28   * @return false|string Path to located template. See {@link bp_locate_template()}.
  29   */
  30  function bp_get_template_part( $slug, $name = null, $args = array() ) {
  31  
  32      /**
  33       * Fires at the start of bp_get_template_part().
  34       *
  35       * This is a variable hook that is dependent on the slug passed in.
  36       *
  37       * @since 1.7.0
  38       * @since 7.0.0 Added $args parameter.
  39       *
  40       * @param string $slug Template part slug requested.
  41       * @param string $name Template part name requested.
  42       * @param array  $args Extra args to pass to locate_template().
  43       */
  44      do_action( 'get_template_part_' . $slug, $slug, $name, $args );
  45  
  46      // Setup possible parts.
  47      $templates = array();
  48      if ( isset( $name ) ) {
  49          $templates[] = $slug . '-' . $name . '.php';
  50      }
  51      $templates[] = $slug . '.php';
  52  
  53      /**
  54       * Filters the template parts to be loaded.
  55       *
  56       * @since 1.7.0
  57       * @since 7.0.0 Added $args parameter.
  58       *
  59       * @param array  $templates Array of templates located.
  60       * @param string $slug      Template part slug requested.
  61       * @param string $name      Template part name requested.
  62       * @param array  $args      Extra args to pass to locate_template().
  63       */
  64      $templates = apply_filters( 'bp_get_template_part', $templates, $slug, $name, $args );
  65  
  66      // Return the part that is found.
  67      return bp_locate_template( $templates, true, false, $args );
  68  }
  69  
  70  /**
  71   * Get an asset template part.
  72   *
  73   * Basically the same as {@link bp_get_template_part()}, but with 'assets/'
  74   * prepended to the slug.
  75   *
  76   * @since 2.6.0
  77   * @since 7.0.0 Added $args parameter.
  78   *
  79   * @see bp_get_template_part() for full documentation.
  80   *
  81   * @param string      $slug Template slug.
  82   * @param string|null $name Template name.
  83   * @param array       $args Optional. Extra args to pass to locate_template().
  84   * @return false|string
  85   */
  86  function bp_get_asset_template_part( $slug, $name = null, $args = array() ) {
  87      return bp_get_template_part( "assets/{$slug}", $name, $args );
  88  }
  89  
  90  /**
  91   * Get a dynamic template part.
  92   *
  93   * @since 9.0.0
  94   *
  95   * @param string $template     The Template Pack's relative path to the templata.
  96   *                             Optional.
  97   * @param string $type         Whether to use the template for JavaScript or PHP.
  98   *                             Optional. Defaults to `js`.
  99   * @param array  $tokens       The data to use to customize the template. Optional.
 100   * @param array  $allowed_tags The allowed tags to use. Optional.
 101   * @return string HTML/JS output.
 102   */
 103  function bp_get_dynamic_template_part( $template = '', $type = 'js', $tokens = array(), $allowed_tags = array() ) {
 104      $template_string = '';
 105  
 106      if ( ! $template ) {
 107          return '';
 108      }
 109  
 110      // Use the BP Theme Compat API to allow template override.
 111      $template_path = bp_locate_template( $template );
 112      if ( $template_path ) {
 113          $template_string = file_get_contents( $template_path );
 114      }
 115  
 116      if ( ! $template_string ) {
 117          return '';
 118      }
 119  
 120      if ( ! $allowed_tags ) {
 121          $allowed_tags = array(
 122              'li'   => array( 'class' => true ),
 123              'div'  => array( 'class' => true ),
 124              'span' => array( 'class' => true ),
 125              'a'    => array(
 126                  'href'            => true,
 127                  'class'           => true,
 128                  'data-bp-tooltip' => true,
 129              ),
 130              'img'  => array(
 131                  'src'     => true,
 132                  'class'   => true,
 133                  'loading' => true,
 134              ),
 135          );
 136      }
 137  
 138      if ( 'js' !== $type ) {
 139          $template_string = wp_kses( $template_string, $allowed_tags );
 140  
 141          return bp_core_replace_tokens_in_text( $template_string, $tokens );
 142      }
 143  
 144      return $template_string;
 145  }
 146  
 147  /**
 148   * Retrieve the name of the highest priority template file that exists.
 149   *
 150   * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which
 151   * inherit from a parent theme can just overload one file. If the template is
 152   * not found in either of those, it looks in the theme-compat folder last.
 153   *
 154   * @since 1.7.0
 155   * @since 7.0.0 Added $args parameter.
 156   *
 157   * @param string|array $template_names Template file(s) to search for, in order.
 158   * @param bool         $load           Optional. If true, the template file will be loaded when
 159   *                                     found. If false, the path will be returned. Default: false.
 160   * @param bool         $require_once   Optional. Whether to require_once or require. Has
 161   *                                     no effect if $load is false. Default: true.
 162   * @param array        $args           Optional. Extra args to pass to locate_template().
 163   * @return string The template filename if one is located.
 164   */
 165  function bp_locate_template( $template_names, $load = false, $require_once = true, $args = array() ) {
 166  
 167      // Bail when there are no templates to locate.
 168      if ( empty( $template_names ) ) {
 169          return false;
 170      }
 171  
 172      // No file found yet.
 173      $located            = false;
 174      $template_locations = bp_get_template_stack();
 175  
 176      // Try to find a template file.
 177      foreach ( (array) $template_names as $template_name ) {
 178  
 179          // Continue if template is empty.
 180          if ( empty( $template_name ) ) {
 181              continue;
 182          }
 183  
 184          // Trim off any slashes from the template name.
 185          $template_name  = ltrim( $template_name, '/' );
 186  
 187          // Loop through template stack.
 188          foreach ( (array) $template_locations as $template_location ) {
 189  
 190              // Continue if $template_location is empty.
 191              if ( empty( $template_location ) ) {
 192                  continue;
 193              }
 194  
 195              // Check child theme first.
 196              if ( file_exists( trailingslashit( $template_location ) . $template_name ) ) {
 197                  $located = trailingslashit( $template_location ) . $template_name;
 198                  break 2;
 199              }
 200          }
 201      }
 202  
 203      /**
 204       * This action exists only to follow the standard BuddyPress coding convention,
 205       * and should not be used to short-circuit any part of the template locater.
 206       *
 207       * If you want to override a specific template part, please either filter
 208       * 'bp_get_template_part' or add a new location to the template stack.
 209       */
 210      do_action( 'bp_locate_template', $located, $template_name, $template_names, $template_locations, $load, $require_once, $args );
 211  
 212      /**
 213       * Filter here to allow/disallow template loading.
 214       *
 215       * @since 2.5.0
 216       *
 217       * @param bool $value True to load the template, false otherwise.
 218       */
 219      $load_template = (bool) apply_filters( 'bp_locate_template_and_load', true );
 220  
 221      if ( $load_template && $load && ! empty( $located ) ) {
 222          load_template( $located, $require_once, $args );
 223      }
 224  
 225      return $located;
 226  }
 227  
 228  /**
 229   * Get file data of the highest priority asset that exists.
 230   *
 231   * Similar to {@link bp_locate_template()}, but for files like CSS and JS.
 232   *
 233   * @since 2.6.0
 234   *
 235   * @param string $filename Relative filename to search for.
 236   * @return false|array Array of asset data if one is located (includes absolute filepath and URI).
 237   *                     Boolean false on failure.
 238   */
 239  function bp_locate_template_asset( $filename ) {
 240      // Ensure assets can be located when running from /src/.
 241      if ( defined( 'BP_SOURCE_SUBDIRECTORY' ) && 'src' === BP_SOURCE_SUBDIRECTORY ) {
 242          $filename = str_replace( '.min', '', $filename );
 243      }
 244  
 245      // Use bp_locate_template() to find our asset.
 246      $located = bp_locate_template( $filename, false );
 247      if ( false === $located ) {
 248          return false;
 249      }
 250  
 251      // Set up data array.
 252      $data = array();
 253      $data['file'] = $data['uri'] = $located;
 254  
 255      $find = array(
 256          get_theme_root(),
 257          bp_get_theme_compat_dir()
 258      );
 259  
 260      $replace = array(
 261          get_theme_root_uri(),
 262          bp_get_theme_compat_url()
 263      );
 264  
 265      // Make sure URI path is relative to site URL.
 266      $data['uri'] = str_replace( $find, $replace, $data['uri'] );
 267  
 268      return $data;
 269  }
 270  
 271  /**
 272   * Register a new template stack location.
 273   *
 274   * This allows for templates to live in places beyond just the parent/child
 275   * relationship, to allow for custom template locations. Used in conjunction
 276   * with bp_locate_template(), this allows for easy template overrides.
 277   *
 278   * @since 1.7.0
 279   *
 280   * @param string $location_callback Callback function that returns the stack location.
 281   * @param int    $priority          Optional. The priority parameter as passed to
 282   *                                  add_filter(). Default: 10.
 283   * @return bool See {@link add_filter()}.
 284   */
 285  function bp_register_template_stack( $location_callback = '', $priority = 10 ) {
 286  
 287      // Bail if no location, or function/method is not callable.
 288      if ( empty( $location_callback ) || ! is_callable( $location_callback ) ) {
 289          return false;
 290      }
 291  
 292      // Add location callback to template stack.
 293      return add_filter( 'bp_template_stack', $location_callback, (int) $priority );
 294  }
 295  
 296  /**
 297   * Deregister a previously registered template stack location.
 298   *
 299   * @since 1.7.0
 300   *
 301   * @see bp_register_template_stack()
 302   *
 303   * @param string $location_callback Callback function that returns the stack location.
 304   * @param int    $priority          Optional. The priority parameter passed to
 305   *                                  {@link bp_register_template_stack()}. Default: 10.
 306   * @return bool See {@link remove_filter()}.
 307   */
 308  function bp_deregister_template_stack( $location_callback = '', $priority = 10 ) {
 309  
 310      // Bail if no location, or function/method is not callable.
 311      if ( empty( $location_callback ) || ! is_callable( $location_callback ) ) {
 312          return false;
 313      }
 314  
 315      // Add location callback to template stack.
 316      return remove_filter( 'bp_template_stack', $location_callback, (int) $priority );
 317  }
 318  
 319  /**
 320   * Get the "template stack", a list of registered directories where templates can be found.
 321   *
 322   * Calls the functions added to the 'bp_template_stack' filter hook, and return
 323   * an array of the template locations.
 324   *
 325   * @since 1.7.0
 326   *
 327   * @see bp_register_template_stack()
 328   *
 329   * @global array $wp_filter         Stores all of the filters.
 330   * @global array $merged_filters    Merges the filter hooks using this function.
 331   * @global array $wp_current_filter Stores the list of current filters with
 332   *                                  the current one last.
 333   * @return array The filtered value after all hooked functions are applied to it.
 334   */
 335  function bp_get_template_stack() {
 336      global $wp_filter, $merged_filters, $wp_current_filter;
 337  
 338      // Setup some default variables.
 339      $tag  = 'bp_template_stack';
 340      $args = $stack = array();
 341  
 342      // Add 'bp_template_stack' to the current filter array.
 343      $wp_current_filter[] = $tag;
 344  
 345      // Sort.
 346      if ( class_exists( 'WP_Hook' ) ) {
 347          $filter = $wp_filter[ $tag ]->callbacks;
 348      } else {
 349          $filter = &$wp_filter[ $tag ];
 350  
 351          if ( ! isset( $merged_filters[ $tag ] ) ) {
 352              ksort( $filter );
 353              $merged_filters[ $tag ] = true;
 354          }
 355      }
 356  
 357      // Ensure we're always at the beginning of the filter array.
 358      reset( $filter );
 359  
 360      // Loop through 'bp_template_stack' filters, and call callback functions.
 361      do {
 362          foreach( (array) current( $filter ) as $the_ ) {
 363              if ( ! is_null( $the_['function'] ) ) {
 364                  $args[1] = $stack;
 365                  $stack[] = call_user_func_array( $the_['function'], array_slice( $args, 1, (int) $the_['accepted_args'] ) );
 366              }
 367          }
 368      } while ( next( $filter ) !== false );
 369  
 370      // Remove 'bp_template_stack' from the current filter array.
 371      array_pop( $wp_current_filter );
 372  
 373      // Remove empties and duplicates.
 374      $stack = array_unique( array_filter( $stack ) );
 375  
 376      /**
 377       * Filters the "template stack" list of registered directories where templates can be found.
 378       *
 379       * @since 1.7.0
 380       *
 381       * @param array $stack Array of registered directories for template locations.
 382       */
 383      return (array) apply_filters( 'bp_get_template_stack', $stack ) ;
 384  }
 385  
 386  /**
 387   * Put a template part into an output buffer, and return it.
 388   *
 389   * @since 1.7.0
 390   * @since 7.0.0 Added $args parameter.
 391   *
 392   * @see bp_get_template_part() for a description of $slug, $name and $args params.
 393   *
 394   * @param string      $slug See {@link bp_get_template_part()}.
 395   * @param string|null $name See {@link bp_get_template_part()}.
 396   * @param bool        $echo If true, template content will be echoed. If false,
 397   *                          returned. Default: true.
 398   * @param array       $args See {@link bp_get_template_part()}.
 399   * @return string|null If $echo, returns the template content.
 400   */
 401  function bp_buffer_template_part( $slug, $name = null, $echo = true, $args = array() ) {
 402      ob_start();
 403  
 404      // Remove 'bp_replace_the_content' filter to prevent infinite loops.
 405      remove_filter( 'the_content', 'bp_replace_the_content' );
 406  
 407      bp_get_template_part( $slug, $name, $args );
 408  
 409      // Remove 'bp_replace_the_content' filter to prevent infinite loops.
 410      add_filter( 'the_content', 'bp_replace_the_content' );
 411  
 412      // Get the output buffer contents.
 413      $output = ob_get_clean();
 414  
 415      // Echo or return the output buffer contents.
 416      if ( true === $echo ) {
 417          echo $output;
 418      } else {
 419          return $output;
 420      }
 421  }
 422  
 423  /**
 424   * Retrieve the path to a template.
 425   *
 426   * Used to quickly retrieve the path of a template without including the file
 427   * extension. It will also check the parent theme and theme-compat theme with
 428   * the use of {@link bp_locate_template()}. Allows for more generic template
 429   * locations without the use of the other get_*_template() functions.
 430   *
 431   * @since 1.7.0
 432   *
 433   * @param string $type      Filename without extension.
 434   * @param array  $templates An optional list of template candidates.
 435   * @return string Full path to file.
 436   */
 437  function bp_get_query_template( $type, $templates = array() ) {
 438      $type = preg_replace( '|[^a-z0-9-]+|', '', $type );
 439  
 440      if ( empty( $templates ) ) {
 441          $templates = array( "{$type}.php" );
 442      }
 443  
 444      /**
 445       * Filters possible file paths to check for for a template.
 446       *
 447       * This is a variable filter based on the type passed into
 448       * bp_get_query_template.
 449       *
 450       * @since 1.7.0
 451       *
 452       * @param array $templates Array of template files already prepared.
 453       */
 454      $templates = apply_filters( "bp_get_{$type}_template", $templates );
 455  
 456      /*
 457       * Filter possible templates, try to match one, and set any BuddyPress theme
 458       * compat properties so they can be cross-checked later.
 459       */
 460      $templates = bp_set_theme_compat_templates( $templates );
 461      $template  = bp_locate_template( $templates );
 462  
 463      /*
 464       * The current theme is using the WordPress Full Site Editing feature.
 465       * BuddyPress then needs to use the WordPress template canvas to retrieve the community content.
 466       */
 467      if ( current_theme_supports( 'block-templates' ) && $template === get_theme_file_path( 'index.php' ) ) {
 468          $template = ABSPATH . WPINC . '/template-canvas.php';
 469      }
 470  
 471      $template = bp_set_theme_compat_template( $template );
 472  
 473      /**
 474       * Filters the path to a template file.
 475       *
 476       * This is a variable filter based on the type passed into
 477       * bp_get_query_template.
 478       *
 479       * @since 1.7.0
 480       *
 481       * @param string $template Path to the most appropriate found template file.
 482       */
 483      return apply_filters( "bp_{$type}_template", $template );
 484  }
 485  
 486  /**
 487   * Get the possible subdirectories to check for templates in.
 488   *
 489   * @since 1.7.0
 490   *
 491   * @param array $templates Templates we are looking for.
 492   * @return array Possible subfolders to look in.
 493   */
 494  function bp_get_template_locations( $templates = array() ) {
 495      $locations = array(
 496          'buddypress',
 497          'community',
 498          ''
 499      );
 500  
 501      /**
 502       * Filters the possible subdirectories to check for templates in.
 503       *
 504       * @since 1.7.0
 505       *
 506       * @param array $locations Array of subfolders to look in.
 507       * @param array $templates Array of templates we are looking for.
 508       */
 509      return apply_filters( 'bp_get_template_locations', $locations, $templates );
 510  }
 511  
 512  /**
 513   * Add template locations to template files being searched for.
 514   *
 515   * @since 1.7.0
 516   *
 517   * @param array $stacks Array of template locations.
 518   * @return array Array of all template locations registered so far.
 519   */
 520  function bp_add_template_stack_locations( $stacks = array() ) {
 521      $retval = array();
 522  
 523      // Get alternate locations.
 524      $locations = bp_get_template_locations();
 525  
 526      // Loop through locations and stacks and combine.
 527      foreach ( (array) $stacks as $stack ) {
 528          foreach ( (array) $locations as $custom_location ) {
 529              $retval[] = untrailingslashit( trailingslashit( $stack ) . $custom_location );
 530          }
 531      }
 532  
 533      /**
 534       * Filters the template locations to template files being searched for.
 535       *
 536       * @since 1.7.0
 537       *
 538       * @param array $value  Array of all template locations registered so far.
 539       * @param array $stacks Array of template locations.
 540       */
 541      return apply_filters( 'bp_add_template_stack_locations', array_unique( $retval ), $stacks );
 542  }
 543  
 544  /**
 545   * Add checks for BuddyPress conditions to 'parse_query' action.
 546   *
 547   * @since 1.7.0
 548   *
 549   * @param WP_Query $posts_query WP_Query object.
 550   */
 551  function bp_parse_query( $posts_query ) {
 552  
 553      // Bail if $posts_query is not the main loop.
 554      if ( ! $posts_query->is_main_query() ) {
 555          return;
 556      }
 557  
 558      // Bail if filters are suppressed on this query.
 559      if ( true == $posts_query->get( 'suppress_filters' ) ) {
 560          return;
 561      }
 562  
 563      // Bail if in admin.
 564      if ( is_admin() ) {
 565          return;
 566      }
 567  
 568      /**
 569       * Fires at the end of the bp_parse_query function.
 570       *
 571       * Allow BuddyPress components to parse the main query.
 572       *
 573       * @since 1.7.0
 574       *
 575       * @param WP_Query $posts_query WP_Query instance. Passed by reference.
 576       */
 577      do_action_ref_array( 'bp_parse_query', array( &$posts_query ) );
 578  }
 579  
 580  /**
 581   * Possibly intercept the template being loaded.
 582   *
 583   * Listens to the 'template_include' filter and waits for any BuddyPress specific
 584   * template condition to be met. If one is met and the template file exists,
 585   * it will be used; otherwise.
 586   *
 587   * Note that the _edit() checks are ahead of their counterparts, to prevent them
 588   * from being stomped on accident.
 589   *
 590   * @since 1.7.0
 591   *
 592   * @param string $template The path to the template file that is being used.
 593   * @return string The path to the template file that is being used.
 594   */
 595  function bp_template_include_theme_supports( $template = '' ) {
 596  
 597      /**
 598       * Filters whether or not to override the template being loaded in parent/child themes.
 599       *
 600       * @since 1.7.0
 601       *
 602       * @param bool   $value    Whether or not there is a file override. Default false.
 603       * @param string $template The path to the template file that is being used.
 604       */
 605      $new_template = apply_filters( 'bp_get_root_template', false, $template );
 606  
 607      // A BuddyPress template file was located, so override the WordPress
 608      // template and use it to switch off BuddyPress's theme compatibility.
 609      if ( ! empty( $new_template ) ) {
 610          $template = bp_set_template_included( $new_template );
 611      }
 612  
 613      /**
 614       * Filters the final template being loaded in parent/child themes.
 615       *
 616       * @since 1.7.0
 617       *
 618       * @param string $template The path to the template file that is being used.
 619       */
 620      return apply_filters( 'bp_template_include_theme_supports', $template );
 621  }
 622  
 623  /**
 624   * Set the included template.
 625   *
 626   * @since 1.8.0
 627   *
 628   * @param mixed $template Default: false.
 629   * @return mixed False if empty. Template name if template included.
 630   */
 631  function bp_set_template_included( $template = false ) {
 632      buddypress()->theme_compat->found_template = $template;
 633  
 634      return buddypress()->theme_compat->found_template;
 635  }
 636  
 637  /**
 638   * Is a BuddyPress template being included?
 639   *
 640   * @since 1.8.0
 641   *
 642   * @return bool True if yes, false if no.
 643   */
 644  function bp_is_template_included() {
 645      return isset( buddypress()->theme_compat->found_template ) && buddypress()->theme_compat->found_template;
 646  }
 647  
 648  /**
 649   * Attempt to load a custom BP functions file, similar to each themes functions.php file.
 650   *
 651   * @since 1.7.0
 652   *
 653   * @global string $pagenow
 654   */
 655  function bp_load_theme_functions() {
 656      global $pagenow, $wp_query;
 657  
 658      // Do not load our custom BP functions file if theme compat is disabled.
 659      if ( ! bp_use_theme_compat_with_current_theme() ) {
 660          return;
 661      }
 662  
 663      // Do not include on BuddyPress deactivation.
 664      if ( bp_is_deactivation() ) {
 665          return;
 666      }
 667  
 668      // If the $wp_query global is empty (the main query has not been run,
 669      // or has been reset), load_template() will fail at setting certain
 670      // global values. This does not happen on a normal page load, but can
 671      // cause problems when running automated tests.
 672      if ( ! is_a( $wp_query, 'WP_Query' ) ) {
 673          return;
 674      }
 675  
 676      // Only include if not installing or if activating via wp-activate.php.
 677      if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) {
 678          bp_locate_template( 'buddypress-functions.php', true );
 679      }
 680  }
 681  
 682  /**
 683   * Get the templates to use as the endpoint for BuddyPress template parts.
 684   *
 685   * @since 1.7.0
 686   * @since 2.4.0 Added singular.php to stack
 687   *
 688   * @return string Possible root level wrapper template files.
 689   */
 690  function bp_get_theme_compat_templates() {
 691      return bp_get_query_template( 'buddypress', array(
 692          'plugin-buddypress.php',
 693          'buddypress.php',
 694          'community.php',
 695          'generic.php',
 696          'page.php',
 697          'single.php',
 698          'singular.php',
 699          'index.php'
 700      ) );
 701  }


Generated: Sat Apr 27 01:00:55 2024 Cross-referenced by PHPXref 0.7.1