Створіть у плагіні користувацьку сторінку архіву для користувацького типу публікації


11

Я пишу плагін, який створює спеціальний тип публікації під назвою "my_plugin_lesson":

$args = array (
    'public' => true,
    'has_archive' => true,
    'rewrite' => array('slug' => 'lessons', 'with_front' => false)
);
register_post_type ('my_plugin_lesson', $args);

Спеціальний тип публікації має архів, а URL-адреса архіву:

http://example.com/lessons

Я хочу налаштувати вигляд цього архіву; Я хочу перелічити публікації у форматі таблиці, а не у стандартному архіві публікацій блогу WordPress. Я розумію, що власний шаблон архіву можна створити в темі, створивши archive-my_plugin_lesson.phpфайл; однак я хотів би, щоб плагін працював з будь-якою темою.

Як я можу змінити вміст сторінки архіву без додавання або зміни файлів тем?

Редагувати: Я розумію, що міг би використовувати archive_templateгачок фільтра. Однак все це - замінити шаблон теми, який все ще повинен бути тематичним. Наприклад, майже кожен шаблоном тема буде потрібна get_header, get_sidebarі get_footerфункція, але що йде ідентифікатор вмісту <div>бути? Це різне в кожній темі.

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

Відповіді:


12

Вам потрібно підключити template_includeфільтр і вибірково завантажувати ваш шаблон всередину плагіна.

Як хороша практика, якщо ви плануєте розповсюджувати свій плагін, слід перевірити, archive-my_plugin_lesson.phpчи myplugin/archive-lesson.phpіснує (або, можливо ) тема, чи не використовується версія плагіна.

Таким чином користувачі легко замінюють шаблон на тему (або дочірню тему) без редагування коду плагіна.

Це метод, який використовують популярні плагіни, наприклад WooCommmerce, просто щоб сказати одне ім’я.

add_filter('template_include', 'lessons_template');

function lessons_template( $template ) {
  if ( is_post_type_archive('my_plugin_lesson') ) {
    $theme_files = array('archive-my_plugin_lesson.php', 'myplugin/archive-lesson.php');
    $exists_in_theme = locate_template($theme_files, false);
    if ( $exists_in_theme != '' ) {
      return $exists_in_theme;
    } else {
      return plugin_dir_path(__FILE__) . 'archive-lesson.php';
    }
  }
  return $template;
}

Більше інформації про Codex для


Це все ще просто замінює файл шаблону теми, правда? Що я можу вставити у файл-сховище.php мого плагіна? Для роботи з кожною темою потрібно було б бути різним. Навіть теми «Двадцять» за замовчуванням не погоджуються щодо того, які контейнери дів / секцій оточують вміст.
Бен Міллер - Згадайте Моніку

7

Ви можете використовувати archive_templateгачок для обробки вмісту шаблону архіву теми, використовуючи схему нижче, але очевидно, ви зможете обробити лише частину тем там, враховуючи, що шаблон може містити будь-яку стару річ .

Схема полягає в завантаженні шаблона в рядок ( $tpl_str) у archive_templateфільтр, підміна його вмісту, включення рядка (з використанням трюку eval( '?>' . $tpl_str );), а потім повернення порожнього файлу, щоб includeу "wp-include / template-loader.php" стає не-оп.

Нижче наведена зламана версія коду, який я використовую у плагіні, який націлений на "класичні" шаблони, які використовують, get_template_partі більше стосується обробки окремих шаблонів, ніж архіву, але повинен допомогти вам розпочати роботу. Установка полягає в тому, що плагін має підкаталог під назвою "шаблони", який містить порожній файл ("null.php") і шаблони вмісту (наприклад, "content-single-posttype1.php", "content-archive-postype1.php") а також шаблону "back.php" для одиночного випадку та використовує власну версію, get_template_partяка виглядає в цьому каталозі.

define( 'MYPLUGIN_FOLDER', dirname( __FILE__ ) . '/' );
define( 'MYPLUGIN_BASENAME', basename( MYPLUGIN_FOLDER ) );

add_filter( 'single_template', 'myplugin_single_template' );
add_filter( 'archive_template', 'myplugin_archive_template' );

