[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Template loading functions. 4 * 5 * @package WordPress 6 * @subpackage Template 7 */ 8 9 /** 10 * Retrieves path to a template. 11 * 12 * Used to quickly retrieve the path of a template without including the file 13 * extension. It will also check the parent theme, if the file exists, with 14 * the use of locate_template(). Allows for more generic template location 15 * without the use of the other get_*_template() functions. 16 * 17 * @since 1.5.0 18 * 19 * @param string $type Filename without extension. 20 * @param string[] $templates An optional list of template candidates. 21 * @return string Full path to template file. 22 */ 23 function get_query_template( $type, $templates = array() ) { 24 $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); 25 26 if ( empty( $templates ) ) { 27 $templates = array( "{$type}.php" ); 28 } 29 30 /** 31 * Filters the list of template filenames that are searched for when retrieving a template to use. 32 * 33 * The dynamic portion of the hook name, `$type`, refers to the filename -- minus the file 34 * extension and any non-alphanumeric characters delimiting words -- of the file to load. 35 * The last element in the array should always be the fallback template for this query type. 36 * 37 * Possible hook names include: 38 * 39 * - `404_template_hierarchy` 40 * - `archive_template_hierarchy` 41 * - `attachment_template_hierarchy` 42 * - `author_template_hierarchy` 43 * - `category_template_hierarchy` 44 * - `date_template_hierarchy` 45 * - `embed_template_hierarchy` 46 * - `frontpage_template_hierarchy` 47 * - `home_template_hierarchy` 48 * - `index_template_hierarchy` 49 * - `page_template_hierarchy` 50 * - `paged_template_hierarchy` 51 * - `privacypolicy_template_hierarchy` 52 * - `search_template_hierarchy` 53 * - `single_template_hierarchy` 54 * - `singular_template_hierarchy` 55 * - `tag_template_hierarchy` 56 * - `taxonomy_template_hierarchy` 57 * 58 * @since 4.7.0 59 * 60 * @param string[] $templates A list of template candidates, in descending order of priority. 61 */ 62 $templates = apply_filters( "{$type}_template_hierarchy", $templates ); 63 64 $template = locate_template( $templates ); 65 66 $template = locate_block_template( $template, $type, $templates ); 67 68 /** 69 * Filters the path of the queried template by type. 70 * 71 * The dynamic portion of the hook name, `$type`, refers to the filename -- minus the file 72 * extension and any non-alphanumeric characters delimiting words -- of the file to load. 73 * This hook also applies to various types of files loaded as part of the Template Hierarchy. 74 * 75 * Possible hook names include: 76 * 77 * - `404_template` 78 * - `archive_template` 79 * - `attachment_template` 80 * - `author_template` 81 * - `category_template` 82 * - `date_template` 83 * - `embed_template` 84 * - `frontpage_template` 85 * - `home_template` 86 * - `index_template` 87 * - `page_template` 88 * - `paged_template` 89 * - `privacypolicy_template` 90 * - `search_template` 91 * - `single_template` 92 * - `singular_template` 93 * - `tag_template` 94 * - `taxonomy_template` 95 * 96 * @since 1.5.0 97 * @since 4.8.0 The `$type` and `$templates` parameters were added. 98 * 99 * @param string $template Path to the template. See locate_template(). 100 * @param string $type Sanitized filename without extension. 101 * @param string[] $templates A list of template candidates, in descending order of priority. 102 */ 103 return apply_filters( "{$type}_template", $template, $type, $templates ); 104 } 105 106 /** 107 * Retrieves path of index template in current or parent template. 108 * 109 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 110 * and {@see '$type_template'} dynamic hooks, where `$type` is 'index'. 111 * 112 * @since 3.0.0 113 * 114 * @see get_query_template() 115 * 116 * @return string Full path to index template file. 117 */ 118 function get_index_template() { 119 return get_query_template( 'index' ); 120 } 121 122 /** 123 * Retrieves path of 404 template in current or parent template. 124 * 125 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 126 * and {@see '$type_template'} dynamic hooks, where `$type` is '404'. 127 * 128 * @since 1.5.0 129 * 130 * @see get_query_template() 131 * 132 * @return string Full path to 404 template file. 133 */ 134 function get_404_template() { 135 return get_query_template( '404' ); 136 } 137 138 /** 139 * Retrieves path of archive template in current or parent template. 140 * 141 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 142 * and {@see '$type_template'} dynamic hooks, where `$type` is 'archive'. 143 * 144 * @since 1.5.0 145 * 146 * @see get_query_template() 147 * 148 * @return string Full path to archive template file. 149 */ 150 function get_archive_template() { 151 $post_types = array_filter( (array) get_query_var( 'post_type' ) ); 152 153 $templates = array(); 154 155 if ( count( $post_types ) === 1 ) { 156 $post_type = reset( $post_types ); 157 $templates[] = "archive-{$post_type}.php"; 158 } 159 $templates[] = 'archive.php'; 160 161 return get_query_template( 'archive', $templates ); 162 } 163 164 /** 165 * Retrieves path of post type archive template in current or parent template. 166 * 167 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 168 * and {@see '$type_template'} dynamic hooks, where `$type` is 'archive'. 169 * 170 * @since 3.7.0 171 * 172 * @see get_archive_template() 173 * 174 * @return string Full path to archive template file. 175 */ 176 function get_post_type_archive_template() { 177 $post_type = get_query_var( 'post_type' ); 178 if ( is_array( $post_type ) ) { 179 $post_type = reset( $post_type ); 180 } 181 182 $obj = get_post_type_object( $post_type ); 183 if ( ! ( $obj instanceof WP_Post_Type ) || ! $obj->has_archive ) { 184 return ''; 185 } 186 187 return get_archive_template(); 188 } 189 190 /** 191 * Retrieves path of author template in current or parent template. 192 * 193 * The hierarchy for this template looks like: 194 * 195 * 1. author-{nicename}.php 196 * 2. author-{id}.php 197 * 3. author.php 198 * 199 * An example of this is: 200 * 201 * 1. author-john.php 202 * 2. author-1.php 203 * 3. author.php 204 * 205 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 206 * and {@see '$type_template'} dynamic hooks, where `$type` is 'author'. 207 * 208 * @since 1.5.0 209 * 210 * @see get_query_template() 211 * 212 * @return string Full path to author template file. 213 */ 214 function get_author_template() { 215 $author = get_queried_object(); 216 217 $templates = array(); 218 219 if ( $author instanceof WP_User ) { 220 $templates[] = "author-{$author->user_nicename}.php"; 221 $templates[] = "author-{$author->ID}.php"; 222 } 223 $templates[] = 'author.php'; 224 225 return get_query_template( 'author', $templates ); 226 } 227 228 /** 229 * Retrieves path of category template in current or parent template. 230 * 231 * The hierarchy for this template looks like: 232 * 233 * 1. category-{slug}.php 234 * 2. category-{id}.php 235 * 3. category.php 236 * 237 * An example of this is: 238 * 239 * 1. category-news.php 240 * 2. category-2.php 241 * 3. category.php 242 * 243 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 244 * and {@see '$type_template'} dynamic hooks, where `$type` is 'category'. 245 * 246 * @since 1.5.0 247 * @since 4.7.0 The decoded form of `category-{slug}.php` was added to the top of the 248 * template hierarchy when the category slug contains multibyte characters. 249 * 250 * @see get_query_template() 251 * 252 * @return string Full path to category template file. 253 */ 254 function get_category_template() { 255 $category = get_queried_object(); 256 257 $templates = array(); 258 259 if ( ! empty( $category->slug ) ) { 260 261 $slug_decoded = urldecode( $category->slug ); 262 if ( $slug_decoded !== $category->slug ) { 263 $templates[] = "category-{$slug_decoded}.php"; 264 } 265 266 $templates[] = "category-{$category->slug}.php"; 267 $templates[] = "category-{$category->term_id}.php"; 268 } 269 $templates[] = 'category.php'; 270 271 return get_query_template( 'category', $templates ); 272 } 273 274 /** 275 * Retrieves path of tag template in current or parent template. 276 * 277 * The hierarchy for this template looks like: 278 * 279 * 1. tag-{slug}.php 280 * 2. tag-{id}.php 281 * 3. tag.php 282 * 283 * An example of this is: 284 * 285 * 1. tag-wordpress.php 286 * 2. tag-3.php 287 * 3. tag.php 288 * 289 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 290 * and {@see '$type_template'} dynamic hooks, where `$type` is 'tag'. 291 * 292 * @since 2.3.0 293 * @since 4.7.0 The decoded form of `tag-{slug}.php` was added to the top of the 294 * template hierarchy when the tag slug contains multibyte characters. 295 * 296 * @see get_query_template() 297 * 298 * @return string Full path to tag template file. 299 */ 300 function get_tag_template() { 301 $tag = get_queried_object(); 302 303 $templates = array(); 304 305 if ( ! empty( $tag->slug ) ) { 306 307 $slug_decoded = urldecode( $tag->slug ); 308 if ( $slug_decoded !== $tag->slug ) { 309 $templates[] = "tag-{$slug_decoded}.php"; 310 } 311 312 $templates[] = "tag-{$tag->slug}.php"; 313 $templates[] = "tag-{$tag->term_id}.php"; 314 } 315 $templates[] = 'tag.php'; 316 317 return get_query_template( 'tag', $templates ); 318 } 319 320 /** 321 * Retrieves path of custom taxonomy term template in current or parent template. 322 * 323 * The hierarchy for this template looks like: 324 * 325 * 1. taxonomy-{taxonomy_slug}-{term_slug}.php 326 * 2. taxonomy-{taxonomy_slug}-{term_id}.php 327 * 3. taxonomy-{taxonomy_slug}.php 328 * 4. taxonomy.php 329 * 330 * An example of this is: 331 * 332 * 1. taxonomy-location-texas.php 333 * 2. taxonomy-location-67.php 334 * 3. taxonomy-location.php 335 * 4. taxonomy.php 336 * 337 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 338 * and {@see '$type_template'} dynamic hooks, where `$type` is 'taxonomy'. 339 * 340 * @since 2.5.0 341 * @since 4.7.0 The decoded form of `taxonomy-{taxonomy_slug}-{term_slug}.php` was added to the top of the 342 * template hierarchy when the term slug contains multibyte characters. 343 * @since 6.9.0 Added `taxonomy-{taxonomy_slug}-{term_id}.php` to the hierarchy. 344 * 345 * @see get_query_template() 346 * 347 * @return string Full path to custom taxonomy term template file. 348 */ 349 function get_taxonomy_template() { 350 $term = get_queried_object(); 351 352 $templates = array(); 353 354 if ( ! empty( $term->slug ) ) { 355 $taxonomy = $term->taxonomy; 356 357 $slug_decoded = urldecode( $term->slug ); 358 if ( $slug_decoded !== $term->slug ) { 359 $templates[] = "taxonomy-$taxonomy-{$slug_decoded}.php"; 360 } 361 362 $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; 363 $templates[] = "taxonomy-$taxonomy-{$term->term_id}.php"; 364 $templates[] = "taxonomy-$taxonomy.php"; 365 } 366 $templates[] = 'taxonomy.php'; 367 368 return get_query_template( 'taxonomy', $templates ); 369 } 370 371 /** 372 * Retrieves path of date template in current or parent template. 373 * 374 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 375 * and {@see '$type_template'} dynamic hooks, where `$type` is 'date'. 376 * 377 * @since 1.5.0 378 * 379 * @see get_query_template() 380 * 381 * @return string Full path to date template file. 382 */ 383 function get_date_template() { 384 return get_query_template( 'date' ); 385 } 386 387 /** 388 * Retrieves path of home template in current or parent template. 389 * 390 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 391 * and {@see '$type_template'} dynamic hooks, where `$type` is 'home'. 392 * 393 * @since 1.5.0 394 * 395 * @see get_query_template() 396 * 397 * @return string Full path to home template file. 398 */ 399 function get_home_template() { 400 $templates = array( 'home.php', 'index.php' ); 401 402 return get_query_template( 'home', $templates ); 403 } 404 405 /** 406 * Retrieves path of front page template in current or parent template. 407 * 408 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 409 * and {@see '$type_template'} dynamic hooks, where `$type` is 'frontpage'. 410 * 411 * @since 3.0.0 412 * 413 * @see get_query_template() 414 * 415 * @return string Full path to front page template file. 416 */ 417 function get_front_page_template() { 418 $templates = array( 'front-page.php' ); 419 420 return get_query_template( 'frontpage', $templates ); 421 } 422 423 /** 424 * Retrieves path of Privacy Policy page template in current or parent template. 425 * 426 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 427 * and {@see '$type_template'} dynamic hooks, where `$type` is 'privacypolicy'. 428 * 429 * @since 5.2.0 430 * 431 * @see get_query_template() 432 * 433 * @return string Full path to privacy policy template file. 434 */ 435 function get_privacy_policy_template() { 436 $templates = array( 'privacy-policy.php' ); 437 438 return get_query_template( 'privacypolicy', $templates ); 439 } 440 441 /** 442 * Retrieves path of page template in current or parent template. 443 * 444 * Note: For block themes, use locate_block_template() function instead. 445 * 446 * The hierarchy for this template looks like: 447 * 448 * 1. {Page Template}.php 449 * 2. page-{page_name}.php 450 * 3. page-{id}.php 451 * 4. page.php 452 * 453 * An example of this is: 454 * 455 * 1. page-templates/full-width.php 456 * 2. page-about.php 457 * 3. page-4.php 458 * 4. page.php 459 * 460 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 461 * and {@see '$type_template'} dynamic hooks, where `$type` is 'page'. 462 * 463 * @since 1.5.0 464 * @since 4.7.0 The decoded form of `page-{page_name}.php` was added to the top of the 465 * template hierarchy when the page name contains multibyte characters. 466 * 467 * @see get_query_template() 468 * 469 * @return string Full path to page template file. 470 */ 471 function get_page_template() { 472 $id = get_queried_object_id(); 473 $template = get_page_template_slug(); 474 $pagename = get_query_var( 'pagename' ); 475 476 if ( ! $pagename && $id ) { 477 /* 478 * If a static page is set as the front page, $pagename will not be set. 479 * Retrieve it from the queried object. 480 */ 481 $post = get_queried_object(); 482 if ( $post ) { 483 $pagename = $post->post_name; 484 } 485 } 486 487 $templates = array(); 488 if ( $template && 0 === validate_file( $template ) ) { 489 $templates[] = $template; 490 } 491 if ( $pagename ) { 492 $pagename_decoded = urldecode( $pagename ); 493 if ( $pagename_decoded !== $pagename ) { 494 $templates[] = "page-{$pagename_decoded}.php"; 495 } 496 $templates[] = "page-{$pagename}.php"; 497 } 498 if ( $id ) { 499 $templates[] = "page-{$id}.php"; 500 } 501 $templates[] = 'page.php'; 502 503 return get_query_template( 'page', $templates ); 504 } 505 506 /** 507 * Retrieves path of search template in current or parent template. 508 * 509 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 510 * and {@see '$type_template'} dynamic hooks, where `$type` is 'search'. 511 * 512 * @since 1.5.0 513 * 514 * @see get_query_template() 515 * 516 * @return string Full path to search template file. 517 */ 518 function get_search_template() { 519 return get_query_template( 'search' ); 520 } 521 522 /** 523 * Retrieves path of single template in current or parent template. Applies to single Posts, 524 * single Attachments, and single custom post types. 525 * 526 * The hierarchy for this template looks like: 527 * 528 * 1. {Post Type Template}.php 529 * 2. single-{post_type}-{post_name}.php 530 * 3. single-{post_type}.php 531 * 4. single.php 532 * 533 * An example of this is: 534 * 535 * 1. templates/full-width.php 536 * 2. single-post-hello-world.php 537 * 3. single-post.php 538 * 4. single.php 539 * 540 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 541 * and {@see '$type_template'} dynamic hooks, where `$type` is 'single'. 542 * 543 * @since 1.5.0 544 * @since 4.4.0 `single-{post_type}-{post_name}.php` was added to the top of the template hierarchy. 545 * @since 4.7.0 The decoded form of `single-{post_type}-{post_name}.php` was added to the top of the 546 * template hierarchy when the post name contains multibyte characters. 547 * @since 4.7.0 `{Post Type Template}.php` was added to the top of the template hierarchy. 548 * 549 * @see get_query_template() 550 * 551 * @return string Full path to single template file. 552 */ 553 function get_single_template() { 554 $object = get_queried_object(); 555 556 $templates = array(); 557 558 if ( ! empty( $object->post_type ) ) { 559 $template = get_page_template_slug( $object ); 560 if ( $template && 0 === validate_file( $template ) ) { 561 $templates[] = $template; 562 } 563 564 $name_decoded = urldecode( $object->post_name ); 565 if ( $name_decoded !== $object->post_name ) { 566 $templates[] = "single-{$object->post_type}-{$name_decoded}.php"; 567 } 568 569 $templates[] = "single-{$object->post_type}-{$object->post_name}.php"; 570 $templates[] = "single-{$object->post_type}.php"; 571 } 572 573 $templates[] = 'single.php'; 574 575 return get_query_template( 'single', $templates ); 576 } 577 578 /** 579 * Retrieves an embed template path in the current or parent template. 580 * 581 * The hierarchy for this template looks like: 582 * 583 * 1. embed-{post_type}-{post_format}.php 584 * 2. embed-{post_type}.php 585 * 3. embed.php 586 * 587 * An example of this is: 588 * 589 * 1. embed-post-audio.php 590 * 2. embed-post.php 591 * 3. embed.php 592 * 593 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 594 * and {@see '$type_template'} dynamic hooks, where `$type` is 'embed'. 595 * 596 * @since 4.5.0 597 * 598 * @see get_query_template() 599 * 600 * @return string Full path to embed template file. 601 */ 602 function get_embed_template() { 603 $object = get_queried_object(); 604 605 $templates = array(); 606 607 if ( ! empty( $object->post_type ) ) { 608 $post_format = get_post_format( $object ); 609 if ( $post_format ) { 610 $templates[] = "embed-{$object->post_type}-{$post_format}.php"; 611 } 612 $templates[] = "embed-{$object->post_type}.php"; 613 } 614 615 $templates[] = 'embed.php'; 616 617 return get_query_template( 'embed', $templates ); 618 } 619 620 /** 621 * Retrieves the path of the singular template in current or parent template. 622 * 623 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 624 * and {@see '$type_template'} dynamic hooks, where `$type` is 'singular'. 625 * 626 * @since 4.3.0 627 * 628 * @see get_query_template() 629 * 630 * @return string Full path to singular template file 631 */ 632 function get_singular_template() { 633 return get_query_template( 'singular' ); 634 } 635 636 /** 637 * Retrieves path of attachment template in current or parent template. 638 * 639 * The hierarchy for this template looks like: 640 * 641 * 1. {mime_type}-{sub_type}.php 642 * 2. {sub_type}.php 643 * 3. {mime_type}.php 644 * 4. attachment.php 645 * 646 * An example of this is: 647 * 648 * 1. image-jpeg.php 649 * 2. jpeg.php 650 * 3. image.php 651 * 4. attachment.php 652 * 653 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 654 * and {@see '$type_template'} dynamic hooks, where `$type` is 'attachment'. 655 * 656 * @since 2.0.0 657 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical. 658 * 659 * @see get_query_template() 660 * 661 * @return string Full path to attachment template file. 662 */ 663 function get_attachment_template() { 664 $attachment = get_queried_object(); 665 666 $templates = array(); 667 668 if ( $attachment ) { 669 if ( str_contains( $attachment->post_mime_type, '/' ) ) { 670 list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); 671 } else { 672 list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); 673 } 674 675 if ( ! empty( $subtype ) ) { 676 $templates[] = "{$type}-{$subtype}.php"; 677 $templates[] = "{$subtype}.php"; 678 } 679 $templates[] = "{$type}.php"; 680 } 681 $templates[] = 'attachment.php'; 682 683 return get_query_template( 'attachment', $templates ); 684 } 685 686 /** 687 * Set up the globals used for template loading. 688 * 689 * @since 6.5.0 690 * 691 * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. 692 * @global string $wp_template_path Path to current theme's template directory. 693 */ 694 function wp_set_template_globals() { 695 global $wp_stylesheet_path, $wp_template_path; 696 697 $wp_stylesheet_path = get_stylesheet_directory(); 698 $wp_template_path = get_template_directory(); 699 } 700 701 /** 702 * Retrieves the name of the highest priority template file that exists. 703 * 704 * Searches in the stylesheet directory before the template directory and 705 * wp-includes/theme-compat so that themes which inherit from a parent theme 706 * can just overload one file. 707 * 708 * @since 2.7.0 709 * @since 5.5.0 The `$args` parameter was added. 710 * 711 * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. 712 * @global string $wp_template_path Path to current theme's template directory. 713 * 714 * @param string|array $template_names Template file(s) to search for, in order. 715 * @param bool $load If true the template file will be loaded if it is found. 716 * @param bool $load_once Whether to require_once or require. Has no effect if `$load` is false. 717 * Default true. 718 * @param array $args Optional. Additional arguments passed to the template. 719 * Default empty array. 720 * @return string The template filename if one is located. 721 */ 722 function locate_template( $template_names, $load = false, $load_once = true, $args = array() ) { 723 global $wp_stylesheet_path, $wp_template_path; 724 725 if ( ! isset( $wp_stylesheet_path ) || ! isset( $wp_template_path ) ) { 726 wp_set_template_globals(); 727 } 728 729 $is_child_theme = is_child_theme(); 730 731 $located = ''; 732 foreach ( (array) $template_names as $template_name ) { 733 if ( ! $template_name ) { 734 continue; 735 } 736 if ( file_exists( $wp_stylesheet_path . '/' . $template_name ) ) { 737 $located = $wp_stylesheet_path . '/' . $template_name; 738 break; 739 } elseif ( $is_child_theme && file_exists( $wp_template_path . '/' . $template_name ) ) { 740 $located = $wp_template_path . '/' . $template_name; 741 break; 742 } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) { 743 $located = ABSPATH . WPINC . '/theme-compat/' . $template_name; 744 break; 745 } 746 } 747 748 if ( $load && '' !== $located ) { 749 load_template( $located, $load_once, $args ); 750 } 751 752 return $located; 753 } 754 755 /** 756 * Requires the template file with WordPress environment. 757 * 758 * The globals are set up for the template file to ensure that the WordPress 759 * environment is available from within the function. The query variables are 760 * also available. 761 * 762 * @since 1.5.0 763 * @since 5.5.0 The `$args` parameter was added. 764 * 765 * @global array $posts 766 * @global WP_Post $post Global post object. 767 * @global bool $wp_did_header 768 * @global WP_Query $wp_query WordPress Query object. 769 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 770 * @global wpdb $wpdb WordPress database abstraction object. 771 * @global string $wp_version 772 * @global WP $wp Current WordPress environment instance. 773 * @global int $id 774 * @global WP_Comment $comment Global comment object. 775 * @global int $user_ID 776 * 777 * @param string $_template_file Path to template file. 778 * @param bool $load_once Whether to require_once or require. Default true. 779 * @param array $args Optional. Additional arguments passed to the template. 780 * Default empty array. 781 */ 782 function load_template( $_template_file, $load_once = true, $args = array() ) { 783 global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; 784 785 if ( is_array( $wp_query->query_vars ) ) { 786 /* 787 * This use of extract() cannot be removed. There are many possible ways that 788 * templates could depend on variables that it creates existing, and no way to 789 * detect and deprecate it. 790 * 791 * Passing the EXTR_SKIP flag is the safest option, ensuring globals and 792 * function variables cannot be overwritten. 793 */ 794 // phpcs:ignore WordPress.PHP.DontExtract.extract_extract 795 extract( $wp_query->query_vars, EXTR_SKIP ); 796 } 797 798 if ( isset( $s ) ) { 799 $s = esc_attr( $s ); 800 } 801 802 /** 803 * Fires before a template file is loaded. 804 * 805 * @since 6.1.0 806 * 807 * @param string $_template_file The full path to the template file. 808 * @param bool $load_once Whether to require_once or require. 809 * @param array $args Additional arguments passed to the template. 810 */ 811 do_action( 'wp_before_load_template', $_template_file, $load_once, $args ); 812 813 if ( $load_once ) { 814 require_once $_template_file; 815 } else { 816 require $_template_file; 817 } 818 819 /** 820 * Fires after a template file is loaded. 821 * 822 * @since 6.1.0 823 * 824 * @param string $_template_file The full path to the template file. 825 * @param bool $load_once Whether to require_once or require. 826 * @param array $args Additional arguments passed to the template. 827 */ 828 do_action( 'wp_after_load_template', $_template_file, $load_once, $args ); 829 } 830 831 /** 832 * Checks whether the template should be output buffered for enhancement. 833 * 834 * By default, an output buffer is only started if a {@see 'wp_template_enhancement_output_buffer'} filter has been 835 * added by the time a template is included at the {@see 'wp_before_include_template'} action. This allows template 836 * responses to be streamed as much as possible when no template enhancements are registered to apply. 837 * 838 * @since 6.9.0 839 * 840 * @return bool Whether the template should be output-buffered for enhancement. 841 */ 842 function wp_should_output_buffer_template_for_enhancement(): bool { 843 /** 844 * Filters whether the template should be output-buffered for enhancement. 845 * 846 * By default, an output buffer is only started if a {@see 'wp_template_enhancement_output_buffer'} filter has been 847 * added. For this default to apply, a filter must be added by the time the template is included at the 848 * {@see 'wp_before_include_template'} action. This allows template responses to be streamed as much as possible 849 * when no template enhancements are registered to apply. This filter allows a site to opt in to adding such 850 * template enhancement filters during the rendering of the template. 851 * 852 * @since 6.9.0 853 * 854 * @param bool $use_output_buffer Whether an output buffer is started. 855 */ 856 return (bool) apply_filters( 'wp_should_output_buffer_template_for_enhancement', has_filter( 'wp_template_enhancement_output_buffer' ) ); 857 } 858 859 /** 860 * Starts the template enhancement output buffer. 861 * 862 * This function is called immediately before the template is included. 863 * 864 * @since 6.9.0 865 * 866 * @return bool Whether the output buffer successfully started. 867 */ 868 function wp_start_template_enhancement_output_buffer(): bool { 869 if ( ! wp_should_output_buffer_template_for_enhancement() ) { 870 return false; 871 } 872 873 $started = ob_start( 874 'wp_finalize_template_enhancement_output_buffer', 875 0, // Unlimited buffer size so that entire output is passed to the filter. 876 /* 877 * Instead of the default PHP_OUTPUT_HANDLER_STDFLAGS (cleanable, flushable, and removable) being used for 878 * flags, the PHP_OUTPUT_HANDLER_FLUSHABLE flag must be omitted. If the buffer were flushable, then each time 879 * that ob_flush() is called, a fragment of the output would be sent into the output buffer callback. This 880 * output buffer is intended to capture the entire response for processing, as indicated by the chunk size of 0. 881 * So the buffer does not allow flushing to ensure the entire buffer can be processed, such as for optimizing an 882 * entire HTML document, where markup in the HEAD may need to be adjusted based on markup that appears late in 883 * the BODY. 884 * 885 * If this ends up being problematic, then PHP_OUTPUT_HANDLER_FLUSHABLE could be added to the $flags and the 886 * output buffer callback could check if the phase is PHP_OUTPUT_HANDLER_FLUSH and abort any subsequent 887 * processing while also emitting a _doing_it_wrong(). 888 * 889 * The output buffer needs to be removable because WordPress calls wp_ob_end_flush_all() and then calls 890 * wp_cache_close(). If the buffers are not all flushed before wp_cache_close() is closed, then some output buffer 891 * handlers (e.g. for caching plugins) may fail to be able to store the page output in the object cache. 892 * See <https://github.com/WordPress/performance/pull/1317#issuecomment-2271955356>. 893 */ 894 PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE 895 ); 896 897 if ( $started ) { 898 /** 899 * Fires when the template enhancement output buffer has started. 900 * 901 * @since 6.9.0 902 */ 903 do_action( 'wp_template_enhancement_output_buffer_started' ); 904 } 905 906 return $started; 907 } 908 909 /** 910 * Finalizes the template enhancement output buffer. 911 * 912 * Checks to see if the output buffer is complete and contains HTML. If so, runs the content through 913 * the `wp_template_enhancement_output_buffer` filter. If not, the original content is returned. 914 * 915 * @since 6.9.0 916 * 917 * @see wp_start_template_enhancement_output_buffer() 918 * 919 * @param string $output Output buffer. 920 * @param int $phase Phase. 921 * @return string Finalized output buffer. 922 */ 923 function wp_finalize_template_enhancement_output_buffer( string $output, int $phase ): string { 924 // When the output is being cleaned (e.g. pending template is replaced with error page), do not send it through the filter. 925 if ( ( $phase & PHP_OUTPUT_HANDLER_CLEAN ) !== 0 ) { 926 return $output; 927 } 928 929 // Detect if the response is an HTML content type. 930 $is_html_content_type = null; 931 $html_content_types = array( 'text/html', 'application/xhtml+xml' ); 932 foreach ( headers_list() as $header ) { 933 $header_parts = explode( ':', strtolower( $header ), 2 ); 934 if ( 935 count( $header_parts ) === 2 && 936 'content-type' === $header_parts[0] 937 ) { 938 /* 939 * This is looking for very specific content types, therefore it 940 * doesn’t need to fully parse the header’s value. Instead, it needs 941 * only assert that the content type is one of the static HTML types. 942 * 943 * Example: 944 * 945 * Content-Type: text/html; charset=utf8 946 * Content-Type: text/html ;charset=latin4 947 * Content-Type:application/xhtml+xml 948 */ 949 $media_type = trim( strtok( $header_parts[1], ';' ), " \t" ); 950 $is_html_content_type = in_array( $media_type, $html_content_types, true ); 951 break; // PHP only sends the first Content-Type header in the list. 952 } 953 } 954 if ( null === $is_html_content_type ) { 955 $is_html_content_type = in_array( ini_get( 'default_mimetype' ), $html_content_types, true ); 956 } 957 958 // If the content type is not HTML, short-circuit since it is not relevant for enhancement. 959 if ( ! $is_html_content_type ) { 960 return $output; 961 } 962 963 $filtered_output = $output; 964 965 /** 966 * Filters the template enhancement output buffer prior to sending to the client. 967 * 968 * This filter only applies the HTML output of an included template. This filter is a progressive enhancement 969 * intended for applications such as optimizing markup to improve frontend page load performance. Sites must not 970 * depend on this filter applying since they may opt to stream the responses instead. Callbacks for this filter are 971 * highly discouraged from using regular expressions to do any kind of replacement on the output. Use the HTML API 972 * (either `WP_HTML_Tag_Processor` or `WP_HTML_Processor`), or else use {@see DOM\HtmlDocument} as of PHP 8.4 which 973 * fully supports HTML5. 974 * 975 * @since 6.9.0 976 * 977 * @param string $filtered_output HTML template enhancement output buffer. 978 * @param string $output Original HTML template output buffer. 979 */ 980 return (string) apply_filters( 'wp_template_enhancement_output_buffer', $filtered_output, $output ); 981 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Oct 23 08:20:05 2025 | Cross-referenced by PHPXref |