WordPress 4.5
[autoinstalls/wordpress.git] / wp-includes / template.php
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 {@link 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 array  $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         $template = locate_template( $templates );
30
31         /**
32          * Filter the path of the queried template by type.
33          *
34          * The dynamic portion of the hook name, `$type`, refers to the filename -- minus the file
35          * extension and any non-alphanumeric characters delimiting words -- of the file to load.
36          * This hook also applies to various types of files loaded as part of the Template Hierarchy.
37          *
38          * Possible values for `$type` include: 'index', '404', 'archive', 'author', 'category', 'tag', 'taxonomy', 'date',
39          * 'home', 'front_page', 'page', 'paged', 'search', 'single', 'singular', and 'attachment'.
40          *
41          * @since 1.5.0
42          *
43          * @param string $template Path to the template. See locate_template().
44          */
45         return apply_filters( "{$type}_template", $template );
46 }
47
48 /**
49  * Retrieve path of index template in current or parent template.
50  *
51  * The template path is filterable via the dynamic {@see '$type_template'} hook,
52  * e.g. 'index_template'.
53  *
54  * @since 3.0.0
55  *
56  * @see get_query_template()
57  *
58  * @return string Full path to index template file.
59  */
60 function get_index_template() {
61         return get_query_template('index');
62 }
63
64 /**
65  * Retrieve path of 404 template in current or parent template.
66  *
67  * The template path is filterable via the dynamic {@see '$type_template'} hook,
68  * e.g. '404_template'.
69  *
70  * @since 1.5.0
71  *
72  * @see get_query_template()
73  *
74  * @return string Full path to 404 template file.
75  */
76 function get_404_template() {
77         return get_query_template('404');
78 }
79
80 /**
81  * Retrieve path of archive template in current or parent template.
82  *
83  * The template path is filterable via the dynamic {@see '$type_template'} hook,
84  * e.g. 'archive_template'.
85  *
86  * @since 1.5.0
87  *
88  * @see get_query_template()
89  *
90  * @return string Full path to archive template file.
91  */
92 function get_archive_template() {
93         $post_types = array_filter( (array) get_query_var( 'post_type' ) );
94
95         $templates = array();
96
97         if ( count( $post_types ) == 1 ) {
98                 $post_type = reset( $post_types );
99                 $templates[] = "archive-{$post_type}.php";
100         }
101         $templates[] = 'archive.php';
102
103         return get_query_template( 'archive', $templates );
104 }
105
106 /**
107  * Retrieve path of post type archive template in current or parent template.
108  *
109  * The template path is filterable via the dynamic {@see '$type_template'} hook,
110  * e.g. 'archive_template'.
111  *
112  * @since 3.7.0
113  *
114  * @see get_archive_template()
115  *
116  * @return string Full path to archive template file.
117  */
118 function get_post_type_archive_template() {
119         $post_type = get_query_var( 'post_type' );
120         if ( is_array( $post_type ) )
121                 $post_type = reset( $post_type );
122
123         $obj = get_post_type_object( $post_type );
124         if ( ! $obj->has_archive )
125                 return '';
126
127         return get_archive_template();
128 }
129
130 /**
131  * Retrieve path of author template in current or parent template.
132  *
133  * The template path is filterable via the dynamic {@see '$type_template'} hook,
134  * e.g. 'author_template'.
135  *
136  * @since 1.5.0
137  *
138  * @see get_query_template()
139  *
140  * @return string Full path to author template file.
141  */
142 function get_author_template() {
143         $author = get_queried_object();
144
145         $templates = array();
146
147         if ( $author instanceof WP_User ) {
148                 $templates[] = "author-{$author->user_nicename}.php";
149                 $templates[] = "author-{$author->ID}.php";
150         }
151         $templates[] = 'author.php';
152
153         return get_query_template( 'author', $templates );
154 }
155
156 /**
157  * Retrieve path of category template in current or parent template.
158  *
159  * Works by first retrieving the current slug, for example 'category-default.php',
160  * and then trying category ID, for example 'category-1.php', and will finally fall
161  * back to category.php template, if those files don't exist.
162  *
163  * The template path is filterable via the dynamic {@see '$type_template'} hook,
164  * e.g. 'category_template'.
165  *
166  * @since 1.5.0
167  *
168  * @see get_query_template()
169  *
170  * @return string Full path to category template file.
171  */
172 function get_category_template() {
173         $category = get_queried_object();
174
175         $templates = array();
176
177         if ( ! empty( $category->slug ) ) {
178                 $templates[] = "category-{$category->slug}.php";
179                 $templates[] = "category-{$category->term_id}.php";
180         }
181         $templates[] = 'category.php';
182
183         return get_query_template( 'category', $templates );
184 }
185
186 /**
187  * Retrieve path of tag template in current or parent template.
188  *
189  * Works by first retrieving the current tag name, for example 'tag-wordpress.php',
190  * and then trying tag ID, for example 'tag-1.php', and will finally fall back to
191  * tag.php template, if those files don't exist.
192  *
193  * The template path is filterable via the dynamic {@see '$type_template'} hook,
194  * e.g. 'tag_template'.
195  *
196  * @since 2.3.0
197  *
198  * @see get_query_template()
199  *
200  * @return string Full path to tag template file.
201  */
202 function get_tag_template() {
203         $tag = get_queried_object();
204
205         $templates = array();
206
207         if ( ! empty( $tag->slug ) ) {
208                 $templates[] = "tag-{$tag->slug}.php";
209                 $templates[] = "tag-{$tag->term_id}.php";
210         }
211         $templates[] = 'tag.php';
212
213         return get_query_template( 'tag', $templates );
214 }
215
216 /**
217  * Retrieve path of taxonomy template in current or parent template.
218  *
219  * Retrieves the taxonomy and term, if term is available. The template is
220  * prepended with 'taxonomy-' and followed by both the taxonomy string and
221  * the taxonomy string followed by a dash and then followed by the term.
222  *
223  * The taxonomy and term template is checked and used first, if it exists.
224  * Second, just the taxonomy template is checked, and then finally, taxonomy.php
225  * template is used. If none of the files exist, then it will fall back on to
226  * index.php.
227  *
228  * The template path is filterable via the dynamic {@see '$type_template'} hook,
229  * e.g. 'taxonomy_template'.
230  *
231  * @since 2.5.0
232  *
233  * @see get_query_template()
234  *
235  * @return string Full path to taxonomy template file.
236  */
237 function get_taxonomy_template() {
238         $term = get_queried_object();
239
240         $templates = array();
241
242         if ( ! empty( $term->slug ) ) {
243                 $taxonomy = $term->taxonomy;
244                 $templates[] = "taxonomy-$taxonomy-{$term->slug}.php";
245                 $templates[] = "taxonomy-$taxonomy.php";
246         }
247         $templates[] = 'taxonomy.php';
248
249         return get_query_template( 'taxonomy', $templates );
250 }
251
252 /**
253  * Retrieve path of date template in current or parent template.
254  *
255  * The template path is filterable via the dynamic {@see '$type_template'} hook,
256  * e.g. 'date_template'.
257  *
258  * @since 1.5.0
259  *
260  * @see get_query_template()
261  *
262  * @return string Full path to date template file.
263  */
264 function get_date_template() {
265         return get_query_template('date');
266 }
267
268 /**
269  * Retrieve path of home template in current or parent template.
270  *
271  * This is the template used for the page containing the blog posts.
272  * Attempts to locate 'home.php' first before falling back to 'index.php'.
273  *
274  * The template path is filterable via the dynamic {@see '$type_template'} hook,
275  * e.g. 'home_template'.
276  *
277  * @since 1.5.0
278  *
279  * @see get_query_template()
280  *
281  * @return string Full path to home template file.
282  */
283 function get_home_template() {
284         $templates = array( 'home.php', 'index.php' );
285
286         return get_query_template( 'home', $templates );
287 }
288
289 /**
290  * Retrieve path of front-page template in current or parent template.
291  *
292  * Looks for 'front-page.php'. The template path is filterable via the
293  * dynamic {@see '$type_template'} hook, e.g. 'frontpage_template'.
294  *
295  * @since 3.0.0
296  *
297  * @see get_query_template()
298  *
299  * @return string Full path to front page template file.
300  */
301 function get_front_page_template() {
302         $templates = array('front-page.php');
303
304         return get_query_template( 'front_page', $templates );
305 }
306
307 /**
308  * Retrieve path of page template in current or parent template.
309  *
310  * Will first look for the specifically assigned page template.
311  * Then will search for 'page-{slug}.php', followed by 'page-{id}.php',
312  * and finally 'page.php'.
313  *
314  * The template path is filterable via the dynamic {@see '$type_template'} hook,
315  * e.g. 'page_template'.
316  *
317  * @since 1.5.0
318  *
319  * @see get_query_template()
320  *
321  * @return string Full path to page template file.
322  */
323 function get_page_template() {
324         $id = get_queried_object_id();
325         $template = get_page_template_slug();
326         $pagename = get_query_var('pagename');
327
328         if ( ! $pagename && $id ) {
329                 // If a static page is set as the front page, $pagename will not be set. Retrieve it from the queried object
330                 $post = get_queried_object();
331                 if ( $post )
332                         $pagename = $post->post_name;
333         }
334
335         $templates = array();
336         if ( $template && 0 === validate_file( $template ) )
337                 $templates[] = $template;
338         if ( $pagename )
339                 $templates[] = "page-$pagename.php";
340         if ( $id )
341                 $templates[] = "page-$id.php";
342         $templates[] = 'page.php';
343
344         return get_query_template( 'page', $templates );
345 }
346
347 /**
348  * Retrieve path of paged template in current or parent template.
349  *
350  * The template path is filterable via the dynamic {@see '$type_template'} hook,
351  * e.g. 'paged_template'.
352  *
353  * @since 1.5.0
354  *
355  * @see get_query_template()
356  *
357  * @return string Full path to paged template file.
358  */
359 function get_paged_template() {
360         return get_query_template('paged');
361 }
362
363 /**
364  * Retrieve path of search template in current or parent template.
365  *
366  * The template path is filterable via the dynamic {@see '$type_template'} hook,
367  * e.g. 'search_template'.
368  *
369  * @since 1.5.0
370  *
371  * @see get_query_template()
372  *
373  * @return string Full path to search template file.
374  */
375 function get_search_template() {
376         return get_query_template('search');
377 }
378
379 /**
380  * Retrieve path of single template in current or parent template.
381  *
382  * The template path is filterable via the dynamic {@see '$type_template'} hook,
383  * e.g. 'single_template'.
384  *
385  * @since 1.5.0
386  * @since 4.4.0 `single-{post_type}-{post_name}.php` was added to the top of the template hierarchy.
387  *
388  * @see get_query_template()
389  *
390  * @return string Full path to single template file.
391  */
392 function get_single_template() {
393         $object = get_queried_object();
394
395         $templates = array();
396
397         if ( ! empty( $object->post_type ) ) {
398                 $templates[] = "single-{$object->post_type}-{$object->post_name}.php";
399                 $templates[] = "single-{$object->post_type}.php";
400         }
401
402         $templates[] = "single.php";
403
404         return get_query_template( 'single', $templates );
405 }
406
407 /**
408  * Retrieves an embed template path in the current or parent template.
409  *
410  * By default the WordPress-template is returned.
411  *
412  * The template path is filterable via the dynamic {@see '$type_template'} hook,
413  * e.g. 'embed_template'.
414  *
415  * @since 4.5.0
416  *
417  * @see get_query_template()
418  *
419  * @return string Full path to embed template file.
420  */
421 function get_embed_template() {
422         $object = get_queried_object();
423
424         $templates = array();
425
426         if ( ! empty( $object->post_type ) ) {
427                 $post_format = get_post_format( $object );
428                 if ( $post_format ) {
429                         $templates[] = "embed-{$object->post_type}-{$post_format}.php";
430                 }
431                 $templates[] = "embed-{$object->post_type}.php";
432         }
433
434         $templates[] = "embed.php";
435
436         return get_query_template( 'embed', $templates );
437 }
438
439 /**
440  * Retrieves the path of the singular template in current or parent template.
441  *
442  * The template path is filterable via the dynamic {@see '$type_template'} hook,
443  * e.g. 'singular_template'.
444  *
445  * @since 4.3.0
446  *
447  * @see get_query_template()
448  *
449  * @return string Full path to singular template file
450  */
451 function get_singular_template() {
452         return get_query_template( 'singular' );
453 }
454
455 /**
456  * Retrieve path of attachment template in current or parent template.
457  *
458  * The attachment path first checks if the first part of the mime type exists.
459  * The second check is for the second part of the mime type. The last check is
460  * for both types separated by an underscore. If neither are found then the file
461  * 'attachment.php' is checked and returned.
462  *
463  * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and
464  * finally 'text-plain.php'.
465  *
466  * The template path is filterable via the dynamic {@see '$type_template'} hook,
467  * e.g. 'attachment_template'.
468  *
469  * @since 2.0.0
470  *
471  * @see get_query_template()
472  *
473  * @global array $posts
474  *
475  * @return string Full path to attachment template file.
476  */
477 function get_attachment_template() {
478         $attachment = get_queried_object();
479
480         $templates = array();
481
482         if ( $attachment ) {
483                 if ( false !== strpos( $attachment->post_mime_type, '/' ) ) {
484                         list( $type, $subtype ) = explode( '/', $attachment->post_mime_type );
485                 } else {
486                         list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
487                 }
488
489                 if ( ! empty( $subtype ) ) {
490                         $templates[] = "{$type}-{$subtype}.php";
491                         $templates[] = "{$subtype}.php";
492                 }
493                 $templates[] = "{$type}.php";
494         }
495         $templates[] = 'attachment.php';
496
497         return get_query_template( 'attachment', $templates );
498 }
499
500 /**
501  * Retrieve the name of the highest priority template file that exists.
502  *
503  * Searches in the STYLESHEETPATH before TEMPLATEPATH and wp-includes/theme-compat
504  * so that themes which inherit from a parent theme can just overload one file.
505  *
506  * @since 2.7.0
507  *
508  * @param string|array $template_names Template file(s) to search for, in order.
509  * @param bool         $load           If true the template file will be loaded if it is found.
510  * @param bool         $require_once   Whether to require_once or require. Default true. Has no effect if $load is false.
511  * @return string The template filename if one is located.
512  */
513 function locate_template($template_names, $load = false, $require_once = true ) {
514         $located = '';
515         foreach ( (array) $template_names as $template_name ) {
516                 if ( !$template_name )
517                         continue;
518                 if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
519                         $located = STYLESHEETPATH . '/' . $template_name;
520                         break;
521                 } elseif ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
522                         $located = TEMPLATEPATH . '/' . $template_name;
523                         break;
524                 } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
525                         $located = ABSPATH . WPINC . '/theme-compat/' . $template_name;
526                         break;
527                 }
528         }
529
530         if ( $load && '' != $located )
531                 load_template( $located, $require_once );
532
533         return $located;
534 }
535
536 /**
537  * Require the template file with WordPress environment.
538  *
539  * The globals are set up for the template file to ensure that the WordPress
540  * environment is available from within the function. The query variables are
541  * also available.
542  *
543  * @since 1.5.0
544  *
545  * @global array      $posts
546  * @global WP_Post    $post
547  * @global bool       $wp_did_header
548  * @global WP_Query   $wp_query
549  * @global WP_Rewrite $wp_rewrite
550  * @global wpdb       $wpdb
551  * @global string     $wp_version
552  * @global WP         $wp
553  * @global int        $id
554  * @global WP_Comment $comment
555  * @global int        $user_ID
556  *
557  * @param string $_template_file Path to template file.
558  * @param bool   $require_once   Whether to require_once or require. Default true.
559  */
560 function load_template( $_template_file, $require_once = true ) {
561         global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
562
563         if ( is_array( $wp_query->query_vars ) ) {
564                 extract( $wp_query->query_vars, EXTR_SKIP );
565         }
566
567         if ( isset( $s ) ) {
568                 $s = esc_attr( $s );
569         }
570
571         if ( $require_once ) {
572                 require_once( $_template_file );
573         } else {
574                 require( $_template_file );
575         }
576 }
577