Template per Custom Post Type dalla Cartella dei Plugin?

16 mag 2011, 16:16:45
Visualizzazioni: 53.9K
Voti: 82

Vorrei offrire il mio custom post type come Plugin, in modo che le persone possano utilizzarlo senza dover modificare la cartella del loro tema. Tuttavia, i template dei custom post type -- come single-movies.php -- risiedono nella cartella del tema. Esiste un modo per far sì che WordPress cerchi il file single-movies.php nella cartella del plugin? Agganciando una funzione alla Gerarchia dei Template? Oppure usando get_template_directory(); ?

0
Tutte le risposte alla domanda 8
7
121

Puoi utilizzare il filtro single_template.

/* Filtra il single_template con la nostra funzione personalizzata */
add_filter('single_template', 'my_custom_template');

function my_custom_template($single) {

    global $post;

    /* Controlla il template single in base al post type */
    if ( $post->post_type == 'NOME POST TYPE' ) {
        if ( file_exists( PERCORSO_PLUGIN . '/Custom_File.php' ) ) {
            return PERCORSO_PLUGIN . '/Custom_File.php';
        }
    }

    return $single;

}
16 mag 2011 16:41:53
Commenti

È una risposta fantastica. Potresti condividere dove posso trovare tutti gli hook disponibili per i template come single_template?

Gowri Gowri
2 mag 2013 21:18:00

@gowri Il filtro viene chiamato dalla funzione get_query_template(). È un hook variabile, quindi la prima parte {$type}_template cambia a seconda del parametro passato a quella funzione. Guarda wp-includes/template.php per alcuni esempi comuni

shea shea
7 mag 2013 12:42:24

Questo tutorial copre l'hook single_template con una buona spiegazione. Una volta compresi gli hook, il commento di @shea suggerisce un approccio più semplice rispetto alla risposta di @Bainternet, utilizzando add_filter( 'single-movies_template', 'my_custom_template' ); come nel tutorial linkato. (Questa domanda è chiusa a nuove risposte, quindi non posso aggiungerla separatamente.)

Greg Perham Greg Perham
26 set 2017 07:34:29

Potresti sostituire PLUGIN_PATH con plugin_dir_path( __FILE__ ) e poi rimuovere la prima barra dal nome del tuo file. Il percorso completo sarebbe qualcosa di simile: return plugin_dir_path( __FILE__ ) . 'Custom_File.php';

Frits Frits
13 feb 2018 08:49:06

Potrebbe essere che PLUGIN_PATH ora si chiami WP_PLUGIN_DIR.

Hans Dash Hans Dash
26 mar 2019 18:19:43

PLUGIN_PATH ha generato un errore, ecco un ottimo post che mostra come fare e che ha funzionato subito per me: https://wpsites.net/free-tutorials/load-single-template-from-plugin-for-different-post-types/

Nathan Nathan
2 mag 2019 23:19:24

esiste un filtro solo per un custom post type?

v3nt v3nt
6 set 2019 11:46:02
Mostra i restanti 2 commenti
3
40

Risposta aggiornata

Versione più pulita e concisa.

function load_movie_template( $template ) {
    global $post;

    if ( 'movie' === $post->post_type && locate_template( array( 'single-movie.php' ) ) !== $template ) {
        /*
         * Questo è un post di tipo 'movie'
         * E il template 'single movie' non viene trovato
         * nella directory del tema o child theme, quindi lo carichiamo
         * dalla directory del nostro plugin.
         */
        return plugin_dir_path( __FILE__ ) . 'single-movie.php';
    }

    return $template;
}

add_filter( 'single_template', 'load_movie_template' );

Vecchia risposta

Aggiunto un controllo per un template specifico del custom post type nella cartella del tema alla risposta di @Brainternet.

function load_cpt_template($template) {
    global $post;

    // È un post di tipo "my-custom-post-type"?
    if ($post->post_type == "my-custom-post-type"){

        //Percorso del tuo plugin 
        $plugin_path = plugin_dir_path( __FILE__ );

        // Nome del template single per il custom post type
        $template_name = 'single-my-custom-post-type.php';

        // Esiste un template single specifico per il mio custom post type nella cartella del tema? O non esiste nemmeno nel mio plugin?
        if($template === get_stylesheet_directory() . '/' . $template_name
            || !file_exists($plugin_path . $template_name)) {

            //Allora restituisci "single.php" o "single-my-custom-post-type.php" dalla directory del tema.
            return $template;
        }

        // Altrimenti, restituisci il template del custom post type dal mio plugin.
        return $plugin_path . $template_name;
    }

    //Questo non è il mio custom post type, non fare nulla con $template
    return $template;
}
add_filter('single_template', 'load_cpt_template');

