Modèles de type de message personnalisé à partir du dossier du plug-in?


57

J'aimerais proposer mon type de message personnalisé sous forme de plug-in, afin que les gens puissent l'utiliser sans toucher à leur dossier de thèmes. Toutefois, les modèles de type de publication personnalisés, tels que single-movies.php, résident dans le dossier du thème. Existe-t-il un moyen de demander à WP de rechercher un fichier single-movies.php dans le dossier du plug-in? Accrocher une fonction dans la hiérarchie de Filer ? Ou get_template_directory (); ?

Réponses:


90

Vous pouvez utiliser le single_templatecrochet de filtre.

/* Filter the single_template with our custom function*/
add_filter('single_template', 'my_custom_template');

function my_custom_template($single) {

    global $post;

    /* Checks for single template by post type */
    if ( $post->post_type == 'POST TYPE NAME' ) {
        if ( file_exists( PLUGIN_PATH . '/Custom_File.php' ) ) {
            return PLUGIN_PATH . '/Custom_File.php';
        }
    }

    return $single;

}

C'est génial réponse. S'il vous plaît partager où puis-je obtenir tous les modèles disponibles crochet comme single_template.
— Gowri

6
@gowri Le filtre est appelé par la get_query_template()fonction. C'est un crochet variable, donc la première partie {$type}_templatechange en fonction du paramètre passé à cette fonction. Voir wp-includes / template.php pour quelques exemples courants
— karité

Ce tutoriel couvre le hook single_template avec une bonne explication. Une fois que vous avez compris les points faibles, le commentaire de @ shea suggère une approche plus simple que la réponse de @ Bainternet, en utilisant add_filter( 'single-movies_template', 'my_custom_template' );comme dans le tutoriel lié. (Cette question est fermée aux nouvelles réponses, je ne peux donc pas l'ajouter toute seule.)
— Greg Perham

2
Vous pouvez remplacer PLUGIN_PATHpar plugin_dir_path( __FILE__ ), puis supprimer la première barre oblique de votre nom de fichier. Le chemin complet ressemblerait à ceci:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
— Frits

1
PLUGIN_PATH a généré une erreur. Voici un excellent article qui explique comment faire cela et qui a fonctionné pour moi immédiatement
— Nathan,

22

Réponse mise à jour

Version plus propre et plus courte.

function load_movie_template( $template ) {
    global $post;

    if ( 'movie' === $post->post_type && locate_template( array( 'single-movie.php' ) ) !== $template ) {
        /*
         * This is a 'movie' post
         * AND a 'single movie template' is not found on
         * theme or child theme directories, so load it
         * from our plugin directory.
         */
        return plugin_dir_path( __FILE__ ) . 'single-movie.php';
    }

    return $template;
}

add_filter( 'single_template', 'load_movie_template' );

Ancienne réponse

Ajout d'une vérification pour un modèle spécifique de type d'article personnalisé dans le dossier de thèmes à @Brainternet answer.

function load_cpt_template($template) {
    global $post;

    // Is this a "my-custom-post-type" post?
    if ($post->post_type == "my-custom-post-type"){

        //Your plugin path 
        $plugin_path = plugin_dir_path( __FILE__ );

        // The name of custom post type single template
        $template_name = 'single-my-custom-post-type.php';

        // A specific single template for my custom post type exists in theme folder? Or it also doesn't exist in my plugin?
        if($template === get_stylesheet_directory() . '/' . $template_name
            || !file_exists($plugin_path . $template_name)) {

            //Then return "single.php" or "single-my-custom-post-type.php" from theme directory.
            return $template;
        }

        // If not, return my plugin custom post type template.
        return $plugin_path . $template_name;
    }

    //This is not my custom post type, do nothing with $template
    return $template;
}
add_filter('single_template', 'load_cpt_template');

Vous pouvez maintenant laisser les utilisateurs du plug-in copier le modèle de votre plug-in dans leur thème pour le remplacer.

Dans cet exemple, les modèles doivent figurer dans le répertoire racine du plugin et du thème.


1
Utiliser pour moi locate_templatedes get_stylesheet_directorysons comme l'option de nettoyage (trouvé ici: code.tutsplus.com/tutorials/… ).
— Felix

1
La réponse mise à jour n'a pas fonctionné, la réponse acceptée (ou votre ancienne réponse) fonctionne.
— Edward

2
Vous avez raison, @ Edward, c'était une mise à jour épouvantable. Je l'ai mis à jour à nouveau avec la suggestion de Félix. Aussi cette fois j'ai testé le code avant de le poster :)
— campsjos le

4

Je tiens à souligner que lorsque vous utilisez la méthode de filtrage pour cela, il est extrêmement important de hiérarchiser le filtre de la manière suivante:

add_filter('single_template', 'my_custom_template', 99);

Si vous ne le faites pas, parfois, WP tentera de vérifier à nouveau après ce filtre. J'arrachais mes cheveux à cause de ça pendant 2 heures.


0

Il existe une bien meilleure façon de le faire que j'utilise pour mes plugins.

Comme @campsjos le mentionne ici , au lieu de la vérification de l’existence du fichier, vous pouvez vérifier locate_templateque cela sera vérifié dans le fichier de modèle de remplacement de thème. Ce qui est assez évident.

function my_plugin_templates() {
    if (is_singular('movie')) {
        if (file_exists($this->template_dir . 'single-movie.php')) {
            return $this->template_dir . 'single-movie.php';
        }
    }
}

Utilisez le template_includecrochet de filtre pour charger le code ci-dessus.

add_filter('template_include' , 'my_plugin_templates');

0

Grâce à cette page, j'ai pu résoudre la même question pour moi.

Pour référence, voici ce que j'ai fini avec:

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';
  return get_post_type() === 'myposttype' && file_exists($myposttype_template) ? $myposttype_template : $single_template;
}
add_filter('single_template', 'pluginName_myposttype_single_template');

le hook de filtre {$ type} _template n'a pas fonctionné pour moi

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';

  if ( file_exists($myposttype_template) ) {
    $single_template = $myposttype_template;
  }
  return $single_template;
}
add_filter('single-myposttype_template', 'pluginName_myposttype_single_template');

-2

La réponse ci-dessus est excellente, mais la vérification de la variable $ single permet au modèle de remplacer un modèle si celui-ci est fourni par le thème theme / child.

/* Filter the single_template with our custom function*/
add_filter('single_template', 'your_cpt_custom_template');

function your_cpt_custom_template( $single ) {
    global $wp_query, $post;
    /* Checks for single template by post type */
    if ( !$single && $post->post_type == 'cpt' ) {
        if( file_exists( plugin_dir_path( __FILE__ ) . 'single-cpt.php' ) )
            return plugin_dir_path( __FILE__ ) . 'single-cpt.php';
    }
    return $single;
}

1
Cela ne vérifie pas si single-cpt.php est présent dans un enfant ou dans le thème. Il ne vérifie que single.php qui sera toujours présent dans tous les thèmes.
— newpxsn

C'est vrai, quand j'ai écrit ça, j'utilisais un thème vraiment dépouillé, il devait y avoir un meilleur moyen!
— DigitalDesignDj
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.