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


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

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

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

Author: Scott, 2018-08-22

1 answers

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

Согласно иерархии шаблонов 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 с приведенным выше примером КОДА вам нужно будет создать простой плагин с тем же примером КОДА.

Сохраните следующий КОД с именем файла, например 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 и так далее (т.Е. иерархию шаблонов страниц по умолчанию).

 13
Author: Fayaz, 2020-06-15 08:21:38