Benutzerdefinierte Post-Typ-Vorlagen aus dem Plugin-Ordner?


57

Ich möchte meinen benutzerdefinierten Beitragstyp als Plug-in anbieten, damit Benutzer ihn verwenden können, ohne ihren Themenordner zu berühren. Im Themenordner befinden sich jedoch benutzerdefinierte Vorlagen für Posts (z. B. "single-movies.php"). Gibt es eine Möglichkeit, WP dazu zu bringen, im Ordner des Plugins nach einer single-movies.php zu suchen? Eine Funktion in die Filer-Hierarchie einbinden ? Oder get_template_directory (); ?

Antworten:


90

Sie können single_templateFilterhaken verwenden.

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

}

Es ist eine wunderbare Antwort. Bitte teilen Sie uns mit, wo ich alle verfügbaren Vorlagenhooks wie single_template erhalten kann.
— Gowri

6
@gowri Der Filter wird von der get_query_template()Funktion aufgerufen . Es ist ein variabler Hook, daher {$type}_templateändert sich der erste Teil abhängig davon, welcher Parameter an diese Funktion übergeben wird. Siehe wp-includes / template.php für einige gebräuchliche
— shea

Dieses Tutorial behandelt den single_template-Hook mit einer guten Erklärung. Sobald Sie die Haken verstanden haben, schlägt der Kommentar von @ shea einen einfacheren Ansatz vor als die Antwort von @ Bainternet add_filter( 'single-movies_template', 'my_custom_template' );. (Diese Frage ist für neue Antworten gesperrt, daher kann ich sie nicht einzeln hinzufügen.)
— Greg Perham

2
Sie könnten ersetzen PLUGIN_PATHmit plugin_dir_path( __FILE__ )und dann den ersten Schrägstrich aus dem Dateinamen entfernen. Der vollständige Pfad würde ungefähr so ​​aussehen:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
— Frits

1
PLUGIN_PATH hat einen Fehler ausgegeben. Hier ist ein großartiger Beitrag, der zeigt, wie das geht und der bei mir sofort funktioniert hat
— Nathan,

22

Aktualisierte Antwort

Sauberere und kürzere Version.

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

Alte Antwort

@Brainternet-Antwort wurde eine Überprüfung für eine benutzerdefinierte posttypspezifische Vorlage im Themenordner hinzugefügt.

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

Jetzt können Sie den Plugin-Benutzern erlauben, die Vorlage von Ihrem Plugin in ihr Design zu kopieren, um sie zu überschreiben.

In diesem Beispiel müssen sich Vorlagen im Stammverzeichnis des Plugins und des Themas befinden.


1
Verwenden locate_templatestatt get_stylesheet_directoryklingt für mich wie die Cleaner-Option (hier zu finden: code.tutsplus.com/tutorials/… ).
— Felix

1
Die aktualisierte Antwort hat nicht funktioniert, die akzeptierte Antwort (oder Ihre alte Antwort) funktioniert.
— Edward

2
Du hast recht, @Edward, das war ein schreckliches Update. Ich habe es nochmal mit Felix Vorschlag aktualisiert. Auch dieses Mal habe ich den Code vor dem Posten getestet :)
— campsjos

4

Ich möchte darauf hinweisen, dass es bei Verwendung der Filtermethode äußerst wichtig ist, den Filter wie folgt zu priorisieren:

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

Wenn Sie dies nicht tun, versucht WP manchmal, nach diesem Filter eine erneute Überprüfung durchzuführen. Zog mir aus diesem Grund etwa 2 Stunden lang die Haare aus.


0

Es gibt einen viel besseren Weg, dies für meine Plugins zu tun.

Wie @campsjos erwähnen hier , anstelle von Dateiexistenzprüfung, können Sie überprüfen , locate_templatedass in das Thema overrode Vorlagendatei überprüfen. Welches ist ganz offensichtlich.

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

Verwenden Sie den template_includeFilter-Hook, um den obigen Code zu laden.

add_filter('template_include' , 'my_plugin_templates');

0

Dank dieser Seite konnte ich die gleiche Frage für mich lösen.

Als Referenz habe ich Folgendes gefunden:

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

Der Filter-Hook {$ type} _template hat bei mir nicht funktioniert

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

Oben ist eine gute Antwort, aber das Prüfen auf die Variable $ single ermöglicht es der Vorlage, eine Vorlage zu überschreiben, wenn eine vom Thema / untergeordneten Thema bereitgestellt wird.

/* 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
Dies prüft nicht, ob single-cpt.php in einem Kind oder dem Thema vorhanden ist. Es prüft nur gegen single.php, die in allen Themen immer vorhanden sein wird.
— newpxsn

Das stimmt, als ich das schrieb, habe ich ein wirklich nacktes Thema verwendet, es muss einen besseren Weg geben!
— DigitalDesignDj
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.