問題描述

我們正在使用 CPT 來管理站點上的常見問題頁面,問題是帖子標題,答案是帖子內容。常見問題的主頁面顯示所有帖子 (FAQ 存檔頁面) 。有了這個結構,我們真的不需要任何常見問題解答的單一視圖,實際上不想從網站結構中省略它。要解決永久鏈接,我們希望將它們設置為 example.com/faq/#uniqueIdentifier,我們認為我們將使用 #uniqueIdentifier 來匹配包含答案的存檔頁面上的一個 div,並在其中注意一些時尚。 uniqueIdentifier 可以是帖子 ID,常見問題標題,來自元框的數據或其他內容。

所以讓我回顧一下我需要做的事情:

(1) 重寫 faq 固定鏈接成為/faq /#某事,以及

(2) 確保所有/faq /links 路由到歸檔模板,而不是單個

我主要是一個 noob,但很好的摸索我的方式通過事情。從來沒有嘗試任何重寫,儘管如此,將會欣賞一些特定的方向。

謝謝。

最佳解決方案

嗨 @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'鈎子中的使用是非常糟糕的做法,應該只能做一次,所以我實現了一個完整的 self-contained 插件,叫做 FAQ_Post_Type 來做正確的事情。這個插件添加了一個 FAQ 文章類型,並且使用了一個 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);
}

你的選擇。

無論如何,讓我知道,如果有 use-cases 你發現這沒有解決。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。