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.