Je souhaite déplacer les fichiers de modèle de page tels que page-{slug}.php
dans un sous-répertoire de mon thème, de manière à ce que WordPress les reconnaisse automatiquement. Si les modèles de page de ce formulaire n'existent pas dans le sous-répertoire, WordPress doit alors revenir aux règles de chargement des modèles par défaut. Comment puis-je y arriver?
Note-1: Cette question et les réponses correspondantes sont plus génériques pour les modèles de page et this link mentionne template-parts/page
, ce qui n'est pas la même chose.
Note-2: J'ai plusieurs page-{slug}.php
comme les fichiers de modèle de page, je veux donc les déplacer dans un sous-répertoire pour une organisation plus ordonnée des fichiers.
Selon la hiérarchie par défaut des modèles WordPress , une demande page
charge un modèle en fonction de la priorité et du nom, comme indiqué ci-dessous:
Custom Page Template
: si défini dans l'éditeur de page.page-{slug}.php
page-{url-encoded-slug}.php
: uniquement pour les caractères multi-octets.page-{id}.php
page.php
singular.php
index.php
Parmi ceux-ci, singular.php
et index.php
sont pas en fait des modèles de page. singular.php
est le modèle de secours pour tout type d'article et index.php
est le modèle de secours ultime pour tout ce qu'un modèle WordPress est censé charger. Donc, les cinq premiers sont des modèles de page.
La fonction principale de WordPress get_page_template()
génère le tableau de hiérarchie de modèle page
nécessaire et juste avant de décider du fichier de modèle à charger de la hiérarchie, WordPress déclenche le hookpage_template_hierarchy
filter. Ainsi, la meilleure façon d’ajouter un sous-répertoire, où WordPress recherchera automatiquement les modèles page-{slug}.php
, consiste à utiliser ce filtre et à injecter les noms de fichier appropriés par rapport à ce sous-répertoire dans le tableau de hiérarchie des modèles de page.
Remarque:le hook de filtre d'origine est un hook de filtre dynamique défini comme
{$type}_template_hierarchy
, situé dans le fichierwp-includes/template.php
. Ainsi, lorsque le$type
estpage
, le hook de filtre devientpage_template_hierarchy
.
Pour ce faire, nous allons maintenant insérer le nom de fichier sub-directory/page-{slug}.php
juste avant page-{slug}.php
dans le tableau de hiérarchie de modèles transmis à la fonction de rappel des crochets. De cette façon, WordPress chargera le fichier sub-directory/page-{slug}.php
s'il existe, sinon il suivra la hiérarchie normale de chargement du modèle de page. Bien sûr, pour maintenir la cohérence, nous allons tout de même donner à Custom Page Template
une priorité supérieure à celle de notre fichier sub-directory/page-{slug}.php
. Ainsi, la hiérarchie de modèle de page modifiée deviendra:
Custom Page Template
: si défini dans l'éditeur de page.sub-directory/page-{slug}.php
sub-directory/page-{url-encoded-slug}.php
: uniquement pour les caractères multi-octets.page-{slug}.php
page-{url-encoded-slug}.php
: uniquement pour les caractères multi-octets.page-{id}.php
page.php
functions.php
CODE:Si vous envisagez de faire cette modification uniquement sur un seul thème, vous pouvez utiliser le code suivant dans le fichier functions.php
de votre thème actif:
// 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' );
Si vous souhaitez suivre la même organisation de fichiers de modèle dans plusieurs thèmes, il est préférable de garder cette fonctionnalité distincte de votre thème. Dans ce cas, au lieu de modifier le fichier functions.php
du thème avec l'exemple de code ci-dessus, vous devez créer un plug-in simple avec le même exemple de code.
Enregistrez le code suivant avec un nom de fichier, par exemple. page-slug-template-subdir.php
dans votre répertoire 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' );
Avec l’un des codes ci-dessus, WordPress reconnaîtra automatiquement les fichiers de modèle
page-{slug}.php
dans le répertoirepage-templates
de votre thème.Disons par exemple que vous avez une page
about
. Donc, si aucun codecustom page template
n'est défini dans l'éditeur, WordPress recherchera le fichier modèleTHEME/page-templates/page-about.php
et s'il n'existe pas, WordPress recherchera le fichier modèleTHEME/page-about.php
et ainsi de suite (c'est-à-dire la hiérarchie de modèles de page par défaut). .