web-dev-qa-db-fra.com

Comment déplacer des fichiers de modèle de page comme page- {slug} .php dans un sous-répertoire?

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.

8
chevallier

Comment les modèles de page sont chargés:

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:

  1. Custom Page Template: si défini dans l'éditeur de page.
  2. page-{slug}.php
  3. page-{url-encoded-slug}.php: uniquement pour les caractères multi-octets.
  4. page-{id}.php
  5. page.php
  6. singular.php
  7. 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.

Comment injecter des fichiers de modèle depuis un sous-répertoire de la hiérarchie:

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_hierarchyfilter. 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 fichier wp-includes/template.php. Ainsi, lorsque le $type est page, le hook de filtre devient page_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:

  1. Custom Page Template: si défini dans l'éditeur de page.
  2. sub-directory/page-{slug}.php
  3. sub-directory/page-{url-encoded-slug}.php: uniquement pour les caractères multi-octets.
  4. page-{slug}.php
  5. page-{url-encoded-slug}.php: uniquement pour les caractères multi-octets.
  6. page-{id}.php
  7. page.php

Exemple 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' );

Exemple de plugin:

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' );

Usage:

Avec l’un des codes ci-dessus, WordPress reconnaîtra automatiquement les fichiers de modèle page-{slug}.php dans le répertoire page-templates de votre thème.

Disons par exemple que vous avez une page about. Donc, si aucun code custom page template n'est défini dans l'éditeur, WordPress recherchera le fichier modèle THEME/page-templates/page-about.php et s'il n'existe pas, WordPress recherchera le fichier modèle THEME/page-about.php et ainsi de suite (c'est-à-dire la hiérarchie de modèles de page par défaut). .

10
Fayaz