web-dev-qa-db-fra.com

Créez un modèle de page "sans fichier" dans Functions.php

(Par "Modèle de page", j'entends un fichier de thème avec l'en-tête "Nom du modèle" qui peut être sélectionné dans le champ déroulant "Modèle" du page admin.)

Dans plusieurs cas, j'ai construit des modèles de page qui auraient pu être réalisés en se connectant à the_content ou à pre_get_posts ou quelque chose de similaire. Cela m'amène à me demander s'il existe un moyen de "enregistrer" un modèle de thème sélectionnable dans functions.php ou un plugin sans créer le fichier de thème lui-même.

Raisons pour lesquelles je veux faire ceci:

  • Dans les scénarios envisagés, je ne copie généralement que page.php presque mot pour mot. Cela signifie que toute modification future de page.php doit être effectuée deux fois. C'est encore plus pénible avec les mises à jour des thèmes enfants.
  • J'aime l'interface utilisateur du champ "Modèle". Pour mes clients, cela a plus de sens que certaines des alternatives (voir ci-dessous) auxquelles je peux penser.

Dans mon cas, je peux penser à certaines solutions de contournement, telles que l’utilisation d’une méta-boîte personnalisée ou d’un shortcode (pour insérer du contenu qui serait autrement conservé dans un modèle). Je pourrais même être capable de faire ceci (ce à quoi je viens de penser mais je n'ai pas encore testé):

/*
Template Name: My Template
*/

get_template_part( 'page' );

Mais au final, je reviens toujours sur cette idée, alors je suis curieux de savoir si quelqu'un sait comment le faire. Si vous pensez que c'est une idée horrible, cette opinion m'intéresse également.

=======

UPDATE: Je devrais ajouter que:

Je suppose que je dois juste comprendre comment le tableau de modèles et les champs personnalisés fonctionnent ensemble (et je suis aussi flou sur le fonctionnement des champs de méta personnalisés masqués).

=======

UPDATE II: 10/8/12 Le backend de thèmes a été considérablement retravaillé depuis que cette question a été posée de sorte que le tableau $ templates ci-dessus n'existe plus.

6
mrwweb

J'ai toujours envie de faire ce genre de chose et j'ai opté pour la solution suivante que j'ai proposée dans le PO et qui me plait pour plusieurs raisons:

  1. Il est très transparent et semble cohérent avec le maintien de la logique dans le thème.
  2. Il est très facile de personnaliser un modèle ultérieurement si nécessaire.

Modèle personnalisé

Voici le fichier de modèle complet si je n'ai besoin d'aucun balisage personnalisé. Disons que c'est dans /wp-content/themes/my-theme/templates/my-template.php

<?php
/**
 * Template Name: My Template
 */
get_template_part( 'page' );

En l'utilisant

Cela nous donne maintenant deux "crochets" pour faire toutes sortes de choses avec:

  1. Une classe de corps de .page-template-my-template pour CSS.
  2. La possibilité d'utiliser if( is_page_template( 'templates/my-template.php' ) ) {...

J'ai utilisé n ° 1 pour modifier les mises en page, les couleurs, etc., et n ° 2 pour filtrer the_content(), ajouter post_classes, configurer des champs personnalisés avec ACF, etc. Parfois, je les utilise en combinaison pour quelque chose comme un modèle pleine largeur qui nécessite encore une barre latérale. C'est sacrément puissant et pourtant très facile à configurer et à comprendre si vous ne le configurez pas vous-même.

Cela reste limité à un thème (vous ne pouvez pas le faire avec un plugin), mais pour les besoins de ma question, cela a été une bonne réponse pour moi.

1
mrwweb

Les pages sont généralement assez rigides, vous feriez mieux d'utiliser un type de message personnalisé . Il serait également très probablement problématique de s’accrocher à la liste déroulante des modèles de page réels (je doute que cela fonctionne sans piratage sérieux). Vous feriez mieux d'écrire votre propre liste déroulante de méta-boîtes.

Je pense que vous êtes sur la bonne voie avec get_template_part. C'est simple, flexible et aide vraiment à structurer une sortie complexe, et l'utilisation des deux paramètres est utile. Il est sans doute plus facile de copier/coller des morceaux de code dans des modèles, puis d’écrire toutes sortes de fonctions géniales, ce qui est plus logique pour d’autres personnes ou lorsque vous revisitez le code ultérieurement.

L'autre alternative est une personne similaire mais au niveau de la fonction, en utilisant l'action template_redirect.

Vous pourriez avoir des fonctions basées sur votre méta-sélection qui chargent des modèles uniques. En fait, maintenant que j'y pense, vous pourriez probablement les combiner avec get_template_part. Le code ci-dessous n'est pas testé.

Quelque chose comme:

function my_special_template() {
//page "contact" for example, make this your meta dropdown selection
    if (is_page('Contact')){  
        get_template_part( 'special-chunk' );  //file named special-chunk.php
    }
}

add_action('template_redirect', 'my_special_template');

À la fin de la journée, vous continuez cependant à récupérer une sorte de fichier .php.

2
Wyck

Je me demande si vous voulez enregistrer un modèle sans fichier avec le filtre theme_page_templates comme ceci:

/**
 * Add a file-less page template to the page template dropdown 
 */
add_filter( 'theme_page_templates', function( $page_templates, $wp_theme, $post ) 
{
    // Edit this to your needs
    $fileless_theme_slug  = 'my_fileless_page_template';
    $fileless_theme_label = esc_html__( 'My File-Less Page Template', 'my-domain' );

    // Append if it doesn't already exists  
    if( ! isset( $page_templates[$fileless_theme_slug] ) )
        $page_templates[$fileless_theme_slug] = $fileless_theme_label ;

    return $page_templates;
}, PHP_INT_MAX, 3 );

se présenter comme ceci dans le backend:

file-less template

puis modifiez sa sortie avec:

/**
 * OUtput for our file-less page template
 */
add_action( 'template_redirect', function() 
{   
    // Target pages with out custom template        
    if( is_page_template( 'my_fileless_page_template' ) )
    {
        // Stop the default page template to be displayed
        add_filter( 'template_include', '__return_null', PHP_INT_MAX );

        // Custom output
        my_fileless_page_template_output();
    }
}, PHP_INT_MAX );

Ici, nous définissons la my_fileless_page_template_output() à nos besoins, par exemple. inclure l'en-tête et le pied de page du thème, la boucle de requête principale ou même des parties de modèle. Je pense que vous pouvez ignorer exit à la fin.

1
birgire