Ora puoi permettere agli utenti del plugin di copiare il template dal tuo plugin al loro tema per sovrascriverlo.

Con questo esempio, i template devono essere nella directory principale sia del plugin che del tema.

15 gen 2016 11:45:36
Commenti

Utilizzare locate_template invece di get_stylesheet_directory mi sembra l'opzione più pulita (trovato qui: http://code.tutsplus.com/tutorials/a-guide-to-wordpress-custom-post-types-creation-display-and-meta-boxes--wp-27645).

Felix Felix
14 giu 2016 21:11:35

La risposta aggiornata non ha funzionato, la risposta accettata (o la tua vecchia risposta) funziona.

Edward Edward
29 mar 2018 17:43:43

Hai ragione, @Edward, quell'aggiornamento era orribile. L'ho aggiornato di nuovo con il suggerimento di Felix. Anche questa volta ho testato il codice prima di pubblicarlo :)

campsjos campsjos
3 apr 2018 18:40:46
0

Vorrei sottolineare che quando si utilizza il metodo del filtro per questo, è estremamente importante dare priorità al filtro in questo modo:

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

Se non lo fai, a volte WordPress tenterà di ricontrollare dopo questo filtro. Mi sono strappato i capelli per circa 2 ore a causa di questo.

14 dic 2016 18:33:50
0

Nei miei plugin utilizzo solitamente locate_template() che rende possibile sovrascrivere i template del plugin copiandoli nel tema corrente:

function templateInclude(string $template): string
{
    if (is_single() && get_query_var('post_type') === 'custom_post_type') {
        $templates = [
            'single-custom_post.php',
            'templates/single-custom_post.php'
        ];
        $template = locate_template($templates);
        if (!$template) {
            $template = __DIR__ . '/templates/single-custom_post.php';
        }
    }
    return $template;
}

add_filter('template_include', 'templateInclude');

Ora l'utente può sovrascrivere il template del plugin copiandolo dalla cartella del plugin templates/single-custom_post.php e posizionandolo sia direttamente nella root che in una cartella templates all'interno del tema attivo.

Suppongo che si possa utilizzare lo stesso approccio anche quando si usa il filtro single_template.

16 dic 2021 21:38:20
0

C'è un modo molto migliore per farlo che sto utilizzando per i miei plugin.

Come @campsjos ha menzionato qui, invece di controllare l'esistenza del file, puoi verificare locate_template che controllerà il file template sovrascritto dal tema. Il che è abbastanza ovvio.

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

Utilizza l'hook filter template_include per caricare il codice sopra.

add_filter('template_include' , 'my_plugin_templates');
1 ago 2019 08:39:55
0

grazie a questa pagina ho potuto risolvere lo stesso problema per me.

Per riferimento, questo è ciò con cui ho finito:

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

l'hook del filtro {$type}_template non ha funzionato per me

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');
20 ott 2019 02:21:03
0

Questo funziona per me, per favore provalo, grazie
I template vengono caricati nel file cpt, che si trova in
custom_plugin -> app -> cpt -> cpt_article.php
Il template si trova in
custom_plugin -> app -> templates

add_filter( 'single_template', 'load_my_custom_template', 99, 1 );
 function load_custom_templates($single_template) {
   global $post;
   if ($post->post_type == 'article' ) {
   $single_template = trailingslashit( plugin_dir_path( __FILE__ ) .'app/templates' ).'single_article.php';
  }
   return $single_template;
}
11 lug 2020 02:59:54
2
-2

La risposta sopra è ottima, ma verificare la variabile $single consente al template di sovrascrivere un template se ne viene fornito uno dal tema/tema child.

/* Filtra il single_template con la nostra funzione personalizzata */
add_filter('single_template', 'your_cpt_custom_template');

function your_cpt_custom_template( $single ) {
    global $wp_query, $post;
    /* Controlla il template single in base al 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;
}
19 ott 2015 19:47:59
Commenti

Questo non controlla se single-cpt.php è presente in un child o nel tema. Controlla solo rispetto a single.php che sarà sempre presente in qualsiasi tema.

newpoison newpoison
28 ott 2015 22:01:47

Esatto, quando ho scritto questo stavo usando un tema molto spartano, ci deve essere un modo migliore!

DigitalDesignDj DigitalDesignDj
20 nov 2015 23:19:20