Назначение Шаблона Страницы В Пользовательском Типе Записи


Я зарегистрировал пользовательский тип записи и создал файл с именем archive-myCPT.php и еще один для отдельных сообщений под названием single-myCPT.php.

Что я хочу сделать, так это создать страницу, на которой я покажу всего несколько сообщений из моего пользовательского типа сообщений. Внутри моего archive-myCPT.php У меня будет ссылка под названием, скажем, "Специальные сообщения", и эта ссылка перейдет на пользовательскую страницу, которая будет немного отличаться от archive-myCPT.php , единственная разница заключается в том, что здесь я буду использовать пользовательский запрос для сообщений.

Единственный способ сделать это, по-видимому, создать шаблон страницы, но проблема здесь в том, что я не могу назначить шаблон страницы страницам в моем CPT. Я нашел этот плагин , который может помочь мне с поддержкой шаблонов страниц для моего пользовательского типа сообщений, но он довольно старый, и я не знаю, совместим ли он с последней версией WordPress.

Есть ли какой-либо другой способ добиться этого?

Является ли это обычная/эффективная практика?

Может быть, вы могли бы порекомендовать что-нибудь еще?

Author: Howdy_McGee, 2013-12-21

2 answers

Если вы добавляете пользовательский запрос в шаблон для загрузки записей, тип записи на этой странице не обязательно должен быть вашим пользовательским типом записи. Вы можете создать обычный ванильный page, создать шаблон для этого с помощью page-your_page_slug.php или с помощью пользовательского шаблона, назначенного в раскрывающемся списке шаблоны, а затем запросить любой тип записи, который вы хотите, с помощью WP_Query.

РЕДАКТИРОВАТЬ - вот пример использования фильтра single_template. вам придется изменить тип сообщения и слаг, чтобы они соответствовали вашим.

function wpa_single_cpt_template( $templates = '' ){
    $single = get_queried_object();

    if( 'myCPT' == $single->post_type
        && 'my-special-slug' == $single->post_name )
        $templates = locate_template( 'my-special-template.php', false );

    return $templates;
}
add_filter( 'single_template', 'wpa_single_cpt_template' );

Адаптировано из пример иерархии шаблонов : Иерархия фильтров.

 1
Author: Milo, 2013-12-23 19:08:08

Вы могли бы подумать, что это будет так же просто, как добавить add_post_type_support( 'cptslug', 'page-attributes' ); в ваш код, но это не так. Если вы проверите источник, вы увидите, что раскрывающийся список шаблонов ограничен только типом записи page. Существует также примечание в Кодексе и ссылка на закрытый билет на маршрут по этой теме.

Вы можете добавить это поле в свой CPT, скопировав основную функцию, сделав небольшое редактирование и добавив новое поле.

function my_cpt_attributes_meta_box($post) {
    $post_type_object = get_post_type_object($post->post_type);
    if ( $post_type_object->hierarchical ) {
        $dropdown_args = array(
            'post_type'        => $post->post_type,
            'exclude_tree'     => $post->ID,
            'selected'         => $post->post_parent,
            'name'             => 'parent_id',
            'show_option_none' => __('(no parent)'),
            'sort_column'      => 'menu_order, post_title',
            'echo'             => 0,
        );

        $dropdown_args = apply_filters( 'page_attributes_dropdown_pages_args', $dropdown_args, $post );
        $pages = wp_dropdown_pages( $dropdown_args );
        if ( ! empty($pages) ) {
?>
<p><strong><?php _e('Parent') ?></strong></p>
<label class="screen-reader-text" for="parent_id"><?php _e('Parent') ?></label>
<?php echo $pages; ?>
<?php
        } // end empty pages check
    } // end hierarchical check.

        $template = get_post_meta($post->ID,'_wp_page_template',true);

        ?>
<p><strong><?php _e('Template') ?></strong></p>
<label class="screen-reader-text" for="page_template"><?php _e('Page Template') ?></label><select name="page_template" id="page_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php page_template_dropdown($template); ?>
</select>

<p><strong><?php _e('Order') ?></strong></p>
<p><label class="screen-reader-text" for="menu_order"><?php _e('Order') ?></label><input name="menu_order" type="text" size="4" id="menu_order" value="<?php echo esc_attr($post->menu_order) ?>" /></p>
<p><?php if ( 'page' == $post->post_type ) _e( 'Need help? Use the Help tab in the upper right of your screen.' ); ?></p>
<?php
}
function add_my_cpt_attributes_meta_box() {
  add_meta_box(
    'my_cpt_attributes_meta_box',
    'My Box Name',
    'my_cpt_attributes_meta_box',
    'book',
    'side',
    'core'
  );
}
add_action( 'add_meta_boxes', 'add_my_cpt_attributes_meta_box' );

Если вы протестируете этот код, вы будете обратите внимание, что поле появляется, но данные не сохраняются. Вот почему.

Нам придется самим сохранять данные.

function my_save_cpt_template($post_ID,$post) {
  $page_template = (isset($_POST['page_template'])) ? $_POST['page_template'] : false;
  $page_templates = wp_get_theme()->get_page_templates();
//   var_dump($page_template,$page_templates,'default' != $page_template && ! isset( $page_templates[ $page_template ] )); die;
  if ( 'default' != $page_template && ! isset( $page_templates[ $page_template ] ) ) {
      if ( $wp_error )
          return new WP_Error('invalid_page_template', __('The page template is invalid.'));
      else
          return 0;
  }
  update_post_meta($post_ID, '_wp_page_template',  $page_template);
}
add_action('save_post_cptslug','my_save_cpt_template',1,2);

Теперь он должен сохраниться, но шаблон не загружается. Вот почему. get_single_template выполняется перед get_page_template, и get_page_template - это то, что ищет специализированные шаблоны. Поэтому нам нужно загрузить этот шаблон самим.

add_action(
  'template_include',
  function ($template) {
    global $post;
    if (is_singular() && isset($post->post_type) && 'book' === $post->post_type) {
      $new = get_post_meta($post->ID,'_wp_page_template',true);
      $new = locate_template($new);
      if (!empty($new)) {
        $template = $new;
      }
    }
    return $template;
  }
);

Едва проверено. Возможно, глючит. Будьте бдительны. Никаких возвратов.

 1
Author: s_ha_dum, 2013-12-22 15:00:00