WordPress 4.4
[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 the path of the singular template in current or parent template.
409  *
410  * The template path is filterable via the dynamic {@see '$type_template'} hook,
411  * e.g. 'singular_template'.
412  *
413  * @since 4.3.0
414  *
415  * @see get_query_template()
416  *
417  * @return string Full path to singular template file
418  */
419 function get_singular_template() {
420         return get_query_template( 'singular' );
421 }
422
423 /**
424  * Retrieve path of attachment template in current or parent template.
425  *
426  * The attachment path first checks if the first part of the mime type exists.
427  * The second check is for the second part of the mime type. The last check is
428  * for both types separated by an underscore. If neither are found then the file
429  * 'attachment.php' is checked and returned.
430  *
431  * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and
432  * finally 'text-plain.php'.
433  *
434  * The template path is filterable via the dynamic {@see '$type_template'} hook,
435  * e.g. 'attachment_template'.
436  *
437  * @since 2.0.0
438  *
439  * @see get_query_template()
440  *
441  * @global array $posts
442  *
443  * @return string Full path to attachment template file.
444  */
445 function get_attachment_template() {
446         $attachment = get_queried_object();
447
448         $templates = array();
449
450         if ( $attachment ) {
451                 if ( false !== strpos( $attachment->post_mime_type, '/' ) ) {
452                         list( $type, $subtype ) = explode( '/', $attachment->post_mime_type );
453                 } else {
454                         list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
455                 }
456
457                 if ( ! empty( $subtype ) ) {
458                         $templates[] = "{$type}-{$subtype}.php";
459                         $templates[] = "{$subtype}.php";
460                 }
461                 $templates[] = "{$type}.php";
462         }
463         $templates[] = 'attachment.php';
464
465         return get_query_template( 'attachment', $templates );
466 }
467
468 /**
469  * Retrieve path of comment popup template in current or parent template.
470  *
471  * Checks for comment popup template in current template, if it exists or in the
472  * parent template.
473  *
474  * The template path is filterable via the dynamic {@see '$type_template'} hook,
475  * e.g. 'commentspopup_template'.
476  *
477  * @since 1.5.0
478  *
479  * @see get_query_template()
480  *
481  * @return string Full path to comments popup template file.
482  */
483 function get_comments_popup_template() {
484         $template = get_query_template( 'comments_popup', array( 'comments-popup.php' ) );
485
486         // Backward compat code will be removed in a future release.
487         if ('' == $template)
488                 $template = ABSPATH . WPINC . '/theme-compat/comments-popup.php';
489
490         return $template;
491 }
492
493 /**
494  * Retrieve the name of the highest priority template file that exists.
495  *
496  * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which
497  * inherit from a parent theme can just overload one file.
498  *
499  * @since 2.7.0
500  *
501  * @param string|array $template_names Template file(s) to search for, in order.
502  * @param bool         $load           If true the template file will be loaded if it is found.
503  * @param bool         $require_once   Whether to require_once or require. Default true. Has no effect if $load is false.
504  * @return string The template filename if one is located.
505  */
506 function locate_template($template_names, $load = false, $require_once = true ) {
507         $located = '';
508         foreach ( (array) $template_names as $template_name ) {
509                 if ( !$template_name )
510                         continue;
511                 if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
512                         $located = STYLESHEETPATH . '/' . $template_name;
513                         break;
514                 } elseif ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
515                         $located = TEMPLATEPATH . '/' . $template_name;
516                         break;
517                 }
518         }
519
520         if ( $load && '' != $located )
521                 load_template( $located, $require_once );
522
523         return $located;
524 }
525
526 /**
527  * Require the template file with WordPress environment.
528  *
529  * The globals are set up for the template file to ensure that the WordPress
530  * environment is available from within the function. The query variables are
531  * also available.
532  *
533  * @since 1.5.0
534  *
535  * @global array      $posts
536  * @global WP_Post    $post
537  * @global bool       $wp_did_header
538  * @global WP_Query   $wp_query
539  * @global WP_Rewrite $wp_rewrite
540  * @global wpdb       $wpdb
541  * @global string     $wp_version
542  * @global WP         $wp
543  * @global int        $id
544  * @global WP_Comment $comment
545  * @global int        $user_ID
546  *
547  * @param string $_template_file Path to template file.
548  * @param bool   $require_once   Whether to require_once or require. Default true.
549  */
550 function load_template( $_template_file, $require_once = true ) {
551         global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
552
553         if ( is_array( $wp_query->query_vars ) ) {
554                 extract( $wp_query->query_vars, EXTR_SKIP );
555         }
556
557         if ( isset( $s ) ) {
558                 $s = esc_attr( $s );
559         }
560
561         if ( $require_once ) {
562                 require_once( $_template_file );
563         } else {
564                 require( $_template_file );
565         }
566 }
567