Пользовательский тип записи, нет необходимости в отдельном просмотре, плюс требуется постоянная перезапись, включающая хэш в URI

8

Мы используем CPT для управления страницей часто задаваемых вопросов на сайте, где вопрос - это заголовок сообщения, а ответ - содержание сообщения. Существует главная страница для часто задаваемых вопросов, которая показывает все сообщения (страница архива FAQ). С этой структурой у нас действительно нет необходимости в едином представлении для любого FAQ и фактически мы хотели бы исключить его из структуры сайта. Чтобы обратиться к постоянным ссылкам, мы бы хотели задать для них что-то вроде example.com/faq/#uniqueIdentifier, думая, что мы будем использовать #uniqueIdentifier для сопоставления с div на странице архива, содержащей ответ, и привлекать к нему внимание в некоторых мода. UniqueIdentifier может быть идентификатором записи, заголовком часто задаваемого вопроса, данными из мета-блока или чем-то еще.

Итак, позвольте мне напомнить, что мне нужно сделать:

(1) переписать постоянные ссылки faq, чтобы они были / faq / # что-то, и

(2) убедитесь, что все / faq / links ссылаются на шаблон архива, а не один

Я в основном новичок, но довольно хорош в поисках вещей. Никогда не пытался что-либо переписать, хотя поэтому был бы признателен за определенное направление в этом.

Спасибо.

daxitude
источник

Ответы:

12

Привет @daxitude:

Позвольте мне сначала предложить вам пересмотреть. Если у вас нет отдельных страниц FAQ для каждого FAQ:

  1. Вы уменьшаете свою поверхность для поисковой оптимизации и уменьшаете потенциальный трафик, который вы можете получить, и

  2. Вы лишаете кого-либо возможности делиться определенными часто задаваемыми вопросами с друзьями по электронной почте и / или делиться ими со своей сетью в Facebook, Twitter и т. Д. (Как пользователь, я всегда разочарован разработчиками сайтов, которые запрещают мне иметь прямой URL-адрес к элементу и вместо этого вынудите меня дать ссылку на страницу со списком всех элементов.)

Однако, если вы все еще хотите сделать это, сделайте две вещи:

1.) Используйте 'post_type_link'крючок

Используйте 'post_type_link'хук, чтобы изменить URL, как в следующем примере * (я предполагаю, что ваш пользовательский тип записи 'faq'). Добавьте следующее в functions.phpфайл вашей темы :

add_action('post_type_link','yoursite_post_type_link',10,2);
function yoursite_post_type_link($link,$post) {
  $post_type = 'faq';
  if ($post->post_type==$post_type) {
    $link = get_post_type_archive_link($post_type) ."#{$post->post_name}";
  }
  return $link;
}

2.) unset($wp_rewrite->extra_permastructs['faq'])

Это взлом , но это обязательный взлом, чтобы делать то, что вы хотите. Используйте 'init'крючок для unset($wp_rewrite->extra_permastructs['faq']). Это удаляет правило перезаписи, которое register_post_type()добавляет. Я включаю вызов, register_post_type()чтобы я мог предоставить полный пример для вас и других:

add_action('init','yoursite_init');
function yoursite_init() {
  register_post_type('faq',array(
      'labels' => array(
      'name' => _x('FAQs', 'post type general name'),
      'singular_name' => _x('FAQ', 'post type singular name'),
      'add_new' => _x('Add New', 'faq'),
      'add_new_item' => __('Add New FAQ'),
      'edit_item' => __('Edit FAQ'),
      'new_item' => __('New FAQ'),
      'view_item' => __('View FAQ'),
      'search_items' => __('Search FAQs'),
      'not_found' =>  __('No FAQs found'),
      'not_found_in_trash' => __('No FAQs found in Trash'),
      'parent_item_colon' => '',
      'menu_name' => 'FAQs'
    ),
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'query_var' => true,
    'rewrite' => array('slug'=>'faqs'),
    'capability_type' => 'post',
    'has_archive' => 'faqs',
    'hierarchical' => false,
    'supports' => array('title','editor','author','thumbnail','excerpt')
  ));

  global $wp_rewrite;
  unset($wp_rewrite->extra_permastructs['faq']);  // Removed URL rewrite for specific FAQ 
  $wp_rewrite->flush_rules(); // THIS SHOULD BE DONE IN A PLUGIN ACTIVATION HOOK, NOT HERE!
}

Вот и все.

Конечно, приведенное выше использование $wp_rewrite->flush_rules()в 'init'хуке - это действительно плохая практика, и его нужно делать только один раз, поэтому я реализовал полный и автономный плагин, призванный FAQ_Post_Typeсделать это правильно. Этот плагин добавляет тип поста FAQ с нужными вам правилами URL и использует a register_activation_hook()для очистки правил перезаписи; очевидно, что активация - это одна из немногих вещей, для которой требуется код плагина вместо кода, который может выполняться в functions.phpфайле темы .

Вот код для FAQ_Post_Typeплагина; не стесняйтесь изменять для ваших требований:

