9 /** |
9 /** |
10 * Retrieve path to a template |
10 * Retrieve path to a template |
11 * |
11 * |
12 * Used to quickly retrieve the path of a template without including the file |
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 |
13 * extension. It will also check the parent theme, if the file exists, with |
14 * the use of {@link locate_template()}. Allows for more generic template location |
14 * the use of locate_template(). Allows for more generic template location |
15 * without the use of the other get_*_template() functions. |
15 * without the use of the other get_*_template() functions. |
16 * |
16 * |
17 * @since 1.5.0 |
17 * @since 1.5.0 |
18 * |
18 * |
19 * @param string $type Filename without extension. |
19 * @param string $type Filename without extension. |
20 * @param array $templates An optional list of template candidates |
20 * @param array $templates An optional list of template candidates |
21 * @return string Full path to template file. |
21 * @return string Full path to template file. |
22 */ |
22 */ |
23 function get_query_template( $type, $templates = array() ) { |
23 function get_query_template( $type, $templates = array() ) { |
24 $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); |
24 $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); |
25 |
25 |
26 if ( empty( $templates ) ) |
26 if ( empty( $templates ) ) |
27 $templates = array("{$type}.php"); |
27 $templates = array("{$type}.php"); |
28 |
28 |
|
29 /** |
|
30 * Filters the list of template filenames that are searched for when retrieving a template to use. |
|
31 * |
|
32 * The last element in the array should always be the fallback template for this query type. |
|
33 * |
|
34 * Possible values for `$type` include: 'index', '404', 'archive', 'author', 'category', 'tag', 'taxonomy', 'date', |
|
35 * 'embed', 'home', 'frontpage', 'page', 'paged', 'search', 'single', 'singular', and 'attachment'. |
|
36 * |
|
37 * @since 4.7.0 |
|
38 * |
|
39 * @param array $templates A list of template candidates, in descending order of priority. |
|
40 */ |
|
41 $templates = apply_filters( "{$type}_template_hierarchy", $templates ); |
|
42 |
29 $template = locate_template( $templates ); |
43 $template = locate_template( $templates ); |
|
44 |
30 /** |
45 /** |
31 * Filter the path of the queried template by type. |
46 * Filters the path of the queried template by type. |
32 * |
47 * |
33 * The dynamic portion of the hook name, `$type`, refers to the filename |
48 * The dynamic portion of the hook name, `$type`, refers to the filename -- minus the file |
34 * -- minus the extension -- of the file to load. This hook also applies |
49 * extension and any non-alphanumeric characters delimiting words -- of the file to load. |
35 * to various types of files loaded as part of the Template Hierarchy. |
50 * This hook also applies to various types of files loaded as part of the Template Hierarchy. |
|
51 * |
|
52 * Possible values for `$type` include: 'index', '404', 'archive', 'author', 'category', 'tag', 'taxonomy', 'date', |
|
53 * 'embed', 'home', 'frontpage', 'page', 'paged', 'search', 'single', 'singular', and 'attachment'. |
36 * |
54 * |
37 * @since 1.5.0 |
55 * @since 1.5.0 |
38 * |
56 * @since 4.8.0 The `$type` and `$templates` parameters were added. |
39 * @param string $template Path to the template. See {@see locate_template()}. |
57 * |
|
58 * @param string $template Path to the template. See locate_template(). |
|
59 * @param string $type Filename without extension. |
|
60 * @param array $templates A list of template candidates, in descending order of priority. |
40 */ |
61 */ |
41 return apply_filters( "{$type}_template", $template ); |
62 return apply_filters( "{$type}_template", $template, $type, $templates ); |
42 } |
63 } |
43 |
64 |
44 /** |
65 /** |
45 * Retrieve path of index template in current or parent template. |
66 * Retrieve path of index template in current or parent template. |
46 * |
67 * |
47 * The template path is filterable via the 'index_template' hook. |
68 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} |
|
69 * and {@see '$type_template'} dynamic hooks, where `$type` is 'index'. |
48 * |
70 * |
49 * @since 3.0.0 |
71 * @since 3.0.0 |
50 * |
72 * |
51 * @see get_query_template() |
73 * @see get_query_template() |
52 * |
74 * |
192 $tag = get_queried_object(); |
259 $tag = get_queried_object(); |
193 |
260 |
194 $templates = array(); |
261 $templates = array(); |
195 |
262 |
196 if ( ! empty( $tag->slug ) ) { |
263 if ( ! empty( $tag->slug ) ) { |
|
264 |
|
265 $slug_decoded = urldecode( $tag->slug ); |
|
266 if ( $slug_decoded !== $tag->slug ) { |
|
267 $templates[] = "tag-{$slug_decoded}.php"; |
|
268 } |
|
269 |
197 $templates[] = "tag-{$tag->slug}.php"; |
270 $templates[] = "tag-{$tag->slug}.php"; |
198 $templates[] = "tag-{$tag->term_id}.php"; |
271 $templates[] = "tag-{$tag->term_id}.php"; |
199 } |
272 } |
200 $templates[] = 'tag.php'; |
273 $templates[] = 'tag.php'; |
201 |
274 |
202 return get_query_template( 'tag', $templates ); |
275 return get_query_template( 'tag', $templates ); |
203 } |
276 } |
204 |
277 |
205 /** |
278 /** |
206 * Retrieve path of taxonomy template in current or parent template. |
279 * Retrieve path of custom taxonomy term template in current or parent template. |
207 * |
280 * |
208 * Retrieves the taxonomy and term, if term is available. The template is |
281 * The hierarchy for this template looks like: |
209 * prepended with 'taxonomy-' and followed by both the taxonomy string and |
282 * |
210 * the taxonomy string followed by a dash and then followed by the term. |
283 * 1. taxonomy-{taxonomy_slug}-{term_slug}.php |
211 * |
284 * 2. taxonomy-{taxonomy_slug}.php |
212 * The taxonomy and term template is checked and used first, if it exists. |
285 * 3. taxonomy.php |
213 * Second, just the taxonomy template is checked, and then finally, taxonomy.php |
286 * |
214 * template is used. If none of the files exist, then it will fall back on to |
287 * An example of this is: |
215 * index.php. |
288 * |
216 * |
289 * 1. taxonomy-location-texas.php |
217 * The template path is filterable via the 'taxonomy_template' hook. |
290 * 2. taxonomy-location.php |
|
291 * 3. taxonomy.php |
|
292 * |
|
293 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} |
|
294 * and {@see '$type_template'} dynamic hooks, where `$type` is 'taxonomy'. |
218 * |
295 * |
219 * @since 2.5.0 |
296 * @since 2.5.0 |
220 * |
297 * @since 4.7.0 The decoded form of `taxonomy-{taxonomy_slug}-{term_slug}.php` was added to the top of the |
221 * @see get_query_template() |
298 * template hierarchy when the term slug contains multibyte characters. |
222 * |
299 * |
223 * @return string Full path to taxonomy template file. |
300 * @see get_query_template() |
|
301 * |
|
302 * @return string Full path to custom taxonomy term template file. |
224 */ |
303 */ |
225 function get_taxonomy_template() { |
304 function get_taxonomy_template() { |
226 $term = get_queried_object(); |
305 $term = get_queried_object(); |
227 |
306 |
228 $templates = array(); |
307 $templates = array(); |
229 |
308 |
230 if ( ! empty( $term->slug ) ) { |
309 if ( ! empty( $term->slug ) ) { |
231 $taxonomy = $term->taxonomy; |
310 $taxonomy = $term->taxonomy; |
|
311 |
|
312 $slug_decoded = urldecode( $term->slug ); |
|
313 if ( $slug_decoded !== $term->slug ) { |
|
314 $templates[] = "taxonomy-$taxonomy-{$slug_decoded}.php"; |
|
315 } |
|
316 |
232 $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; |
317 $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; |
233 $templates[] = "taxonomy-$taxonomy.php"; |
318 $templates[] = "taxonomy-$taxonomy.php"; |
234 } |
319 } |
235 $templates[] = 'taxonomy.php'; |
320 $templates[] = 'taxonomy.php'; |
236 |
321 |
358 function get_search_template() { |
446 function get_search_template() { |
359 return get_query_template('search'); |
447 return get_query_template('search'); |
360 } |
448 } |
361 |
449 |
362 /** |
450 /** |
363 * Retrieve path of single template in current or parent template. |
451 * Retrieve path of single template in current or parent template. Applies to single Posts, |
364 * |
452 * single Attachments, and single custom post types. |
365 * The template path is filterable via the 'single_template' hook. |
453 * |
366 * |
454 * The hierarchy for this template looks like: |
367 * @since 1.5.0 |
455 * |
|
456 * 1. {Post Type Template}.php |
|
457 * 2. single-{post_type}-{post_name}.php |
|
458 * 3. single-{post_type}.php |
|
459 * 4. single.php |
|
460 * |
|
461 * An example of this is: |
|
462 * |
|
463 * 1. templates/full-width.php |
|
464 * 2. single-post-hello-world.php |
|
465 * 3. single-post.php |
|
466 * 4. single.php |
|
467 * |
|
468 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} |
|
469 * and {@see '$type_template'} dynamic hooks, where `$type` is 'single'. |
|
470 * |
|
471 * @since 1.5.0 |
|
472 * @since 4.4.0 `single-{post_type}-{post_name}.php` was added to the top of the template hierarchy. |
|
473 * @since 4.7.0 The decoded form of `single-{post_type}-{post_name}.php` was added to the top of the |
|
474 * template hierarchy when the post name contains multibyte characters. |
|
475 * @since 4.7.0 {Post Type Template}.php was added to the top of the template hierarchy. |
368 * |
476 * |
369 * @see get_query_template() |
477 * @see get_query_template() |
370 * |
478 * |
371 * @return string Full path to single template file. |
479 * @return string Full path to single template file. |
372 */ |
480 */ |
373 function get_single_template() { |
481 function get_single_template() { |
374 $object = get_queried_object(); |
482 $object = get_queried_object(); |
375 |
483 |
376 $templates = array(); |
484 $templates = array(); |
377 |
485 |
378 if ( ! empty( $object->post_type ) ) |
486 if ( ! empty( $object->post_type ) ) { |
|
487 $template = get_page_template_slug( $object ); |
|
488 if ( $template && 0 === validate_file( $template ) ) { |
|
489 $templates[] = $template; |
|
490 } |
|
491 |
|
492 $name_decoded = urldecode( $object->post_name ); |
|
493 if ( $name_decoded !== $object->post_name ) { |
|
494 $templates[] = "single-{$object->post_type}-{$name_decoded}.php"; |
|
495 } |
|
496 |
|
497 $templates[] = "single-{$object->post_type}-{$object->post_name}.php"; |
379 $templates[] = "single-{$object->post_type}.php"; |
498 $templates[] = "single-{$object->post_type}.php"; |
|
499 } |
|
500 |
380 $templates[] = "single.php"; |
501 $templates[] = "single.php"; |
381 |
502 |
382 return get_query_template( 'single', $templates ); |
503 return get_query_template( 'single', $templates ); |
383 } |
504 } |
384 |
505 |
385 /** |
506 /** |
|
507 * Retrieves an embed template path in the current or parent template. |
|
508 * |
|
509 * The hierarchy for this template looks like: |
|
510 * |
|
511 * 1. embed-{post_type}-{post_format}.php |
|
512 * 2. embed-{post_type}.php |
|
513 * 3. embed.php |
|
514 * |
|
515 * An example of this is: |
|
516 * |
|
517 * 1. embed-post-audio.php |
|
518 * 2. embed-post.php |
|
519 * 3. embed.php |
|
520 * |
|
521 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} |
|
522 * and {@see '$type_template'} dynamic hooks, where `$type` is 'embed'. |
|
523 * |
|
524 * @since 4.5.0 |
|
525 * |
|
526 * @see get_query_template() |
|
527 * |
|
528 * @return string Full path to embed template file. |
|
529 */ |
|
530 function get_embed_template() { |
|
531 $object = get_queried_object(); |
|
532 |
|
533 $templates = array(); |
|
534 |
|
535 if ( ! empty( $object->post_type ) ) { |
|
536 $post_format = get_post_format( $object ); |
|
537 if ( $post_format ) { |
|
538 $templates[] = "embed-{$object->post_type}-{$post_format}.php"; |
|
539 } |
|
540 $templates[] = "embed-{$object->post_type}.php"; |
|
541 } |
|
542 |
|
543 $templates[] = "embed.php"; |
|
544 |
|
545 return get_query_template( 'embed', $templates ); |
|
546 } |
|
547 |
|
548 /** |
|
549 * Retrieves the path of the singular template in current or parent template. |
|
550 * |
|
551 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} |
|
552 * and {@see '$type_template'} dynamic hooks, where `$type` is 'singular'. |
|
553 * |
|
554 * @since 4.3.0 |
|
555 * |
|
556 * @see get_query_template() |
|
557 * |
|
558 * @return string Full path to singular template file |
|
559 */ |
|
560 function get_singular_template() { |
|
561 return get_query_template( 'singular' ); |
|
562 } |
|
563 |
|
564 /** |
386 * Retrieve path of attachment template in current or parent template. |
565 * Retrieve path of attachment template in current or parent template. |
387 * |
566 * |
388 * The attachment path first checks if the first part of the mime type exists. |
567 * The hierarchy for this template looks like: |
389 * The second check is for the second part of the mime type. The last check is |
568 * |
390 * for both types separated by an underscore. If neither are found then the file |
569 * 1. {mime_type}-{sub_type}.php |
391 * 'attachment.php' is checked and returned. |
570 * 2. {sub_type}.php |
392 * |
571 * 3. {mime_type}.php |
393 * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and |
572 * 4. attachment.php |
394 * finally 'text_plain.php'. |
573 * |
395 * |
574 * An example of this is: |
396 * The template path is filterable via the 'attachment_template' hook. |
575 * |
|
576 * 1. image-jpeg.php |
|
577 * 2. jpeg.php |
|
578 * 3. image.php |
|
579 * 4. attachment.php |
|
580 * |
|
581 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'} |
|
582 * and {@see '$type_template'} dynamic hooks, where `$type` is 'attachment'. |
397 * |
583 * |
398 * @since 2.0.0 |
584 * @since 2.0.0 |
399 * |
585 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical. |
400 * @see get_query_template() |
586 * |
|
587 * @see get_query_template() |
|
588 * |
|
589 * @global array $posts |
401 * |
590 * |
402 * @return string Full path to attachment template file. |
591 * @return string Full path to attachment template file. |
403 */ |
592 */ |
404 function get_attachment_template() { |
593 function get_attachment_template() { |
405 global $posts; |
594 $attachment = get_queried_object(); |
406 |
595 |
407 if ( ! empty( $posts ) && isset( $posts[0]->post_mime_type ) ) { |
596 $templates = array(); |
408 $type = explode( '/', $posts[0]->post_mime_type ); |
597 |
409 |
598 if ( $attachment ) { |
410 if ( ! empty( $type ) ) { |
599 if ( false !== strpos( $attachment->post_mime_type, '/' ) ) { |
411 if ( $template = get_query_template( $type[0] ) ) |
600 list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); |
412 return $template; |
601 } else { |
413 elseif ( ! empty( $type[1] ) ) { |
602 list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); |
414 if ( $template = get_query_template( $type[1] ) ) |
603 } |
415 return $template; |
604 |
416 elseif ( $template = get_query_template( "$type[0]_$type[1]" ) ) |
605 if ( ! empty( $subtype ) ) { |
417 return $template; |
606 $templates[] = "{$type}-{$subtype}.php"; |
418 } |
607 $templates[] = "{$subtype}.php"; |
419 } |
608 } |
420 } |
609 $templates[] = "{$type}.php"; |
421 |
610 } |
422 return get_query_template( 'attachment' ); |
611 $templates[] = 'attachment.php'; |
423 } |
612 |
424 |
613 return get_query_template( 'attachment', $templates ); |
425 /** |
|
426 * Retrieve path of comment popup template in current or parent template. |
|
427 * |
|
428 * Checks for comment popup template in current template, if it exists or in the |
|
429 * parent template. |
|
430 * |
|
431 * The template path is filterable via the 'comments_popup_template' hook. |
|
432 * |
|
433 * @since 1.5.0 |
|
434 * |
|
435 * @see get_query_template() |
|
436 * |
|
437 * @return string Full path to comments popup template file. |
|
438 */ |
|
439 function get_comments_popup_template() { |
|
440 $template = get_query_template( 'comments_popup', array( 'comments-popup.php' ) ); |
|
441 |
|
442 // Backward compat code will be removed in a future release |
|
443 if ('' == $template) |
|
444 $template = ABSPATH . WPINC . '/theme-compat/comments-popup.php'; |
|
445 |
|
446 return $template; |
|
447 } |
614 } |
448 |
615 |
449 /** |
616 /** |
450 * Retrieve the name of the highest priority template file that exists. |
617 * Retrieve the name of the highest priority template file that exists. |
451 * |
618 * |
452 * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which |
619 * Searches in the STYLESHEETPATH before TEMPLATEPATH and wp-includes/theme-compat |
453 * inherit from a parent theme can just overload one file. |
620 * so that themes which inherit from a parent theme can just overload one file. |
454 * |
621 * |
455 * @since 2.7.0 |
622 * @since 2.7.0 |
456 * |
623 * |
457 * @param string|array $template_names Template file(s) to search for, in order. |
624 * @param string|array $template_names Template file(s) to search for, in order. |
458 * @param bool $load If true the template file will be loaded if it is found. |
625 * @param bool $load If true the template file will be loaded if it is found. |
459 * @param bool $require_once Whether to require_once or require. Default true. Has no effect if $load is false. |
626 * @param bool $require_once Whether to require_once or require. Default true. Has no effect if $load is false. |
460 * @return string The template filename if one is located. |
627 * @return string The template filename if one is located. |
461 */ |
628 */ |
462 function locate_template($template_names, $load = false, $require_once = true ) { |
629 function locate_template($template_names, $load = false, $require_once = true ) { |
463 $located = ''; |
630 $located = ''; |
464 foreach ( (array) $template_names as $template_name ) { |
631 foreach ( (array) $template_names as $template_name ) { |
486 * environment is available from within the function. The query variables are |
656 * environment is available from within the function. The query variables are |
487 * also available. |
657 * also available. |
488 * |
658 * |
489 * @since 1.5.0 |
659 * @since 1.5.0 |
490 * |
660 * |
|
661 * @global array $posts |
|
662 * @global WP_Post $post |
|
663 * @global bool $wp_did_header |
|
664 * @global WP_Query $wp_query |
|
665 * @global WP_Rewrite $wp_rewrite |
|
666 * @global wpdb $wpdb |
|
667 * @global string $wp_version |
|
668 * @global WP $wp |
|
669 * @global int $id |
|
670 * @global WP_Comment $comment |
|
671 * @global int $user_ID |
|
672 * |
491 * @param string $_template_file Path to template file. |
673 * @param string $_template_file Path to template file. |
492 * @param bool $require_once Whether to require_once or require. Default true. |
674 * @param bool $require_once Whether to require_once or require. Default true. |
493 */ |
675 */ |
494 function load_template( $_template_file, $require_once = true ) { |
676 function load_template( $_template_file, $require_once = true ) { |
495 global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; |
677 global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; |
496 |
678 |
497 if ( is_array( $wp_query->query_vars ) ) |
679 if ( is_array( $wp_query->query_vars ) ) { |
498 extract( $wp_query->query_vars, EXTR_SKIP ); |
680 extract( $wp_query->query_vars, EXTR_SKIP ); |
499 |
681 } |
500 if ( $require_once ) |
682 |
|
683 if ( isset( $s ) ) { |
|
684 $s = esc_attr( $s ); |
|
685 } |
|
686 |
|
687 if ( $require_once ) { |
501 require_once( $_template_file ); |
688 require_once( $_template_file ); |
502 else |
689 } else { |
503 require( $_template_file ); |
690 require( $_template_file ); |
504 } |
691 } |
505 |
692 } |