Функция возвращает путь к первому найденному файлу шаблона или подключает его. Если файла шаблона не найдено, то возвращает пустую строку.
Если вам интересно лучше разбираться, как устроены файлы тем в WordPress и как работает их иерархия, то рекомендую посмотреть этот видеоурок.
locate_template( $template_names, $load = false, $require_once = true, $args = array() )
true
, если хотите, чтобы функция сразу же подключила файл.true
– в этом случае файл будет подключаться PHP-функцией require_once()
,false
– будет подключаться функцией require()
.Давайте разберёмся пошагово, как и что делает эта функция. Лучше всего это показать на примере.
// массив названий файлов шаблонов $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
$template_names
.file1.php
file1.php
в текущей теме?file1.php
в родительской теме в случае, если используется дочерняя?file1.php
в папке wp-includes/theme-compat/
?file1.php
ни одно из условий не совпало, то точно по такому же алгоритму проверяется file2.php
.file2.php
найдется в текущей или родительской теме, или в папке theme-compat
, то функция выходит из цикла и не проверяет все остальные названия файлов, переданные в неё.$load
установлен в значение true
, то функция сразу же попробует подключить найденный файл шаблона функцией load_template()
и передав в неё параметры $require_once
и $args
.В этом примере используем функцию load_template() для подключения файлов шаблона.
if ( $template = locate_template( 'true-template.php' ) ) { // locate_template() возвращает путь к файлу, если он есть в дочерней или родительской теме // тогда мы сразу его и подключаем load_template( $template ); } else { // если ни в дочерней ни в родительской теме файла нет // подключим его из произвольной локации load_template( __DIR__ . '/templates/true-template.php' ); }
Дело в том, что данная функция не исключает перемещения по директориям сайта, например кто-то вместо обычного названия файла может передать что-то типо /../../../../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 ); }
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
Здравствуйте.
Посоветовали вашу статью для решения моей проблемы, но у меня не получилось, я не программист к сожалению. Можно мне помочь? У меня тема twentytwenty и в её дочерней теме нужно сделать рабочим файл inc/template-tags.php. Все остальные файлы из папки дочерней темы, работают, а в папке inc нет. Когда пробую варианты (уже очень много попробовала), появляется ошибка cannot redeclare. Как понимаю, WP ругается, что такое уже есть в родительской теме и почему-то не хочет воспроизводить в дочерней...
Спасибо!
Здравствуйте!
Возможно вот тут есть ответ на ваш вопрос.