Создание пользовательского шаблона публикации по умолчанию, который может быть переопределен темой
Я нахожусь в процессе создания плагина Wordpress, который добавляет пользовательский тип записи, для которого я хотел бы включить шаблон по умолчанию для отображения. По сути, это плагин для управления событиями, и пользовательский тип записи предназначен для событий. Существует несколько настраиваемых мета-полей, а также дочерний тип публикации (Выступления), поэтому без шаблона по умолчанию для их отображения его использование было бы довольно недружелюбным. Но я бы хотел, чтобы дизайнеры тем могли создавать свои собственные шаблоны для этих типов записей, если это необходимо.
Есть ли способ использовать шаблон, поставляемый с моим плагином, если тема не предоставляет свой собственный шаблон? Какова наилучшая практика для этого?
Редактировать:
Следуя совету Питера Роуэлла, я поймал действие template_redirect и, если тип сообщения был одним из моих, а шаблон для него не существовал в текущей теме, по умолчанию использовал шаблон плагина:
class FestivityTemplates {
public static function determineTemplate(){
global $post;
$standard_type = strpos($post->post_type, 'fest_');
if(is_single() && $standard_type !== false) {
FestivityTemplates::loadSingleTemplate($post);
}
}
private static function loadSingleTemplate($post) {
$template_name = 'single-'.$post->post_type.'.php';
$template = locate_template(array($template_name), true);
if(empty($template)) {
include(WP_PLUGIN_DIR . '/Festivity/lib/templates/' . $template_name);
exit();
}
}
}
add_action('template_redirect', array('FestivityTemplates', 'determineTemplate'));
3 answers
Возможно, вы захотите взглянуть на процедуру, которую WP использует для этого: locate_template()
. Он находится в wp-includes/theme.php
и вызывается из ряда функций в этом файле. Эти функции используются wp-includes/template-loader.php
для выбора правильного типа шаблона на основе текущей страницы, а затем поднимаются по иерархии тем в поисках соответствия.
Также есть набор фильтров, связанных с шаблонами (прокрутите вниз), которые вы можете использовать, чтобы "перехватывать" запросы шаблонов и применять к ним свою собственную логику .
Вот пример того, как перехватить вызовы single-saalon_events.php
и archive-saalon_events.php
и использовать файлы из папки /your-plugin/templates/
вместо этого:
# Template for displaying a single event
add_filter( 'single_template', 'saalon_events_single_template') ) ;
function saalon_events_single_template($single_template) {
global $post;
if ($post->post_type == 'saalon_events')
$single_template = dirname( __FILE__ ) . '/templates/saalon_events_single.php';
return $single_template;
}
# Template for displaying the events archive
add_filter( 'archive_template', 'saalon_events_archive_template') ) ;
function saalon_events_archive_template($archive_template) {
if ( is_post_type_archive('saalon_events') ) // since 3.1
$archive_template = dirname( __FILE__ ) . '/templates/saalon_events_archive.php';
return $archive_template;
}
Resources:
http://codex.wordpress.org/Plugin_API/Filter_Reference#Template_Filters
http://codex.wordpress.org/Plugin_API/Filter_Reference/_single_template
О, и template_redirect
Действие тоже выглядит неплохо!
http://codex.wordpress.org/Plugin_API/Action_Reference#Template_Actions
Надеюсь, это поможет!
Я не знаю, является ли это лучшей практикой, но когда я столкнулся с подобной проблемой, я использовал крючок the_content, проверил тип записи, чтобы узнать, мой ли это пользовательский тип, и если да, то я вернул именно то, что хотел. например:
add_filter('the_content','events_conetnt_display');
function events_conetnt_display($content){
global $post;
if (!$post_type == "events"){
return $content;
}else{
remove_filter( 'the_content', 'events_conetnt_display' );
$events_meta = get_post_custom($post->ID);
$new_content = '<div class="event_container">';
$new_content .= '<div class="event_title">'.get_the_title($post->ID).'</div>';
$new_content .= '<div class="event_description">'.apply_filters('the_content',get_the_content()).'</div>';
$new_content .= '<div class="event_start_date">'.$events_meta['start_date'].'</div>';
$new_content .= '<div class="event_end_date">'.$events_meta['start_end'].'</div>';
//...
//whatever
//...
add_filter('the_content','events_conetnt_display');
return $new_content;
}
}
И у моего плагина была возможность позволить пользователю решать, использовать ли ему крючок the_content или у него есть собственный шаблон для этого, например:
if (get_option('use_content_template')){
add_filter('the_content','events_conetnt_display');
}