自定义帖子类型的日期档案

时间:2014-04-30 作者:wickywills

我已经看到了很多关于这方面的问题/帖子,但还没有找到一个像样的解决方案。基本上我想做什么wp_get_archives 是的,但对于自定义的帖子类型(我个人不知道为什么wp_get_archives 不支持自定义帖子类型!)。

我目前使用的代码如下

functions.php

function Cpt_getarchives_where_filter( $where , $r ) {
  $post_type = \'events\';
  return str_replace( "post_type = \'post\'" , "post_type = \'$post_type\'" , $where );
}

sidebar-events.php

add_filter( \'getarchives_where\' , \'Cpt_getarchives_where_filter\' , 10 , 2 );
wp_get_archives();
remove_filter(\'getarchives_where\' , \'Cpt_getarchives_where_filter\' , 10 );
此代码显示日期(例如2014年4月、2014年3月)等,这很好,但单击链接只会转到404。在每个日期链接上创建的URL是/2014/04/,但它应该类似于/events/2014/04/。

有没有办法在URL中包含“事件”,以便归档事件。php模板可以使用,有什么原因导致链接当前生成404?

非常感谢您的帮助

2 个回复
最合适的回答,由SO网友:gmazzap 整理而成

还可以进行筛选\'month_link\' 对于月度档案,\'year_link\' 用于年度档案和\'day_link\' 用于日常存档。

您还可以编写一个扩展wp_get_archives 要使用CPT,请将筛选器添加到\'getarchives_where\' 和存档链接。

function wp_get_cpt_archives( $cpt = \'post\', $args = array() ) {
  // if cpt is post run the core get archives
  if ( $cpt === \'post\' ) return wp_get_archives($args); 
  // if cpt doesn\'t exists return error
  if ( ! post_type_exists($cpt) ) return new WP_Error(\'invalid-post-type\');
  $pto = get_post_type_object($cpt);
  // if cpt doesn\'t have archive return error
  if ( ! $pto = get_post_type_object( $cpt ) ) return false;
  $types = array(\'monthly\' => \'month\', \'daily\' => \'day\', \'yearly\' => \'year\');
  $type = isset( $args[\'type\'] ) ?  $args[\'type\'] : \'monthly\';
  if ( ! array_key_exists($type, $types) ) {
    // supporting only \'monthly\', \'daily\' and \'yearly\' archives
     return FALSE;
  }
  $done_where = $done_link = FALSE;
  // filter where
  add_filter( \'getarchives_where\' , function( $where ) use (&$done_where, $cpt) {
    if ( $done_where ) return $where;
    return str_replace( "post_type = \'post\'" , "post_type = \'{$cpt}\'" , $where );
  });
  // filter link
  add_filter( "{$types[$type]}_link", function( $url ) use (&$done_link, $pto, $cpt) {
    if ( $done_link ) return $url;
     // if no pretty permalink add post_type url var
     // if ( get_option( \'permalink_structure\' ) || ! $pto->rewrite ) {
     if ( ! get_option( \'permalink_structure\' ) || ! $pto->rewrite ) {
       return add_query_arg( array( \'post_type\' => $cpt ), $url );
     } else { // pretty permalink
       global $wp_rewrite;
       $slug = is_array( $pto->rewrite ) ? $pto->rewrite[\'slug\'] : $cpt;
       $base = $pto->rewrite[\'with_front\'] ? $wp_rewrite->front : $wp_rewrite->root;
       $home = untrailingslashit( home_url( $base ) );
       return str_replace( $home,  home_url( $base . $slug ), $url );
     }
  });
  // get original echo arg and then set echo to false  
  $notecho = isset($args[\'echo\']) && empty($args[\'echo\']);
  $args[\'echo\'] = FALSE; 
  // get archives
  $archives = wp_get_archives($args);
  // prevent filter running again
  $done_where = $done_link = TRUE;
  // echo or return archives
  if ( $notecho ) {
    return $archives;
  } else {
    echo $archives;
  }
}
有关函数如何工作的更多信息,请阅读内联注释。

现在有一个问题。url类似/events/2014/04/not WordPress可以识别,因此您需要添加处理此类URL的reqrite规则。

同样,您可以编写一个函数来为您添加规则:

function generate_cpt_archive_rules( $cpt ) {
  if ( empty($cpt) || ! post_type_exists($cpt) ) return;
  global $wp_rewrite;
  $pto = get_post_type_object($cpt);
  if ( ! $pto->has_archive ) return;
  $base = $pto->rewrite[\'with_front\'] ? $wp_rewrite->front : $wp_rewrite->root;
  $base = trailingslashit( $base );
  $slug = is_array( $pto->rewrite ) ? $pto->rewrite[\'slug\'] : $cpt;
  $year = ltrim( $base . $slug . \'/([0-9]{4})/?$\', \'/\' );
  $month = ltrim( $base . $slug . \'/([0-9]{4})/([0-9]{2})/?$\', \'/\' );
  $day = ltrim( $base . $slug . \'/([0-9]{4})/([0-9]{2})/([0-9]{2})/?$\', \'/\' );
  $index = \'index.php?post_type=\' . $cpt;
  $rules[$year] =  $index . \'&m=$matches[1]\';
  $rules[$month] = $index . \'&m=$matches[1]$matches[2]\';
  $rules[$day] = $index . \'&m=$matches[1]$matches[2]$matches[3]\';
  $page = 2;
  foreach ( array( $year, $month, $day ) as $rule ) {
    $paged = str_replace( \'/?$\', \'/page/([0-9]{1,})/?$\', $rule);
    $rules[$paged] = $rules[$rule] . \'&paged=$matches[\' . $page . \']\';
    $page++;
  }
  return $rules;
}
此函数生成规则,但是,您还需要添加和刷新规则。

现在建议刷新主题(或插件)激活的规则并在init上注册,因此您应该执行以下操作:

function register_cpt_dates_rules() {
  $cpts = array( \'events\' );
  foreach ( $cpts as $cpt ) {
    foreach ( generate_cpt_archive_rules( $cpt ) as $rule => $rewrite ) {
      add_rewrite_rule( $rule, $rewrite, \'top\' );
    }
  }
}
// flushing on theme switch
add_action(\'after_switch_theme\', function() {
  register_cpt_dates_rules();
  $GLOBALS[\'wp_rewrite\']->flush_rules();
});
// registering on init
add_action( \'init\', \'register_cpt_dates_rules\' );
将这些函数添加到functions.php (您已停用并再次激活您的主题\'after_switch_theme\' 运行)您可以使用以下方式显示存档:

wp_get_cpt_archives( \'events\' );
它将显示事件CPT的档案,链接将是/events/2014/04/.

它还适用于年度或每日存档:

wp_get_cpt_archives( \'events\', array( \'type\'=>\'yearly\' ) );
wp_get_cpt_archives( \'events\', array( \'type\'=>\'daily\' ) );
使用我的两个函数,您可以非常轻松地wp_get_archives 与CPT配合使用。

请注意all 这里的代码需要PHP 5.3+。

SO网友:Eric Holmes

我想通用汽车已经给了你所需要的一切。我写了一个blog post 关于CPT日期档案的permalink生成,但还没有时间获取另一个pre_get_posts 它的一部分在博客文章的形式尚未。

基本上有三块拼图:

生成重写规则以读取/2014/04/30, /2014/, 等等。日期字符串

结束

相关推荐

Php conditional help needed

我正在尝试添加作者身份的条件,以便在特定的作者id上显示帖子。如果有人能快速查看以下内容,我将不胜感激<?php if is_author (\'2\') AND ( is_single() ) {?> <link rel=\"author\" href=\"https://plus.google.com/**********\"/> <?php }?>