it-swarm.com.ru

Как переместить файлы шаблона страницы, такие как page- {slug} .php, в подкаталог?

Я хочу переместить файлы шаблона страницы, такие как page-{slug}.php, в подкаталог в моей теме таким образом, чтобы WordPress распознал их автоматически. Если шаблоны страниц указанной формы не существуют в подкаталоге, WordPress должен вернуться к правилам загрузки шаблонов по умолчанию. Как я могу этого достичь?

Примечание-1: Это вопрос и соответствующие ответы являются более общими для шаблонов страниц и это ссылка упоминает template-parts/page, что не одно и то же.

Примечание-2: У меня есть несколько файлов шаблонов страниц, похожих на page-{slug}.php, поэтому я хочу переместить их в подкаталог для более аккуратной организации файлов.

8
chevallier

Как загружаются шаблоны страниц:

Согласно стандартной иерархии шаблонов WordPress , запрос page загружает шаблон на основе приоритета и именования, как указано ниже:

  1. Custom Page Template: если определен в редакторе страниц.
  2. page-{slug}.php
  3. page-{url-encoded-slug}.php: только для многобайтовых символов.
  4. page-{id}.php
  5. page.php
  6. singular.php
  7. index.php

Среди них singular.php и index.php являются не собственно шаблонами страниц. singular.php является резервным шаблоном для любых типов записей, а index.php является конечным резервным шаблоном для всего, что должен загружать шаблон WordPress. Итак, первые пять - это шаблоны страниц.

Как добавить файлы шаблона из подкаталога в иерархии:

Основная функция WordPress get_page_template() генерирует необходимый массив иерархии шаблонов page, и непосредственно перед тем, как решить, какой именно файл шаблона загрузить из иерархии, WordPress запускаетpage_template_hierarchyфильтр-хук. Таким образом, лучший способ добавить подкаталог, где WordPress будет автоматически искать шаблоны page-{slug}.php, - это использовать этот фильтр и вводить правильные имена файлов относительно этого подкаталога в массив иерархии шаблонов страниц.

Примечание:исходная ловушка фильтра - это ловушка динамического фильтра, определенная как{$type}_template_hierarchy, которая находится в файле wp-includes/template.php. Поэтому, когда $type равен page, ловушка фильтра становится page_template_hierarchy.

Теперь, для нашей цели, мы вставим имя файла sub-directory/page-{slug}.php непосредственно перед page-{slug}.php в массиве иерархии шаблонов, переданном в функцию обратного вызова hooks. Таким образом, WordPress загрузит файл sub-directory/page-{slug}.php, если он существует, в противном случае он будет следовать обычной иерархии загрузки шаблонов страниц. Конечно, для обеспечения согласованности мы по-прежнему будем отдавать Custom Page Template более высокий приоритет по сравнению с нашим файлом sub-directory/page-{slug}.php. Таким образом, измененная иерархия шаблонов страниц станет:

  1. Custom Page Template: если определен в редакторе страниц.
  2. sub-directory/page-{slug}.php
  3. sub-directory/page-{url-encoded-slug}.php: только для многобайтовых символов.
  4. page-{slug}.php
  5. page-{url-encoded-slug}.php: только для многобайтовых символов.
  6. page-{id}.php
  7. page.php

Пример functions.php КОД:

Если вы планируете сделать это изменение только для одной темы, вы можете использовать следующий код в файле functions.php вашей активной темы:

// defining the sub-directory so that it can be easily accessed from elsewhere as well.
define( 'WPSE_PAGE_TEMPLATE_SUB_DIR', 'page-templates' );

function wpse312159_page_template_add_subdir( $templates = array() ) {
    // Generally this doesn't happen, unless another plugin / theme does modifications
    // of their own. In that case, it's better not to mess with it again with our code.
    if( empty( $templates ) || ! is_array( $templates ) || count( $templates ) < 3 )
        return $templates;

    $page_tpl_idx = 0;
    if( $templates[0] === get_page_template_slug() ) {
        // if there is custom template, then our page-{slug}.php template is at the next index 
        $page_tpl_idx = 1;
    }

    $page_tpls = array( WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx] );

    // As of WordPress 4.7, the URL decoded page-{$slug}.php template file is included in the
    // page template hierarchy just before the URL encoded page-{$slug}.php template file.
    // Also, WordPress always keeps the page id different from page slug. So page-{slug}.php will
    // always be different from page-{id}.php, even if you try to input the {id} as {slug}.
    // So this check will work for WordPress versions prior to 4.7 as well.
    if( $templates[$page_tpl_idx] === urldecode( $templates[$page_tpl_idx + 1] ) ) {
        $page_tpls[] = WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx + 1];
    }

    array_splice( $templates, $page_tpl_idx, 0, $page_tpls );

    return $templates;
}
add_filter( 'page_template_hierarchy', 'wpse312159_page_template_add_subdir' );

Пример плагина:

Если вы хотите следовать одной и той же организации файла шаблона в нескольких темах, то лучше оставить эту функцию отдельной от вашей темы. В этом случае вместо изменения файла functions.php темы указанным выше примером CODE вам потребуется создать простой плагин с тем же примером CODE.

Сохраните следующий код с именем файла, например, page-slug-template-subdir.php в вашем каталоге WordPress plugins:

<?php
/*
Plugin Name:  WPSE Page Template page-slug.php to Sub Directory
Plugin URI:   https://wordpress.stackexchange.com/a/312159/110572
Description:  Page Template with page-{slug}.php to a Sub Directory
Version:      1.0.0
Author:       Fayaz Ahmed
Author URI:   https://www.fayazmiraz.com/
*/

// defining the sub-directory so that it can be easily accessed from elsewhere as well.
define( 'WPSE_PAGE_TEMPLATE_SUB_DIR', 'page-templates' );

function wpse312159_page_template_add_subdir( $templates = array() ) {
    // Generally this doesn't happen, unless another plugin / theme does modifications
    // of their own. In that case, it's better not to mess with it again with our code.
    if( empty( $templates ) || ! is_array( $templates ) || count( $templates ) < 3 )
        return $templates;

    $page_tpl_idx = 0;
    if( $templates[0] === get_page_template_slug() ) {
        // if there is custom template, then our page-{slug}.php template is at the next index 
        $page_tpl_idx = 1;
    }

    $page_tpls = array( WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx] );
                                                                                  uded in the
    // page template hierarchy just before the URL encoded page-{$slug}.php template file.
    // Also, WordPress always keeps the page id different from page slug. So page-{slug}.php will
    // always be different from page-{id}.php, even if you try to input the {id} as {slug}.
    // So this check will work for WordPress versions prior to 4.7 as well.
    if( $templates[$page_tpl_idx] === urldecode( $templates[$page_tpl_idx + 1] ) ) {
        $page_tpls[] = WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx + 1];
    }

    array_splice( $templates, $page_tpl_idx, 0, $page_tpls );

    return $templates;
}
// the original filter hook is {$type}_template_hierarchy,
// wihch is located in wp-includes/template.php file
add_filter( 'page_template_hierarchy', 'wpse312159_page_template_add_subdir' );

Использование:

Используя любой из приведенных выше кодов, WordPress автоматически распознает файлы шаблонов page-{slug}.php в каталоге page-templates вашей темы.

Например, у вас есть страница about. Итак, если у него не установлен custom page template из редактора, то WordPress будет искать файл шаблона THEME/page-templates/page-about.php, а если его нет, то WordPress будет искать файл шаблона THEME/page-about.php и т.д. (То есть иерархию шаблонов страниц по умолчанию) ,.

10
Fayaz