问题描述

我们正在使用 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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。