Niestandardowe szablony typów wpisów z folderu wtyczek?

57

Chciałbym zaoferować mój niestandardowy typ postu jako wtyczkę, aby ludzie mogli go używać bez dotykania folderu motywu. Ale niestandardowe szablony typów postów - takie jak single-movies.php - znajdują się w folderze motywów. Czy istnieje sposób, aby WP sprawdził, czy w folderze wtyczki jest plik single-movies.php? Podłączanie funkcji do hierarchii filtrów ? Lub get_template_directory (); ?

nathanbweb
źródło

Odpowiedzi:

90

Możesz użyć single_templatehaka filtra.

/* 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
źródło
To świetna odpowiedź. Udostępnij, czy mogę uzyskać wszystkie dostępne haki szablonu, takie jak single_template.
Gowri
6
@gowri Filtr jest wywoływany przez get_query_template()funkcję. Jest to zmienny haczyk, więc pierwsza część {$type}_templatezmienia się w zależności od parametru przekazanego do tej funkcji. Zobacz wp-include / template.php, aby zapoznać się z niektórymi typowymi
shea
W tym samouczku omówiono haczyk single_template z dobrym wyjaśnieniem. Kiedy zrozumiesz haczyki, komentarz @ shea sugeruje prostsze podejście niż odpowiedź @ Bainternet, używając add_filter( 'single-movies_template', 'my_custom_template' );jak w połączonym samouczku. (To pytanie jest zamknięte na nowe odpowiedzi, więc nie mogę go dodać samodzielnie).
Greg Perham
2
Można wymienić PLUGIN_PATHz plugin_dir_path( __FILE__ )czym usunąć pierwszy ukośnik z nazwy pliku. Pełna ścieżka wyglądałaby return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
Frits
1
PLUGIN_PATH rzucił błąd, oto świetny post, który pokazuje, jak to zrobić i zadziałało dla mnie po wyjęciu z pudełka: wpsites.net/free-tutorials/…
Nathan
22

Zaktualizowana odpowiedź

Czystsza i krótsza wersja.

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

Stara odpowiedź

Dodano sprawdzanie niestandardowego szablonu określonego typu posta w folderze motywu do odpowiedzi @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');

Teraz możesz pozwolić użytkownikom wtyczki skopiować szablon z wtyczki do ich motywu, aby go zastąpić.

W tym przykładzie szablony muszą znajdować się w katalogu głównym wtyczki i kompozycji.

campsjos
źródło
1
Używanie locate_templatezamiast dla mnie get_stylesheet_directorybrzmi jak opcja czyszczenia (znajduje się tutaj: code.tutsplus.com/tutorials/... ).
Felix
1
Zaktualizowana odpowiedź nie działała, zaakceptowana odpowiedź (lub twoja stara odpowiedź) działa.
Edward
2
Masz rację, @Edward, to była przerażająca aktualizacja. Zaktualizowałem go ponownie z sugestią Felixa. Również tym razem przetestowałem kod przed opublikowaniem go :)
campsjos,
4

Chciałbym zauważyć, że kiedy używasz do tego metody filtrowania, niezwykle ważne jest nadanie priorytetu filtrowi w ten sposób:

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

Jeśli tego nie zrobisz, czasami WP spróbuje ponownie sprawdzić po tym filtrze. Z tego powodu wyciągałam włosy przez jakieś 2 godziny.

RBizzle
źródło
0

Jest o wiele lepszy sposób, aby to zrobić, którego używam do swoich wtyczek.

Jak wspomniano tutaj @campsjos , zamiast sprawdzania istnienia pliku, możesz sprawdzić , czy spowoduje to zastąpienie pliku szablonu kompozycji. Co jest dość oczywiste.locate_template

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

Użyj template_includehaka filtra, aby załadować powyżej kodu.

add_filter('template_include' , 'my_plugin_templates');
pixelngrain
źródło
0

dzięki tej stronie udało mi się rozwiązać to samo pytanie.

Dla porównania skończyłem z:

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

hak filtrujący {$ type} _template nie działał dla mnie

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
źródło
-2

Powyżej jest świetną odpowiedzią, ale sprawdzenie $ single var pozwala szablonowi zastąpić szablon, jeśli jest on dostarczony przez motyw / motyw potomny.

/* 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
źródło
1
Nie sprawdza to, czy plik single-cpt.php jest obecny w podrzędnym lub kompozycji. Sprawdza tylko w stosunku do single.php, który zawsze będzie obecny w dowolnym temacie.
newpxsn
Zgadza się, kiedy to napisałem, używałem naprawdę nagiego motywu, musi być lepszy sposób!
DigitalDesignDj