Șabloane pentru Tipuri de Postări Personalizate din Directorul Plugin-ului?
Aș dori să ofer tipul meu de postare personalizată ca Plugin, astfel încât oamenii să îl poată folosi fără a modifica directorul temei lor. Dar șabloanele pentru tipuri de postări personalizate -- cum ar fi single-movies.php -- se află în directorul temei. Există vreo modalitate de a face WordPress să verifice existența unui fișier single-movies.php în directorul plugin-ului? Prin atașarea unei funcții la Ierarhia de Filtrare? Sau folosind get_template_directory(); ?

Poți utiliza filtrul single_template
.
/* Filtrează single_template cu funcția noastră personalizată */
add_filter('single_template', 'my_custom_template');
function my_custom_template($single) {
global $post;
/* Verifică template-ul pentru un anumit tip de post */
if ( $post->post_type == 'NUMELE TIPULUI DE POST' ) {
if ( file_exists( PLUGIN_PATH . '/Custom_File.php' ) ) {
return PLUGIN_PATH . '/Custom_File.php';
}
}
return $single;
}

Este un răspuns minunat. Te rog să împărtășești unde pot găsi toate cârligele disponibile pentru șabloane, precum single_template.

@gowri Filtrul este apelat de funcția get_query_template()
. Este un cârlig variabil, așa că prima parte {$type}_template
se schimbă în funcție de parametrul transmis acestei funcții. Vezi wp-includes/template.php pentru unele exemple comune

Acest tutorial acoperă cârligul single_template cu o explicație bună. Odată ce înțelegi cârligele, comentariul lui @shea sugerează o abordare mai simplă decât răspunsul lui @Bainternet, folosind add_filter( 'single-movies_template', 'my_custom_template' );
ca în tutorialul linkuit. (Această întrebare este închisă pentru răspunsuri noi, așa că nu o pot adăuga separat.)

Poți înlocui PLUGIN_PATH
cu plugin_dir_path( __FILE__ )
și apoi să elimini prima liniuță din numele fișierului tău. Calea completă ar arăta cam așa: return plugin_dir_path( __FILE__ ) . 'Custom_File.php';

Este posibil ca PLUGIN_PATH să se numească WP_PLUGIN_DIR în zilele noastre.

PLUGIN_PATH a generat o eroare, iată un articol excelent care arată cum să faci asta și a funcționat pentru mine imediat: https://wpsites.net/free-tutorials/load-single-template-from-plugin-for-different-post-types/

Răspuns actualizat
Versiune mai curată și mai scurtă.
function load_movie_template( $template ) {
global $post;
if ( 'movie' === $post->post_type && locate_template( array( 'single-movie.php' ) ) !== $template ) {
/*
* Aceasta este o postare de tip 'movie'
* ȘI nu s-a găsit un șablon 'single movie' în
* directoarele temei sau temei copil, așa că îl încărcăm
* din directorul pluginului nostru.
*/
return plugin_dir_path( __FILE__ ) . 'single-movie.php';
}
return $template;
}
add_filter( 'single_template', 'load_movie_template' );
Răspuns vechi
Am adăugat o verificare pentru un șablon specific tipului de postare personalizată în directorul temei la răspunsul lui @Brainternet.
function load_cpt_template($template) {
global $post;
// Este aceasta o postare de tip "my-custom-post-type"?
if ($post->post_type == "my-custom-post-type"){
//Calea pluginului tău
$plugin_path = plugin_dir_path( __FILE__ );
// Numele șablonului single pentru tipul de postare personalizată
$template_name = 'single-my-custom-post-type.php';
// Există un șablon single specific în directorul temei? Sau nu există nici în pluginul meu?
if($template === get_stylesheet_directory() . '/' . $template_name
|| !file_exists($plugin_path . $template_name)) {
//Atunci returnează "single.php" sau "single-my-custom-post-type.php" din directorul temei.
return $template;
}
// Dacă nu, returnează șablonul din plugin.
return $plugin_path . $template_name;
}
//Nu este tipul meu de postare personalizată, nu face nimic cu $template
return $template;
}
add_filter('single_template', 'load_cpt_template');
Acum poți permite utilizatorilor pluginului să copieze șablonul din plugin în tema lor pentru a-l suprascrie.
Cu acest exemplu, șabloanele trebuie să fie în directorul rădăcină atât al pluginului cât și al temei.

Folosirea locate_template
în loc de get_stylesheet_directory
mi se pare o opțiune mai curată (găsit aici: http://code.tutsplus.com/tutorials/a-guide-to-wordpress-custom-post-types-creation-display-and-meta-boxes--wp-27645).

Răspunsul actualizat nu a funcționat, răspunsul acceptat (sau vechiul tău răspuns) funcționează.

Aș dori să subliniez că atunci când utilizați metoda de filtrare pentru aceasta, este extrem de important să prioritizați filtrul astfel:
add_filter('single_template', 'my_custom_template', 99);
Dacă nu faceți acest lucru, uneori WP va încerca să verifice din nou după acest filtru. Am stat aproape 2 ore să-mi smulg părul din cap din cauza asta.

În propriile mele plugin-uri, folosesc de obicei locate_template()
, ceea ce face posibilă suprascrierea șablonului plugin-ului prin copierea acestuia în tema curentă:
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');
Acum utilizatorul poate suprascrie șablonul plugin-ului copiind fișierul din folderul plugin-ului templates/single-custom_post.php
și plasându-l fie direct în rădăcina temei, fie într-un folder templates
din tema activă.
Cred că aceeași abordare ar trebui să funcționeze și atunci când se folosește filtrul single_template
.

Există o metodă mult mai bună de a face acest lucru pe care o folosesc pentru plugin-urile mele.
După cum menționează @campsjos aici, în loc să verifici existența fișierului, poți verifica
locate_template
care va căuta șablonul suprascris în tema. Ceea ce este destul de evident.
function my_plugin_templates() {
if (is_singular('movie')) {
if (file_exists($this->template_dir . 'single-movie.php')) {
return $this->template_dir . 'single-movie.php';
}
}
}
Folosește filtru template_include
pentru a încărca codul de mai sus.
add_filter('template_include' , 'my_plugin_templates');

mulțumesc acestei pagini, am reușit să rezolv aceeași problemă pentru mine.
Pentru referință, iată cu ce am rămas:
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');
filtru-ul {$type}_template nu a funcționat pentru mine
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');

Acest lucru funcționează pentru mine, te rog să încerci, Mulțumesc
Șabloanele sunt încărcate în fișierul cpt, care se află la
custom_plugin -> app -> cpt -> cpt_article.php
Șablonul este localizat
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;
}

Răspunsul de mai sus este foarte bun, dar verificarea variabilei $single permite șablonului să suprascrie un șablon dacă acesta este furnizat de tema/tema copil.
/* Filtrează single_template cu funcția noastră personalizată */
add_filter('single_template', 'your_cpt_custom_template');
function your_cpt_custom_template( $single ) {
global $wp_query, $post;
/* Verifică dacă există un șablon single pentru tipul de post */
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;
}

Acest lucru nu verifică dacă single-cpt.php este prezent în child theme sau în tema principală. Verifică doar față de single.php, care va fi întotdeauna prezent în orice teme.
