自定义帖子类型每年/每月存档
Posted
技术标签:
【中文标题】自定义帖子类型每年/每月存档【英文标题】:Custom post type yearly/ monthly archive 【发布时间】:2013-01-07 08:24:07 【问题描述】:我的 Wordpress 网站中有一个自定义帖子类型“新闻”。我正在使用 Advanced Custom Fields 插件为每个帖子添加元数据。
我想创建一个新闻项目数组作为存档:
[2013]
[January] => 5
[2012]
[January] => 20
[February] => 10
[2011]
[April] => 30
我设法使用:
global $wpdb;
$news = $wpdb->get_results(
"SELECT wp_posts.post_date, COUNT(wp_posts.ID) as count
FROM $wpdb->posts
WHERE
wp_posts.post_type = 'news' AND
wp_posts.post_status = 'publish' AND
wp_posts.post_date <= CURDATE() AND
wp_posts.post_date >= DATE_SUB(CURDATE(), INTERVAL 3 YEAR)
GROUP BY YEAR(wp_posts.post_date), MONTH(wp_posts.post_date)
ORDER BY wp_posts.post_date DESC",
ARRAY_A);
$archive = array();
foreach ($news as $post):
$year = date('Y', strtotime($post['post_date']));
$month = date('m', strtotime($post['post_date']));
$month_name = date('F', strtotime($post['post_date']));
$post['url'] = 'NOT SURE ABOUT URL';
$archive[$year][$month_name] = $post;
endforeach;
我需要能够使用http://example.com/2012/
和http://example.com/2012/10/
链接到特定的年份和月份。
由于这涉及自定义帖子类型“新闻”,我不确定如何做到这一点?
【问题讨论】:
我还应该提到,当我尝试浏览到:http://example.com/index.php?post_type=news&year=2012
时,我会被重定向到 http://example.com/news
您可能还想在这里尝试:wordpress.stackexchange.com
【参考方案1】:
为了满足您的要求,您需要修改 Wordpress 重写,以便能够捕获自定义帖子类型的年/月/等帖子数据。
你可以用下面的代码做到这一点:
/**
* Custom post type date archives
*/
/**
* Custom post type specific rewrite rules
* @return wp_rewrite Rewrite rules handled by Wordpress
*/
function cpt_rewrite_rules($wp_rewrite)
$rules = cpt_generate_date_archives('news', $wp_rewrite);
$wp_rewrite->rules = $rules + $wp_rewrite->rules;
return $wp_rewrite;
add_action('generate_rewrite_rules', 'cpt_rewrite_rules');
/**
* Generate date archive rewrite rules for a given custom post type
* @param string $cpt slug of the custom post type
* @return rules returns a set of rewrite rules for Wordpress to handle
*/
function cpt_generate_date_archives($cpt, $wp_rewrite)
$rules = array();
$post_type = get_post_type_object($cpt);
$slug_archive = $post_type->has_archive;
if ($slug_archive === false) return $rules;
if ($slug_archive === true)
$slug_archive = $post_type->name;
$dates = array(
array(
'rule' => "([0-9]4)/([0-9]1,2)/([0-9]1,2)",
'vars' => array('year', 'monthnum', 'day')),
array(
'rule' => "([0-9]4)/([0-9]1,2)",
'vars' => array('year', 'monthnum')),
array(
'rule' => "([0-9]4)",
'vars' => array('year'))
);
foreach ($dates as $data)
$query = 'index.php?post_type='.$cpt;
$rule = $slug_archive.'/'.$data['rule'];
$i = 1;
foreach ($data['vars'] as $var)
$query.= '&'.$var.'='.$wp_rewrite->preg_index($i);
$i++;
$rules[$rule."/?$"] = $query;
$rules[$rule."/feed/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
$rules[$rule."/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
$rules[$rule."/page/([0-9]1,)/?$"] = $query."&paged=".$wp_rewrite->preg_index($i);
return $rules;
您会注意到我已将news
硬编码到代码的$rules = cpt_generate_date_archives('news', $wp_rewrite);
部分。您可以根据需要进行更改。
使用此代码,您应该能够导航到 http://yoursite.com/news/2013/02/ 并接收该特定帖子类型在特定时间的存档列表。
为了完整起见,我将介绍如何生成每月存档小部件以便使用它。
/**
* Get a montlhy archive list for a custom post type
* @param string $cpt Slug of the custom post type
* @param boolean $echo Whether to echo the output
* @return array Return the output as an array to be parsed on the template level
*/
function get_cpt_archives( $cpt, $echo = false )
global $wpdb;
$sql = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_type = %s AND post_status = 'publish' GROUP BY YEAR($wpdb->posts.post_date), MONTH($wpdb->posts.post_date) ORDER BY $wpdb->posts.post_date DESC", $cpt);
$results = $wpdb->get_results($sql);
if ( $results )
$archive = array();
foreach ($results as $r)
$year = date('Y', strtotime( $r->post_date ) );
$month = date('F', strtotime( $r->post_date ) );
$month_num = date('m', strtotime( $r->post_date ) );
$link = get_bloginfo('siteurl') . '/' . $cpt . '/' . $year . '/' . $month_num;
$this_archive = array( 'month' => $month, 'year' => $year, 'link' => $link );
array_push( $archive, $this_archive );
if( !$echo )
return $archive;
foreach( $archive as $a )
echo '<li><a href="' . $a['link'] . '">' . $a['month'] . ' ' . $a['year'] . '</a></li>';
return false;
要使用此功能,只需提供自定义帖子类型的 slug,即:get_cpt_archives( 'news' )
。这将返回一个唯一的年份/日期/链接数组,即:
Array
(
[0] => Array
(
[month] => February
[year] => 2013
[link] => http://yoursite.com/news/2013/02
)
[1] => Array
(
[month] => January
[year] => 2013
[link] => http://yoursite.com/news/2013/01
)
)
您可以使用foreach
循环遍历这些内容,然后根据需要输出它们。
或者,您可以使用get_cpt_archives( 'news', true )
,它会自动回显包装在<li>
中的每个项目,链接到其特定存档。
输出的格式不是你想要的,所以你必须稍微调整一下才能让它显示在
Year
Month
Month
Year
Month
您需要的格式。
我希望这会有所帮助。
【讨论】:
第一次没用。你可能必须去Settings->Permalinks
,选择自定义并保存。然后将其设置回上一个并再次保存。有人说存钱就够了,对我来说不行。
非常感谢您提供这些功能。它工作得很好!我在网上找到了这个问题的最佳答案。
目前,对我来说它不起作用。有兴趣的朋友,我刚刚开了一个专门的帖子:***.com/questions/39589697/…
@Stratboy 如果我发布的解决方案适合你,你试过了吗?
完美。非常感谢。【参考方案2】:
我知道这是一篇旧帖子,但有一种更简洁的方法可以满足 OP 的要求:
function cpt_add_rewrite_rules()
$cpt = 'news';
add_rewrite_rule($cpt.'/([0-9]4)/([0-9]1,2)/([0-9]1,2)?$',
'index.php?post_type='.$cpt.'&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]',
'top');
add_rewrite_rule($cpt.'/([0-9]4)/([0-9]1,2)?$',
'index.php?post_type='.$cpt.'&year=$matches[1]&monthnum=$matches[2]',
'top');
add_rewrite_rule($cpt.'/([0-9]4)?$',
'index.php?post_type='.$cpt.'&year=$matches[1]',
'top');
add_filter('init', 'cpt_add_rewrite_rules');
【讨论】:
以上是关于自定义帖子类型每年/每月存档的主要内容,如果未能解决你的问题,请参考以下文章
获取自定义帖子类型(Wordpress)的每年帖子数量的数组