Intereting Posts
Почему в шаблонах содержится так много пар тэгов PHP? Несколько таксономий в одном правиле permalink Могу ли я заблокировать пост в позиции, поэтому он всегда появляется на главной странице? Измените вывод для короткого кода Как клонировать wp-admin и создавать новую панель управления, управляемую вашим кодом? Получить идентификатор комментария верхнего уровня Изменить количество столбцов виджетов на панели управления? Самый элегантный способ вставить скрипты в function.php с помощью цикла foreach Показывать одно сообщение, то все сообщения (с разбивкой на страницы) Поиск сообщений / Страницы с несколькими вариантами? Добавить пользовательский текст в мета-области изображения медиа-библиотеки Установка WordPress вводит бесконечный цикл Страница частично кэширования с супер кешем Как сделать регистрационную форму ajax? Как заказывать сообщения в произвольном порядке?

Создайте страницу пользовательского архива для персонализированного типа сообщения в плагине

Я пишу плагин, который создает собственный тип сообщения с именем «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-my_plugin_lesson.php ; однако, я хотел бы, чтобы плагин работал с любой темой.

Как изменить содержимое страницы архива без добавления или изменения файлов тем?

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

То, что я хотел бы сделать, это заменить сам контент собственным контентом и использовать его вместо страницы архива для моего настраиваемого типа сообщений.

Solutions Collecting From Web of "Создайте страницу пользовательского архива для персонализированного типа сообщения в плагине"

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

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

Ниже приведена взломанная версия кода, который я использую в плагине, который предназначен для «классических» шаблонов, которые используют get_template_part и больше заботятся о обработке отдельных шаблонов, кроме архива, но должны помочь вам приступить к работе. Настройка заключается в том, что у плагина есть подкаталог под названием «шаблоны», который содержит пустой файл («null.php») и шаблоны контента (например, «content-single-posttype1.php», «content-archive-postype1.php») а также шаблон возврата «single.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; } 

Для полноты здесь отпадает «single.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(); ?> 

Вам нужно подключить фильтр 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 for

  • Фильтр template_include
  • Функция locate_template

Я размышлял над тем же вопросом, и это гипотетическое решение, которое я придумал:

  • Внутри плагина создайте короткий код, который выводит ваш цикл архива так, как вы пожелаете.
  • При создании настраиваемого типа сообщения не включайте параметр «архив».
  • Добавьте таблицу стилей, которая управляет всеми стилями содержимого цикла.

При активации плагина создайте страницу с помощью wp_insert_post с именем, являющимся типом сообщения, а контент – коротким.

Вы можете предоставить опции в коротком коде для дополнительных соображений стиля или добавить классы в почтовый контейнер в соответствии с конкретными темами или настраиваемыми стилями. Пользователь также может добавлять дополнительный контент до / после цикла, редактируя страницу.

Вы можете использовать фильтр 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" );