[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Template loading functions. 4 * 5 * @package WordPress 6 * @subpackage Template 7 */ 8 9 /** 10 * Retrieve 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 /** 67 * Filters the path of the queried template by type. 68 * 69 * The dynamic portion of the hook name, `$type`, refers to the filename -- minus the file 70 * extension and any non-alphanumeric characters delimiting words -- of the file to load. 71 * This hook also applies to various types of files loaded as part of the Template Hierarchy. 72 * 73 * Possible hook names include: 74 * 75 * - `404_template` 76 * - `archive_template` 77 * - `attachment_template` 78 * - `author_template` 79 * - `category_template` 80 * - `date_template` 81 * - `embed_template` 82 * - `frontpage_template` 83 * - `home_template` 84 * - `index_template` 85 * - `page_template` 86 * - `paged_template` 87 * - `privacypolicy_template` 88 * - `search_template` 89 * - `single_template` 90 * - `singular_template` 91 * - `tag_template` 92 * - `taxonomy_template` 93 * 94 * @since 1.5.0 95 * @since 4.8.0 The `$type` and `$templates` parameters were added. 96 * 97 * @param string $template Path to the template. See locate_template(). 98 * @param string $type Sanitized filename without extension. 99 * @param string[] $templates A list of template candidates, in descending order of priority. 100 */ 101 return apply_filters( "{$type}_template", $template, $type, $templates ); 102 } 103 104 /** 105 * Retrieve path of index template in current or parent template. 106 * 107 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 108 * and {@see '$type_template'} dynamic hooks, where `$type` is 'index'. 109 * 110 * @since 3.0.0 111 * 112 * @see get_query_template() 113 * 114 * @return string Full path to index template file. 115 */ 116 function get_index_template() { 117 return get_query_template( 'index' ); 118 } 119 120 /** 121 * Retrieve path of 404 template in current or parent template. 122 * 123 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 124 * and {@see '$type_template'} dynamic hooks, where `$type` is '404'. 125 * 126 * @since 1.5.0 127 * 128 * @see get_query_template() 129 * 130 * @return string Full path to 404 template file. 131 */ 132 function get_404_template() { 133 return get_query_template( '404' ); 134 } 135 136 /** 137 * Retrieve path of archive template in current or parent template. 138 * 139 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 140 * and {@see '$type_template'} dynamic hooks, where `$type` is 'archive'. 141 * 142 * @since 1.5.0 143 * 144 * @see get_query_template() 145 * 146 * @return string Full path to archive template file. 147 */ 148 function get_archive_template() { 149 $post_types = array_filter( (array) get_query_var( 'post_type' ) ); 150 151 $templates = array(); 152 153 if ( count( $post_types ) == 1 ) { 154 $post_type = reset( $post_types ); 155 $templates[] = "archive-{$post_type}.php"; 156 } 157 $templates[] = 'archive.php'; 158 159 return get_query_template( 'archive', $templates ); 160 } 161 162 /** 163 * Retrieve path of post type archive template in current or parent template. 164 * 165 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 166 * and {@see '$type_template'} dynamic hooks, where `$type` is 'archive'. 167 * 168 * @since 3.7.0 169 * 170 * @see get_archive_template() 171 * 172 * @return string Full path to archive template file. 173 */ 174 function get_post_type_archive_template() { 175 $post_type = get_query_var( 'post_type' ); 176 if ( is_array( $post_type ) ) { 177 $post_type = reset( $post_type ); 178 } 179 180 $obj = get_post_type_object( $post_type ); 181 if ( ! ( $obj instanceof WP_Post_Type ) || ! $obj->has_archive ) { 182 return ''; 183 } 184 185 return get_archive_template(); 186 } 187 188 /** 189 * Retrieve path of author template in current or parent template. 190 * 191 * The hierarchy for this template looks like: 192 * 193 * 1. author-{nicename}.php 194 * 2. author-{id}.php 195 * 3. author.php 196 * 197 * An example of this is: 198 * 199 * 1. author-john.php 200 * 2. author-1.php 201 * 3. author.php 202 * 203 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 204 * and {@see '$type_template'} dynamic hooks, where `$type` is 'author'. 205 * 206 * @since 1.5.0 207 * 208 * @see get_query_template() 209 * 210 * @return string Full path to author template file. 211 */ 212 function get_author_template() { 213 $author = get_queried_object(); 214 215 $templates = array(); 216 217 if ( $author instanceof WP_User ) { 218 $templates[] = "author-{$author->user_nicename}.php"; 219 $templates[] = "author-{$author->ID}.php"; 220 } 221 $templates[] = 'author.php'; 222 223 return get_query_template( 'author', $templates ); 224 } 225 226 /** 227 * Retrieve path of category template in current or parent template. 228 * 229 * The hierarchy for this template looks like: 230 * 231 * 1. category-{slug}.php 232 * 2. category-{id}.php 233 * 3. category.php 234 * 235 * An example of this is: 236 * 237 * 1. category-news.php 238 * 2. category-2.php 239 * 3. category.php 240 * 241 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 242 * and {@see '$type_template'} dynamic hooks, where `$type` is 'category'. 243 * 244 * @since 1.5.0 245 * @since 4.7.0 The decoded form of `category-{slug}.php` was added to the top of the 246 * template hierarchy when the category slug contains multibyte characters. 247 * 248 * @see get_query_template() 249 * 250 * @return string Full path to category template file. 251 */ 252 function get_category_template() { 253 $category = get_queried_object(); 254 255 $templates = array(); 256 257 if ( ! empty( $category->slug ) ) { 258 259 $slug_decoded = urldecode( $category->slug ); 260 if ( $slug_decoded !== $category->slug ) { 261 $templates[] = "category-{$slug_decoded}.php"; 262 } 263 264 $templates[] = "category-{$category->slug}.php"; 265 $templates[] = "category-{$category->term_id}.php"; 266 } 267 $templates[] = 'category.php'; 268 269 return get_query_template( 'category', $templates ); 270 } 271 272 /** 273 * Retrieve path of tag template in current or parent template. 274 * 275 * The hierarchy for this template looks like: 276 * 277 * 1. tag-{slug}.php 278 * 2. tag-{id}.php 279 * 3. tag.php 280 * 281 * An example of this is: 282 * 283 * 1. tag-wordpress.php 284 * 2. tag-3.php 285 * 3. tag.php 286 * 287 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 288 * and {@see '$type_template'} dynamic hooks, where `$type` is 'tag'. 289 * 290 * @since 2.3.0 291 * @since 4.7.0 The decoded form of `tag-{slug}.php` was added to the top of the 292 * template hierarchy when the tag slug contains multibyte characters. 293 * 294 * @see get_query_template() 295 * 296 * @return string Full path to tag template file. 297 */ 298 function get_tag_template() { 299 $tag = get_queried_object(); 300 301 $templates = array(); 302 303 if ( ! empty( $tag->slug ) ) { 304 305 $slug_decoded = urldecode( $tag->slug ); 306 if ( $slug_decoded !== $tag->slug ) { 307 $templates[] = "tag-{$slug_decoded}.php"; 308 } 309 310 $templates[] = "tag-{$tag->slug}.php"; 311 $templates[] = "tag-{$tag->term_id}.php"; 312 } 313 $templates[] = 'tag.php'; 314 315 return get_query_template( 'tag', $templates ); 316 } 317 318 /** 319 * Retrieve path of custom taxonomy term template in current or parent template. 320 * 321 * The hierarchy for this template looks like: 322 * 323 * 1. taxonomy-{taxonomy_slug}-{term_slug}.php 324 * 2. taxonomy-{taxonomy_slug}.php 325 * 3. taxonomy.php 326 * 327 * An example of this is: 328 * 329 * 1. taxonomy-location-texas.php 330 * 2. taxonomy-location.php 331 * 3. taxonomy.php 332 * 333 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 334 * and {@see '$type_template'} dynamic hooks, where `$type` is 'taxonomy'. 335 * 336 * @since 2.5.0 337 * @since 4.7.0 The decoded form of `taxonomy-{taxonomy_slug}-{term_slug}.php` was added to the top of the 338 * template hierarchy when the term slug contains multibyte characters. 339 * 340 * @see get_query_template() 341 * 342 * @return string Full path to custom taxonomy term template file. 343 */ 344 function get_taxonomy_template() { 345 $term = get_queried_object(); 346 347 $templates = array(); 348 349 if ( ! empty( $term->slug ) ) { 350 $taxonomy = $term->taxonomy; 351 352 $slug_decoded = urldecode( $term->slug ); 353 if ( $slug_decoded !== $term->slug ) { 354 $templates[] = "taxonomy-$taxonomy-{$slug_decoded}.php"; 355 } 356 357 $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; 358 $templates[] = "taxonomy-$taxonomy.php"; 359 } 360 $templates[] = 'taxonomy.php'; 361 362 return get_query_template( 'taxonomy', $templates ); 363 } 364 365 /** 366 * Retrieve path of date template in current or parent template. 367 * 368 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 369 * and {@see '$type_template'} dynamic hooks, where `$type` is 'date'. 370 * 371 * @since 1.5.0 372 * 373 * @see get_query_template() 374 * 375 * @return string Full path to date template file. 376 */ 377 function get_date_template() { 378 return get_query_template( 'date' ); 379 } 380 381 /** 382 * Retrieve path of home template in current or parent template. 383 * 384 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 385 * and {@see '$type_template'} dynamic hooks, where `$type` is 'home'. 386 * 387 * @since 1.5.0 388 * 389 * @see get_query_template() 390 * 391 * @return string Full path to home template file. 392 */ 393 function get_home_template() { 394 $templates = array( 'home.php', 'index.php' ); 395 396 return get_query_template( 'home', $templates ); 397 } 398 399 /** 400 * Retrieve path of front page template in current or parent template. 401 * 402 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 403 * and {@see '$type_template'} dynamic hooks, where `$type` is 'frontpage'. 404 * 405 * @since 3.0.0 406 * 407 * @see get_query_template() 408 * 409 * @return string Full path to front page template file. 410 */ 411 function get_front_page_template() { 412 $templates = array( 'front-page.php' ); 413 414 return get_query_template( 'frontpage', $templates ); 415 } 416 417 /** 418 * Retrieve path of Privacy Policy page template in current or parent template. 419 * 420 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 421 * and {@see '$type_template'} dynamic hooks, where `$type` is 'privacypolicy'. 422 * 423 * @since 5.2.0 424 * 425 * @see get_query_template() 426 * 427 * @return string Full path to privacy policy template file. 428 */ 429 function get_privacy_policy_template() { 430 $templates = array( 'privacy-policy.php' ); 431 432 return get_query_template( 'privacypolicy', $templates ); 433 } 434 435 /** 436 * Retrieve path of page template in current or parent template. 437 * 438 * The hierarchy for this template looks like: 439 * 440 * 1. {Page Template}.php 441 * 2. page-{page_name}.php 442 * 3. page-{id}.php 443 * 4. page.php 444 * 445 * An example of this is: 446 * 447 * 1. page-templates/full-width.php 448 * 2. page-about.php 449 * 3. page-4.php 450 * 4. page.php 451 * 452 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 453 * and {@see '$type_template'} dynamic hooks, where `$type` is 'page'. 454 * 455 * @since 1.5.0 456 * @since 4.7.0 The decoded form of `page-{page_name}.php` was added to the top of the 457 * template hierarchy when the page name contains multibyte characters. 458 * 459 * @see get_query_template() 460 * 461 * @return string Full path to page template file. 462 */ 463 function get_page_template() { 464 $id = get_queried_object_id(); 465 $template = get_page_template_slug(); 466 $pagename = get_query_var( 'pagename' ); 467 468 if ( ! $pagename && $id ) { 469 // If a static page is set as the front page, $pagename will not be set. 470 // Retrieve it from the queried object. 471 $post = get_queried_object(); 472 if ( $post ) { 473 $pagename = $post->post_name; 474 } 475 } 476 477 $templates = array(); 478 if ( $template && 0 === validate_file( $template ) ) { 479 $templates[] = $template; 480 } 481 if ( $pagename ) { 482 $pagename_decoded = urldecode( $pagename ); 483 if ( $pagename_decoded !== $pagename ) { 484 $templates[] = "page-{$pagename_decoded}.php"; 485 } 486 $templates[] = "page-{$pagename}.php"; 487 } 488 if ( $id ) { 489 $templates[] = "page-{$id}.php"; 490 } 491 $templates[] = 'page.php'; 492 493 return get_query_template( 'page', $templates ); 494 } 495 496 /** 497 * Retrieve path of search template in current or parent template. 498 * 499 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 500 * and {@see '$type_template'} dynamic hooks, where `$type` is 'search'. 501 * 502 * @since 1.5.0 503 * 504 * @see get_query_template() 505 * 506 * @return string Full path to search template file. 507 */ 508 function get_search_template() { 509 return get_query_template( 'search' ); 510 } 511 512 /** 513 * Retrieve path of single template in current or parent template. Applies to single Posts, 514 * single Attachments, and single custom post types. 515 * 516 * The hierarchy for this template looks like: 517 * 518 * 1. {Post Type Template}.php 519 * 2. single-{post_type}-{post_name}.php 520 * 3. single-{post_type}.php 521 * 4. single.php 522 * 523 * An example of this is: 524 * 525 * 1. templates/full-width.php 526 * 2. single-post-hello-world.php 527 * 3. single-post.php 528 * 4. single.php 529 * 530 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 531 * and {@see '$type_template'} dynamic hooks, where `$type` is 'single'. 532 * 533 * @since 1.5.0 534 * @since 4.4.0 `single-{post_type}-{post_name}.php` was added to the top of the template hierarchy. 535 * @since 4.7.0 The decoded form of `single-{post_type}-{post_name}.php` was added to the top of the 536 * template hierarchy when the post name contains multibyte characters. 537 * @since 4.7.0 `{Post Type Template}.php` was added to the top of the template hierarchy. 538 * 539 * @see get_query_template() 540 * 541 * @return string Full path to single template file. 542 */ 543 function get_single_template() { 544 $object = get_queried_object(); 545 546 $templates = array(); 547 548 if ( ! empty( $object->post_type ) ) { 549 $template = get_page_template_slug( $object ); 550 if ( $template && 0 === validate_file( $template ) ) { 551 $templates[] = $template; 552 } 553 554 $name_decoded = urldecode( $object->post_name ); 555 if ( $name_decoded !== $object->post_name ) { 556 $templates[] = "single-{$object->post_type}-{$name_decoded}.php"; 557 } 558 559 $templates[] = "single-{$object->post_type}-{$object->post_name}.php"; 560 $templates[] = "single-{$object->post_type}.php"; 561 } 562 563 $templates[] = 'single.php'; 564 565 return get_query_template( 'single', $templates ); 566 } 567 568 /** 569 * Retrieves an embed template path in the current or parent template. 570 * 571 * The hierarchy for this template looks like: 572 * 573 * 1. embed-{post_type}-{post_format}.php 574 * 2. embed-{post_type}.php 575 * 3. embed.php 576 * 577 * An example of this is: 578 * 579 * 1. embed-post-audio.php 580 * 2. embed-post.php 581 * 3. embed.php 582 * 583 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 584 * and {@see '$type_template'} dynamic hooks, where `$type` is 'embed'. 585 * 586 * @since 4.5.0 587 * 588 * @see get_query_template() 589 * 590 * @return string Full path to embed template file. 591 */ 592 function get_embed_template() { 593 $object = get_queried_object(); 594 595 $templates = array(); 596 597 if ( ! empty( $object->post_type ) ) { 598 $post_format = get_post_format( $object ); 599 if ( $post_format ) { 600 $templates[] = "embed-{$object->post_type}-{$post_format}.php"; 601 } 602 $templates[] = "embed-{$object->post_type}.php"; 603 } 604 605 $templates[] = 'embed.php'; 606 607 return get_query_template( 'embed', $templates ); 608 } 609 610 /** 611 * Retrieves the path of the singular template in current or parent template. 612 * 613 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 614 * and {@see '$type_template'} dynamic hooks, where `$type` is 'singular'. 615 * 616 * @since 4.3.0 617 * 618 * @see get_query_template() 619 * 620 * @return string Full path to singular template file 621 */ 622 function get_singular_template() { 623 return get_query_template( 'singular' ); 624 } 625 626 /** 627 * Retrieve path of attachment template in current or parent template. 628 * 629 * The hierarchy for this template looks like: 630 * 631 * 1. {mime_type}-{sub_type}.php 632 * 2. {sub_type}.php 633 * 3. {mime_type}.php 634 * 4. attachment.php 635 * 636 * An example of this is: 637 * 638 * 1. image-jpeg.php 639 * 2. jpeg.php 640 * 3. image.php 641 * 4. attachment.php 642 * 643 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} 644 * and {@see '$type_template'} dynamic hooks, where `$type` is 'attachment'. 645 * 646 * @since 2.0.0 647 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical. 648 * 649 * @see get_query_template() 650 * 651 * @global array $posts 652 * 653 * @return string Full path to attachment template file. 654 */ 655 function get_attachment_template() { 656 $attachment = get_queried_object(); 657 658 $templates = array(); 659 660 if ( $attachment ) { 661 if ( false !== strpos( $attachment->post_mime_type, '/' ) ) { 662 list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); 663 } else { 664 list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); 665 } 666 667 if ( ! empty( $subtype ) ) { 668 $templates[] = "{$type}-{$subtype}.php"; 669 $templates[] = "{$subtype}.php"; 670 } 671 $templates[] = "{$type}.php"; 672 } 673 $templates[] = 'attachment.php'; 674 675 return get_query_template( 'attachment', $templates ); 676 } 677 678 /** 679 * Retrieve the name of the highest priority template file that exists. 680 * 681 * Searches in the STYLESHEETPATH before TEMPLATEPATH and wp-includes/theme-compat 682 * so that themes which inherit from a parent theme can just overload one file. 683 * 684 * @since 2.7.0 685 * @since 5.5.0 The `$args` parameter was added. 686 * 687 * @param string|array $template_names Template file(s) to search for, in order. 688 * @param bool $load If true the template file will be loaded if it is found. 689 * @param bool $require_once Whether to require_once or require. Has no effect if `$load` is false. 690 * Default true. 691 * @param array $args Optional. Additional arguments passed to the template. 692 * Default empty array. 693 * @return string The template filename if one is located. 694 */ 695 function locate_template( $template_names, $load = false, $require_once = true, $args = array() ) { 696 $located = ''; 697 foreach ( (array) $template_names as $template_name ) { 698 if ( ! $template_name ) { 699 continue; 700 } 701 if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) { 702 $located = STYLESHEETPATH . '/' . $template_name; 703 break; 704 } elseif ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) { 705 $located = TEMPLATEPATH . '/' . $template_name; 706 break; 707 } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) { 708 $located = ABSPATH . WPINC . '/theme-compat/' . $template_name; 709 break; 710 } 711 } 712 713 if ( $load && '' !== $located ) { 714 load_template( $located, $require_once, $args ); 715 } 716 717 return $located; 718 } 719 720 /** 721 * Require the template file with WordPress environment. 722 * 723 * The globals are set up for the template file to ensure that the WordPress 724 * environment is available from within the function. The query variables are 725 * also available. 726 * 727 * @since 1.5.0 728 * @since 5.5.0 The `$args` parameter was added. 729 * 730 * @global array $posts 731 * @global WP_Post $post Global post object. 732 * @global bool $wp_did_header 733 * @global WP_Query $wp_query WordPress Query object. 734 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 735 * @global wpdb $wpdb WordPress database abstraction object. 736 * @global string $wp_version 737 * @global WP $wp Current WordPress environment instance. 738 * @global int $id 739 * @global WP_Comment $comment Global comment object. 740 * @global int $user_ID 741 * 742 * @param string $_template_file Path to template file. 743 * @param bool $require_once Whether to require_once or require. Default true. 744 * @param array $args Optional. Additional arguments passed to the template. 745 * Default empty array. 746 */ 747 function load_template( $_template_file, $require_once = true, $args = array() ) { 748 global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; 749 750 if ( is_array( $wp_query->query_vars ) ) { 751 /* 752 * This use of extract() cannot be removed. There are many possible ways that 753 * templates could depend on variables that it creates existing, and no way to 754 * detect and deprecate it. 755 * 756 * Passing the EXTR_SKIP flag is the safest option, ensuring globals and 757 * function variables cannot be overwritten. 758 */ 759 // phpcs:ignore WordPress.PHP.DontExtract.extract_extract 760 extract( $wp_query->query_vars, EXTR_SKIP ); 761 } 762 763 if ( isset( $s ) ) { 764 $s = esc_attr( $s ); 765 } 766 767 if ( $require_once ) { 768 require_once $_template_file; 769 } else { 770 require $_template_file; 771 } 772 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 9 01:00:03 2021 | Cross-referenced by PHPXref 0.7.1 |