Создание пользовательского шаблона публикации по умолчанию, который может быть переопределен темой


Я нахожусь в процессе создания плагина 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'));
Author: saalon, 2011-03-17

3 answers

Возможно, вы захотите взглянуть на процедуру, которую WP использует для этого: locate_template(). Он находится в wp-includes/theme.php и вызывается из ряда функций в этом файле. Эти функции используются wp-includes/template-loader.php для выбора правильного типа шаблона на основе текущей страницы, а затем поднимаются по иерархии тем в поисках соответствия.

 4
Author: Peter Rowell, 2011-03-17 14:54:13

Также есть набор фильтров, связанных с шаблонами (прокрутите вниз), которые вы можете использовать, чтобы "перехватывать" запросы шаблонов и применять к ним свою собственную логику .

Вот пример того, как перехватить вызовы 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

Надеюсь, это поможет!

 4
Author: Michal Mau, 2011-03-17 20:05:12

Я не знаю, является ли это лучшей практикой, но когда я столкнулся с подобной проблемой, я использовал крючок 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');
}
 1
Author: Bainternet, 2011-03-17 16:21:30