Keine Beschreibung

template.php 22KB

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