Спеціальні шаблони типу публікації з папки плагіна?


57

Я хотів би запропонувати свій власний тип публікації як плагін, щоб люди могли ним користуватися, не торкаючись папки їх тем. Але спеціальні шаблони типу публікації - наприклад, single-movies.php - знаходяться у папці тем. Чи є спосіб отримати WP для перевірки наявності single-movies.php у папці плагіна? Приєднання функції до ієрархії Філера ? Або get_template_directory (); ?

Відповіді:


90

Можна використовувати single_templateгачок фільтра.

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

}

Це приголомшлива відповідь. Будь ласка, поділіться, чи можу я отримати всі доступні шаблони шаблонів, як single_template.
Гоурі

6
@gowri Фільтр викликається get_query_template()функцією. Це гак змінної, тому перша частина {$type}_templateзмінюється залежно від того, який параметр передається цій функції. Див. Wp-include / template.php для деяких поширених
shea

Цей підручник охоплює гачок з одним шаблоном з хорошим поясненням. Як тільки ви зрозумієте гачки, коментар @ shea пропонує більш простий підхід, ніж відповідь @ Bainternet, використовуючи, add_filter( 'single-movies_template', 'my_custom_template' );як у пов'язаному підручнику. (Це запитання закрито для нових відповідей, тому я не можу його самостійно додати.)
Грег Перхем,

2
Ви могли б замінити PLUGIN_PATHз , plugin_dir_path( __FILE__ )а потім видалити перший слеш від Вашого імені файлу. Повний шлях виглядав би приблизно так:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
Фріт

1
PLUGIN_PATH видав помилку, ось чудовий допис, який показує, як це зробити, і він працював для мене з коробки: wpsites.net/free-tutorials/…
Натан

22

Оновлена ​​відповідь

Чистіший і коротший варіант.

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

Стара відповідь

До відповіді @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');

Тепер ви можете дозволити користувачам плагіну скопіювати шаблон із вашого плагіна на їхню тему, щоб змінити його.

У цьому прикладі шаблони повинні бути в кореневій директорії як плагіна, так і теми.


1
Використання locate_templateзамість get_stylesheet_directoryзвуків, як для мене чистіший варіант (знайдено тут: code.tutsplus.com/tutorials/… ).
Фелікс

1
Оновлена ​​відповідь не працювала, прийнята відповідь (або ваша стара відповідь) працює.
Едвард

2
Ви маєте рацію, @Edward, це було жахливе оновлення. Я оновив його знову за пропозицією Фелікса. Також цього разу я перевірив код, перш ніж публікувати його :)
Campjos

4

Я хотів би зазначити, що коли ви використовуєте для цього метод фільтрування, надзвичайно важливо розставити пріоритет фільтру так:

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

Якщо цього не зробити, інколи WP спробує повторно перевірити цей фільтр. Витягнув волосся через це протягом 2 годин.


0

Є набагато кращий спосіб зробити це, який я використовую для своїх плагінів.

Як тут згадується @campsjos , замість того, щоб перевірити існування файлів, ви можете перевірити, чи буде перевірятись файл шаблону, який переоцінив тему. Що цілком очевидно.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';
        }
    }
}

Використовуйте template_includeгачок фільтра для завантаження вище коду.

add_filter('template_include' , 'my_plugin_templates');

0

завдяки цій сторінці я зміг вирішити те саме питання для мене.

Для довідки, ось що я закінчив:

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

{$ type} _ гачок фільтру шаблону не працював для мене

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

Вище є чудовою відповіддю, але перевірка наявності $ single var дозволяє шаблону перекрити шаблон, якщо його надає тема / дочірня тема.

/* 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
Це не перевіряє, чи є одна дитина-cpt.php у дитини або в темі. Він перевіряє лише single.php, який завжди буде присутній у будь-яких темах.
newpxsn

Правильно, коли я писав це, я використовував справді голу тему, має бути кращий спосіб!
DigitalDesignDj
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.