function myplugin_single_template( $template ) {
    static $using_null = array();

    // Adjust with your custom post types.
    $post_types = array( 'posttype1', );

    if ( is_single() || is_archive() ) {
        $template_basename = basename( $template );
        // This check can be removed.
        if ( $template == '' || substr( $template_basename, 0, 4 ) == 'sing' || substr( $template_basename, 0, 4 ) == 'arch' ) {
            $post_type = get_post_type();
            $slug = is_archive() ? 'archive' : 'single';
            if ( in_array( $post_type, $post_types ) ) {
                // Allow user to override.
                if ( $single_template = myplugin_get_template( $slug, $post_type ) ) {
                    $template = $single_template;
                } else {
                    // If haven't gone through all this before...
                    if ( empty( $using_null[$slug][$post_type] ) ) {
                        if ( $template && ( $content_template = myplugin_get_template( 'content-' . $slug, $post_type ) ) ) {
                            $tpl_str = file_get_contents( $template );
                            // You'll have to adjust these regexs to your own case - good luck!
                            if ( preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*get_post_format\s*\(\s*\)\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'content\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'[^\']+\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE ) ) {
                                $using_null[$slug][$post_type] = true;
                                $tpl_str = substr( $tpl_str, 0, $matches[0][1] ) . 'include \'' . $content_template . '\'' . substr( $tpl_str, $matches[0][1] + strlen( $matches[0][0] ) );
                                // This trick includes the $tpl_str.
                                eval( '?>' . $tpl_str );
                            }
                        }
                    }
                    if ( empty( $using_null[$slug][$post_type] ) ) {
                        // Failed to parse - look for fall back template.
                        if ( file_exists( MYPLUGIN_FOLDER . 'templates/' . $slug . '.php' ) ) {
                            $template = MYPLUGIN_FOLDER . 'templates/' . $slug . '.php';
                        }
                    } else {
                        // Success! "null.php" is just a blank zero-byte file.
                        $template = MYPLUGIN_FOLDER . 'templates/null.php';
                    }
                }
            }
        }
    }
    return $template;
}

function myplugin_archive_template( $template ) {
    return myplugin_single_template( $template );
}

Звичай get_template_part:

/*
 * Version of WP get_template_part() that looks in theme, then parent theme, and finally in plugin template directory (sub-directory "templates").
 * Also looks initially in "myplugin" sub-directory if any in theme and parent theme directories so that plugin templates can be kept separate.
 */
function myplugin_get_template( $slug, $part = '' ) {
    $template = $slug . ( $part ? '-' . $part : '' ) . '.php';

    $dirs = array();

    if ( is_child_theme() ) {
        $child_dir = get_stylesheet_directory() . '/';
        $dirs[] = $child_dir . MYPLUGIN_BASENAME . '/';
        $dirs[] = $child_dir;
    }

    $template_dir = get_template_directory() . '/';
    $dirs[] = $template_dir . MYPLUGIN_BASENAME . '/';
    $dirs[] = $template_dir;
    $dirs[] = MYPLUGIN_FOLDER . 'templates/';

    foreach ( $dirs as $dir ) {
        if ( file_exists( $dir . $template ) ) {
            return $dir . $template;
        }
    }
    return false;
}

Для повноти ось ось "back.php", який використовує звичай get_template_part:

<?php
get_header(); ?>

    <div id="primary" class="content-area">
        <div id="content" class="clearfix">
            <?php while ( have_posts() ) : the_post(); ?>

            <?php if ( $template = myplugin_get_template( 'content-single', get_post_type() ) ) include $template; else get_template_part( 'content', 'single' ); ?>

                <?php
                    // If comments are open or we have at least one comment, load up the comment template
                    if ( comments_open() || '0' != get_comments_number() ) :
                        comments_template();
                    endif;
                ?>

            <?php endwhile; ?>

        </div><!-- #content -->
    </div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

1

Я розмірковував над тим же питанням, і це гіпотетичне рішення, з яким я придумав:

  • У плагіні створіть короткий код, який виводить цикл архіву так, як вам завгодно.
  • Під час створення користувальницького типу публікації не вмикайте параметр "архів".
  • Додайте таблицю стилів, яка контролює всі стилі вмісту циклу.

Після активації плагіну створіть сторінку, використовуючи wp_insert_post з назвою типу публікації, а вміст - коротким кодом.

Ви можете надати параметри в короткому коді для додаткових міркувань щодо стилю або додати класи до контейнера для публікації, щоб відповідати певним або спеціальним стилям. Користувач також може додавати додатковий вміст до / після циклу, редагуючи сторінку.


Незважаючи на те, що я не ОП, я шукав рішення тієї ж проблеми. Я дотримувався вашого гіпотетичного рішення і тепер можу підтвердити, що він працює і на практиці.
Lucio Crusca

Гей чудово! Радий, що це комусь було корисно. Я зовсім забув про це.
SkyShab

0

Можна використовувати фільтр single_template. Основний приклад, взятий з Кодексу :

function get_custom_post_type_template($single_template) {
     global $post;

     if ($post->post_type == 'my_post_type') {
          $single_template = dirname( __FILE__ ) . '/post-type-template.php';
     }
     return $single_template;
}

add_filter( "single_template", "get_custom_post_type_template" );

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