Функция возвращает путь к первому найденному файлу шаблона или подключает его. Если файла шаблона не найдено, то возвращает пустую строку.
locate_template( $template_names, $load = false, $require_once = true, $args = array() )
Параметры
- $template_names
- (массив|строка) Один или несколько названий PHP-файлов.
- $load
- Укажите
true
, если хотите, чтобы функция сразу же подключила файл. - $require_once
-
true
– в этом случае файл будет подключаться PHP-функциейrequire_once()
,false
– будет подключаться функциейrequire()
.
- $args
- (массив) Дополнительный массив аргументов, который вы хотите передать в подключаемый файл шаблона.
Пример 1. Как работает функция
Давайте разберёмся пошагово, как и что делает эта функция. Лучше всего это показать на примере.
// массив названий файлов шаблонов $template_names = array( 'file1.php', // не существует 'file2.php', // существует, будет возвращен 'page-templates/file3.php', // до него цикл не дойдёт, проверяться не будет ); $template_name_path = locate_template( $template_names ); echo $template_name_path; // выведет: /home/misha.agency/wp-content/themes/truemisha/file2.php
Пример 2. Используем как условие
В этом примере используем функцию load_template() для подключения файлов шаблона.
if ( $template = locate_template( 'true-template.php' ) ) { // locate_template() возвращает путь к файлу, если он есть в дочерней или родительской теме // тогда мы сразу его и подключаем load_template( $template ); } else { // если ни в дочерней ни в родительской теме файла нет // подключим его из произвольной локации load_template( __DIR__ . '/templates/true-template.php' ); }
Пример 3. Предотвращение «directory traversal» атак
Дело в том, что данная функция не исключает перемещения по директориям сайта, например кто-то вместо обычного названия файла может передать что-то типо /../../../../some-file.php
, а такого вообше не должно быть.
В очистке подобного из путей файлов нам может помочь PHP-функция realpath()
.
// сначала получаем полный путь шаблона из неочищенных данных $template = locate_template( $template_filename_from_unsanitized_user_input ); // Разрешаем только директорию текущей темы, дочерней темы и папку theme-compat $template_in_theme_or_parent_theme_or_compat = ( // Если путь содержит директорию текущей темы 0 === strpos( realpath( $template ), realpath( STYLESHEETPATH ) ) || // Директория родительской темы 0 === strpos( realpath( $template ), realpath( TEMPLATEPATH ) ) || // Директория theme-compat 0 === strpos( realpath( $template ), realpath( ABSPATH . WPINC . '/theme-compat/' ) ) ); if ( $template_in_theme_or_parent_theme_or_compat ) { require_once( $template ); }