Ajout d'éléments au menu déroulant du modèle de page sur l'écran de modification de page

4

Je développe un thème WP avec une approche MVC. Il n'y a que index.php , functions.php et styles.css sur le répertoire parent. Par conséquent, je ne souhaite pas y placer de modèles de page, mais plutôt les fournir par programmation à partir de classes View tandis que les fonctionnalités à partir de l'écran d'édition restent inchangées.

Les utilisateurs ont besoin que les modèles de page sélectionnent l'option sur l'écran d'édition. Comment ajouter des éléments au menu déroulant du modèle?

J'ai essayé de me connecter à theme_page_templates filtre.

Exemple de code:

add_filter( 'theme_page_templates', function($templates){

    $templates['my-page-template.php'] = "My Page Template";

    return $templates;

});

Cela ne fonctionne pas à cause de l'utilisation de array_intersect_assoc() sur le filtre. tableau, qui supprime l'élément de modèle de page ajouté. Je ne comprends pas pourquoi cette fonction est utilisée. Il semble que vous ne pouvez supprimer que le modèle de page de la liste, mais vous ne pouvez pas en ajouter un nouveau à l'aide du filtre donné.

Y a-t-il un autre moyen?

    
posée Sisir 07.08.2015 - 18:00

2 réponses

5

Je pensais vous proposer une autre approche. C'est aussi un peu hackish, mais il est d'usage général et vous permet d'enregistrer simplement le nom de fichier et l'étiquette que vous souhaitez utiliser, comme suit:

if ( class_exists( 'WPSE_196995_Page_Templates' ) ) {   
    WPSE_196995_Page_Templates::register_page_template(
        'My Page Template',
        'my-page-template.php'
    );
}

Vous pouvez ajouter le code ci-dessus au fichier functions.php de votre thème.

Pour que ce qui précède fonctionne réellement, j'ai implémenté une classe autonome pouvant être utilisée comme plug-in ou simplement copiée dans functions.php :

<?php   
/**
 * Plugin Name: WPSE 196995 Page Templates
 *
 * Class WPSE_196995_Page_Templates
 *
 * Allows registering page templates via code.
 */
class WPSE_196995_Page_Templates {

    static $registered_templates = array();

    static function on_load() {

        /**
         * Add registered page templates to 'page_template' cache.
         * @note This hook is called just before page templates are loaded
         */
        add_action( 'default_page_template_title', array( __CLASS__, '_default_page_template_title' ) );
    }

    /**
     * Register page templates
     *
     * @param string $label
     * @param string $filename
     */
    static function register_page_template( $label, $filename ) {

        self::$registered_templates[ $filename ] = $label;

    }

    /**
     * Add registered page templates to 'page_template' cache.
     *
     * @param string $title
     *
     * @return string mixed
     */
    static function _default_page_template_title( $title ) {

        /**
         * @var WP_Theme $theme
         */
        $theme = wp_get_theme();

        /**
         * Access the cache the hard way since WP_Theme makes almost everything private
         */
        $cache_hash = md5( $theme->get_stylesheet_directory() );

        /**
         * Get the page templates as the 'page_templates' cache will already be primed
         */
        $page_templates = wp_cache_get( $key = "page_templates-{$cache_hash}", $group = 'themes' );

        /**
         * Add in registered page templates
         */
        $page_templates += self::$registered_templates;

        /**
         * Now update the cache, which is what the get_page_templates() uses.
         */
        wp_cache_set( $key, $page_templates, $group, 1800 );

        /**
         * We are using this hook as if it were an action.
         * So do not modify $title, just return it.
         */
        return $title;

    }

}
WPSE_196995_Page_Templates::on_load();

La classe fournit la méthode register_page_template() , bien sûr, mais pour ajouter réellement votre modèle de page, elle met à jour la valeur de 'page_templates' définie dans le cache d'objets.

C’est un peu compliqué, car WordPress a créé la plupart des méthodes et propriétés de WP_Theme class private , mais heureusement, ils ont utilisé le cache d’objets WordPress, accessible au public, pour stocker les valeurs. Et en mettant à jour le cache d'objets dans le hook 'default_page_template_title' , appelé juste avant que le menu déroulant des modèles de page ne soit généré et envoyé au navigateur, nous pouvons faire en sorte que WordPress affiche votre ou vos modèles de page, comme vous le souhaitez.

    
réponse donnée MikeSchinkel 08.08.2015 - 18:33
1

J'ai eu un truc moche: - /. Je vais mettre à jour la réponse si je vais avec jQuery plus tard. La solution nécessite toujours d’avoir des fichiers de modèle mais le code pour le fichier de modèle se charge à partir de index.php

.
  1. J'ai créé un nouveau répertoire template/ et y ai placé tous les modèles de page.
  2. Tous les modèles de page sont vides. Nous en avons besoin seulement pour qu’ils apparaissent dans le menu déroulant.
  3. Utilisez le filtre template_include pour rediriger vers index.php

Code

Exemple de modèle de page vierge

<?php
/*
Template Name: No Sidebar
 *
 * */

Filtre

add_filter( 'template_include', function ($template ) {

    if ( !is_page_template()  )
        return $template;

    return locate_template( array( 'index.php' ), true );

}, 99);

J'ai créé un ticket de suivi pour autoriser l'ajout de modèles via un filtre.

    
réponse donnée Sisir 08.08.2015 - 10:16

Lire d'autres questions sur les étiquettes