自定义帖子类型,无需单一视图,并且希望永久链接重写为在URI中包含哈希


8

我们正在使用CPT来管理网站上的常见问题页面,其中问题是帖子标题,答案是帖子内容。FAQ的主页显示了所有帖子(FAQ存档页面)。通过这种结构,我们确实不需要任何FAQ的单一视图,并且实际上希望从站点结构中忽略它。为了解决永久链接,我们希望将它们设置为例如example.com/faq/#uniqueIdentifier,认为我们将使用#uniqueIdentifier匹配包含答案的存档页面上的div,并在某些情况下引起注意时尚。uniqueIdentifier可以是帖子ID,常见问题标题,来自meta框的数据或其他内容。

因此,让我回顾一下我们需要完成的工作:

(1)将常见问题的永久链接重写为/ faq /#something,然后

(2)确保所有/ faq /链接都路由到存档模板,而不是单个

我主要是菜鸟,但擅长摸索事物。尽管从未尝试过任何重写,所以希望对此有一些特别的指导。

谢谢。

Answers:


12

@daxitude:

让我首先建议您重新考虑。如果每个常见问题解答都没有单独的常见问题解答页面:

  1. 您减少了搜索引擎优化的工作量,减少了可能获得的潜在流量,并且

  2. 您使某人无法通过电子邮件与朋友共享特定的 FAQ和/或在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'])

这是一个hack,但它是您执行所需操作所必需的hack。用'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正确完成。此插件添加带有所需URL规则的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);
}

你的选择。

无论如何,请让我知道您是否发现用例无法解决。


嗨@MikeSchinkel。哇!您当然是个乐于助人的人。我全心全意地同意你对第一点和第二点的重新考虑,但我相信我们已主要解决了这些问题。对于#1-由于我们在cpt存档页面上显示完整的问题和答案,因此每个常见问题解答的单一视图不是重复的内容,因此不一定对SEO有利吗?除此之外,我们觉得一个常见问题的整个页面有点动摇,我们宁愿为人们提供更快的内容,而不必单击更多的链接即可到达那里。
daxitude 2011年

(显然,注释的字符数限制,我是一个冗长的人!)对于#2-uri中的哈希值之后的所有内容都与包含答案的页面上的div匹配。所有其他答案都在页面加载时隐藏,并且匹配的答案幻灯片会打开。以这种方式,我们确实保留了共享和保存链接的能力……只要我们不因某些愚蠢的原因而变幻无常并更改此结构。
daxitude 2011年

关于您的答复,第一步非常好!我以前对这个钩子不熟悉,也没想到会有这么好的解决方案。出于好奇,我意识到您可以实施第1步,而不是第2步。这会将常见问题解答链接发送到相应的uri,但还会保留单个页面。我们永远不会通过站点链接到它们。这似乎是一种合理的做法吗?谢谢。
daxitude 2011年

@daxitude-最好禁止搜索引擎在存档页面上建立索引,并允许它们为各个页面建立索引。对于SEO来说,最重要的两件事是页面<title><h1>Heading</h1>只能在存档页面上找到其中之一,但是对于单个FAQ页面,您只能分别获取其中之一。我同意所有的FAQ内容在存档页面上都是最好的,但是您可以在主页上提供所有内容,想要的人(包括搜索引擎)上提供向下钻取的页面,它当然不会对您造成任何伤害;只需在FAQ问题附近添加“永久链接”
MikeSchinkel 2011年

@daxitude-为什么您认为我没有实现#2?这就是标题“ 2.)unset($wp_rewrite->extra_permastructs['faq'])之后的代码的目的,当然,我认为您不使用它。:)
MikeSchinkel 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.