<?php
/*
Plugin Name: FAQ Post Type
Description: Answers the question "Custom post type, no need for single view, plus want permalink rewrites that include hash in URI" on WordPress Answers.
Plugin URL: http://wordpress.stackexchange.com/questions/12762/custom-post-type-no-need-for-single-view-plus-want-permalink-rewrites-that-incl
*/
if (!class_exists('FAQ_Post_Type')) {
  class FAQ_Post_Type {
    static function on_load() {
      add_action('post_type_link', array(__CLASS__,'post_type_link'),10,2);
      add_action('init', array(__CLASS__,'init'));
    }
    static function post_type_link($link,$post) {
      if ('faq'==$post->post_type) {
        $link = get_post_type_archive_link('faq') ."#{$post->post_name}";
      }
      return $link;
    }
    static function init() {
      register_post_type('faq',array(
          'labels' => array(
          'name' => _x('FAQs', 'post type general name'),
          'singular_name' => _x('FAQ', 'post type singular name'),
          'add_new' => _x('Add New', 'faq'),
          'add_new_item' => __('Add New FAQ'),
          'edit_item' => __('Edit FAQ'),
          'new_item' => __('New FAQ'),
          'view_item' => __('View FAQ'),
          'search_items' => __('Search FAQs'),
          'not_found' =>  __('No FAQs found'),
          'not_found_in_trash' => __('No FAQs found in Trash'),
          'parent_item_colon' => '',
          'menu_name' => 'FAQs'
        ),
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'query_var' => true,
        'rewrite' => array('slug'=>'faqs'),
        'capability_type' => 'post',
        'has_archive' => 'faqs',
        'hierarchical' => false,
        'supports' => array('title','editor','author','thumbnail','excerpt'),
      ));
      global $wp_rewrite;
      unset($wp_rewrite->extra_permastructs['faq']);  // Remove URL rewrite for specific FAQ
    }
    static function activate() {
      global $wp_rewrite;
      $wp_rewrite->flush_rules();
    }
  }
  FAQ_Post_Type::on_load();
  register_activation_hook(__FILE__,array('FAQ_Post_Type','activate'));
}

Вы также можете сохранить правила сброса внутри 'init', используя проверку значения параметра, если вы предпочитаете это:

// Add this code in your 'init' hook at your register_post_type('faq',...)
if (!get_option('faq_rewrite_rules_updated')) {
  global $wp_rewrite;
  unset($wp_rewrite->extra_permastructs['faq']);  // Remove URL rewrite for specific FAQ
  $wp_rewrite->flush_rules();
  update_option('faq_rewrite_rules_updated',true);
}

Твой выбор.

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

MikeSchinkel
источник
Привет @MikeSchinkel. ВОТ ЭТО ДА! Вы, безусловно, полезный человек. Я от всего сердца согласен с вашими пунктами пересмотра № 1 и № 2, но я считаю, что мы в основном решили эти проблемы. Для # 1 - так как мы показываем полный вопрос и ответ на странице архива cpt, разве одно представление для каждого часто задаваемого вопроса не будет дублированным контентом и, следовательно, не обязательно благоприятным для SEO? В дополнение к этому, мы почувствовали, что целая страница только для одного часто задаваемого вопроса - это немного хлопотно, и мы бы предпочли быстрее доставлять контент пользователям, а не кликать по большему количеству ссылок, чтобы попасть туда.
daxitude
(очевидно, есть ограничения символов для комментариев, и я многословный человек!) Для # 2 - все после хэша в URI соответствует div на странице, которая содержит ответ. все остальные ответы скрываются при загрузке страницы, и соответствующие ответы открываются. Таким образом, мы полностью сохраняем возможность обмениваться и сохранять ссылки ... до тех пор, пока мы не изменяем и не меняем эту структуру по какой-то глупой причине.
daxitude
Что касается вашего ответа, шаг 1 является фантастическим! Ранее я не был знаком с этим крючком и не ожидал такого аккуратного решения. Любопытно, что я понимаю, что вы можете реализовать шаг 1, а не шаг 2. Это отправляет faq-ссылки на соответствующие uri, но также сохраняет отдельные страницы ... и мы просто никогда не ссылаемся на них через сайт. Это похоже на разумный путь? Спасибо.
daxitude
@daxitude - лучше запретить индексацию поисковыми системами на странице архива и разрешить им индексировать отдельные страницы. Две наиболее важные вещи для SEO - это страницы, <title>и <h1>Heading</h1>вы получите только одну из них на странице архива, но вы получите одну для каждой страницы часто задаваемых вопросов. Я согласен с тем, что весь контент FAQ лучше всего подходит на странице архива, но вы можете предоставить весь контент на главной странице и странице детализации для тех, кто этого хочет (включая поисковые системы) , и это, безусловно, ничего не повредит; Просто добавьте «Постоянная ссылка» рядом с часто задаваемыми вопросами.
MikeSchinkel
@daxitude - Как вы думаете, почему я не реализовал # 2? Это цель кода, который следует за заголовком «2.) unset($wp_rewrite->extra_permastructs['faq'])», который, конечно, я утверждаю, что вы не используете. :)
MikeSchinkel