Modelli di post personalizzati dalla cartella dei plugin?


57

Vorrei offrire il mio tipo di post personalizzato come Plugin, in modo che le persone possano utilizzarlo senza toccare la cartella del tema. Ma i modelli di tipo di post personalizzati - come single-movies.php - risiedono nella cartella del tema. C'è un modo per convincere WP a cercare un singolo-movie.php nella cartella del plugin? Collegare una funzione alla Gerarchia di Filer ? Oppure get_template_directory (); ?

Risposte:


90

È possibile utilizzare il single_templategancio del filtro.

/* 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;

}

È una risposta fantastica. Per favore condividi dove posso ottenere tutti gli hook disponibili come template single_template.
Gowri,

6
@gowri Il filtro viene chiamato dalla get_query_template()funzione. È un hook variabile, quindi la prima parte {$type}_templatecambia in base al parametro passato a quella funzione. Vedi wp-Includes / template.php per alcuni comuni
shea

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, usando add_filter( 'single-movies_template', 'my_custom_template' );come nel tutorial collegato. (Questa domanda è chiusa a nuove risposte, quindi non posso aggiungerla da sola.)
Greg Perham,

2
È possibile sostituire PLUGIN_PATHcon plugin_dir_path( __FILE__ )e quindi rimuovere la prima barra dal nome del file. Il percorso completo sarebbe simile a questo:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
Frits

1
PLUGIN_PATH ha generato un errore, ecco un ottimo post che mostra come farlo e ha funzionato per me fuori dagli schemi: wpsites.net/free-tutorials/…
Nathan

22

Risposta aggiornata

Versione più pulita e più corta.

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

Vecchia risposta

Aggiunto un controllo per un modello specifico di tipo di post personalizzato nella cartella del tema alla risposta @Brainternet.

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

Ora puoi consentire agli utenti del plug-in di copiare il modello dal tuo plug-in sul loro tema per sovrascriverlo.

Con questo esempio, i modelli devono trovarsi nella directory principale sia del plugin che del tema.


1
Usare locate_templateinvece di get_stylesheet_directorysuona come l'opzione più pulita per me (disponibile qui: code.tutsplus.com/tutorials/… ).
Felix,

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

2
Hai ragione, @Edward, è stato un aggiornamento orrendo. L'ho aggiornato di nuovo con il suggerimento di Felix. Anche questa volta ho testato il codice prima di pubblicarlo :)
Campsjos,

4

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

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

In caso contrario, a volte WP tenterà di ricontrollare dopo questo filtro. Mi stavo strappando i capelli per questo per circa 2 ore.


0

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

Come menzionato @campsjos qui , invece del controllo dell'esistenza del file, puoi verificare locate_templateche verifichi nel file di modello di sostituzione del 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';
        }
    }
}

Utilizzare il template_includegancio del filtro per caricare il codice sopra.

add_filter('template_include' , 'my_plugin_templates');

0

grazie a questa pagina sono stato in grado di risolvere la stessa domanda per me.

Per riferimento, questo è quello che ho finito con:

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

il gancio filtro $ $} _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');

-2

Sopra è un'ottima risposta, ma il controllo di $ single var consente al modello di sovrascrivere un modello se fornito dal tema tema / figlio.

/* 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
Questo non controlla se single-cpt.php è presente in un bambino o nel tema. Controlla solo contro single.php che sarà sempre presente in tutti i temi.
newpxsn,

Esatto, quando ho scritto questo stavo usando un tema davvero spoglio, ci deve essere un modo migliore!
DigitalDesignDj,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.