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 (); ?

nathanbweb
quelle

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;

}
Bainternet
quelle
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.

campsjos
quelle
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.

RBizzle
quelle
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');
Pixelngrain
quelle
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');
Thomas Fellinger
quelle
-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;
}
DigitalDesignDj
quelle
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