虽说 Web 已经日薄西山,流量式微,但作为自己的一亩三分地偶尔看看还是不错的。于是这几日疯狂折腾现用的主题,包括代码修改及功能补齐,本文分享两个免插件实现 WordPress 文章归档页面的方法。
1. 利用 WordPress 原生函数实现文章归档
此方式和代码来自国内知名博主@Zwwooooo,是一个经典的、简单的、广为流传的方式,我本人之前就用过,记录此处只是怕以后找不到代码。具体效果可以参考我的文章归档页面。
1.1 文章归档主程序
将这段代码放进主题的function.php
循环中,请注意因为有部分中文字符,所以你的代码格式必须为UTF-8
。此程序会在 WordPress 数据库中创建一个归档页面的索引表,为了减小服务器压力,本程序的索引仅在文章发生更改后才重建。Kevin's 基于原始代码添加了访问统计,需要在你的程序中安装WP-PostViews插件配合实用。
//文章归档页面 | 基于 zwwooooo(https://zww.me)增加文章访问量,Kevin's BLOG(www.shephe.com)
function zww_archives_list() {
if( !$output = get_option('zww_db_cache_archives_list') ){
$output = '<div id="archives"><p><a id="al_expand_collapse" href="#">全部展开 / 收缩</a> <em>(注: 点击月份可以展开)</em></p>';
$args = array(
'post_type' => array('archives', 'post', 'zsay'),
'posts_per_page' => -1, //全部 posts
'ignore_sticky_posts' => 1 //忽略 sticky posts
);
$the_query = new WP_Query( $args );
$posts_rebuild = array();
$year = $mon = 0;
while ( $the_query->have_posts() ) : $the_query->the_post();
$post_year = get_the_time('Y');
$post_mon = get_the_time('m');
$post_day = get_the_time('d');
if ($year != $post_year) $year = $post_year;
if ($mon != $post_mon) $mon = $post_mon;
$views = function_exists('the_views') ? intval(get_post_meta(get_the_ID(), 'views', true)) : 0; // Get post views using WP-PostViews plugin
$posts_rebuild[$year][$mon][] = '<li>'. get_the_time('d 日: ') .'<a target="_blank" href="'. get_permalink() .'">'. get_the_title() .'</a> <em>('. get_comments_number('0', '1', '%') .'条评论, '.$views.'次浏览)</em></li>';
endwhile;
wp_reset_postdata();
foreach ($posts_rebuild as $key_y => $y) {
$y_i = 0; $y_output = '';
foreach ($y as $key_m => $m) {
$posts = ''; $i = 0;
foreach ($m as $p) {
++$i; ++$y_i;
$posts .= $p;
}
$y_output .= '<li><span class="al_mon">'. $key_m .' 月 <em>( '. $i .' 篇文章 )</em></span><ul class="al_post_list">'; //输出月份
$y_output .= $posts; //输出 posts
$y_output .= '</ul></li>';
}
$output .= '<h3 class="al_year">'. $key_y .' 年 <em>( '. $y_i .' 篇文章 )</em></h3><ul class="al_mon_list">'; //输出年份
$output .= $y_output;
$output .= '</ul>';
}
$output .= '</div>';
update_option('zww_db_cache_archives_list', $output);
}
echo $output;
}
function clear_db_cache_archives_list() {
update_option('zww_db_cache_archives_list', ''); // 清空 zww_archives_list
}
add_action('save_post', 'clear_db_cache_archives_list'); // 新发表文章/修改文章时
1.2 创建一个独立的文章归档页面
在你的主题根目录或者类似 page-templates 这样的文件夹里边找一个 page 模板,复制一份并给予其一个新的文件名,将其头部修改成类似如下样式:
<?php
/*
Template Name: Archives Page
*
* @version 1.0
* @author 牧羊人
* @URI https://www.shephe.com/
*/
然后找到此文件的正文处,将归档页面主程序function zww_archives_list()
加进去后保存,比如:
<div id="grve-content" <?php impeka_grve_content_class(); ?>>
<div class="grve-content-wrapper">
<div id="grve-main-content">
<div class="grve-main-content-wrapper clearfix">
<div id="page-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php the_content(); ?>
<?php zww_archives_list(); ?>
<?php wp_link_pages(); ?>
</div>
</div>
</div>
<?php get_sidebar(); ?>
</div>
</div>
最后在 WordPress 后台新建独立页面,模板选择为刚才建好的Archives Page
。
1.3 Javascript 脚本和样式表
将如下 js 代码添加加载在 jQuery 库后面,比如你可以简单粗暴的直接把它放在footer.php
中。其中的(s-10<1)?0:s-10
用来控制收缩的时间,可以更改成s
试试,据说效果会更好。至此你的文章归档页面已经初见成效,如果要把它弄好看一些,可能就需要更改部分 css 代码了,此处不表。
<script type="text/javascript">
(function ($, window) {
$(function() {
var $a = $('#archives'),
$m = $('.al_mon', $a),
$l = $('.al_post_list', $a),
$l_f = $('.al_post_list:first', $a);
$l.hide();
$l_f.show();
$m.css('cursor', 's-resize').on('click', function(){
$(this).next().slideToggle(400);
});
var animate = function(index, status, s) {
if (index > $l.length) {
return;
}
if (status == 'up') {
$l.eq(index).slideUp(s, function() {
animate(index+1, status, (s-10<1)?0:s-10);
});
} else {
$l.eq(index).slideDown(s, function() {
animate(index+1, status, (s-10<1)?0:s-10);
});
}
};
$('#al_expand_collapse').on('click', function(e){
e.preventDefault();
if ( $(this).data('s') ) {
$(this).data('s', '');
animate(0, 'up', 100);
} else {
$(this).data('s', 1);
animate(0, 'down', 100);
}
});
});
})(jQuery, window);
</script>
/*! https://www.shephe.com/archives/ 实用的样式表
#archives{position:relative}#archives h3{margin-bottom:0;padding:0 15px;border-bottom:1px solid #ddd;font-weight:400;text-align:center;letter-spacing:5px}#archives ul{list-style:none;margin:0 30px;padding:10px 0 20px 10px;border-left:1px solid #ddd}#archives li{list-style:none;position:relative;line-height:30px}#archives ul ul{margin:-15px 0 0;padding:15px 0 10px}#archives ul ul li{padding:0 0 0 15px}#archives ul ul li:before{content:"";position:absolute;left:0;top:10px;border-top:5px dashed transparent;border-bottom:5px dashed transparent;border-left:10px solid #ddd}#al_expand_collapse{display:inline-block;line-height:24px;padding:0 10px;color:#fff;font-size:14px;text-decoration:none;background:linear-gradient(180deg,#c33 20%,rgba(204,51,51,.82) 80%) repeat scroll 0 0 transparent;background:-webkit-linear-gradient(180deg,#c33 20%,rgba(204,51,51,.82) 80%) repeat scroll 0 0 transparent}#al_expand_collapse:hover{background:linear-gradient(180deg,rgba(204,51,51,.76) 20%,rgba(204,51,51,.7) 80%) repeat scroll 0 0 transparent;background:-webkit-linear-gradient(180deg,#c33 20%,rgba(204,51,51,.49) 80%) repeat scroll 0 0 transparent}#archives em{padding-left:5px;font-size:12px;color:#777}#archives .al_mon{padding-left:5px;font-size:14px;font-weight:700}#archives .al_mon:after{content:"";position:absolute;left:-10px;top:15px;width:10px;height:1px;background:#ddd}#archives .al_mon em{font-size:12px;font-weight:400}
.archives-meta{
line-height:24px;
font-size:15px;
font-style:italic;
text-align:center;
margin:10px;
}
2. 时间轴样式的 WordPress 文章归档页面
这第二种方式其实更适用完全不会的新手小白,原作者@西部盒子将 WordPress 归档页面所需的完整代码集成在了一个文件中,并且可以作为插件适用,简单方便。真实效果查看这个页面:
这个程序可以实现按时间自动调用文章显示成时间轴效果,且支持按分页显示,也可按需排除特定分类。使用方式可以是将代码加入 function.php 中或者作为插件安装,插件按此下载后在后台去上传安装即可,代码如下:
<?php
/**
* Plugin Name: Wbox 时间轴文章归档
* Author: 西部盒子
* Author URI: http://blog.wbox8.com
* Version: 1.2
* Plugin URI: http://wbox.taobao.com
* Description: 新建页面添加简码 <code>[wboxtimeline]</code>
*/
add_shortcode('wboxtimeline', 'wboxtimeline');
function wboxtimeline() {
$css = get_option('wb_time_line_css');
$html = <<<wbox
<style>
.wbcss-archive {
position: relative;
font-size: 14px;
color: rgba(0, 0, 0, 0.6);
}
.wbcss-archive:before {
content: "";
width: 3px;
background-color: rgba(0, 0, 0, 0.05);
position: absolute;
top: 0;
bottom: 0;
left: 100px;
}
.wbcss-archive h3{
border:0 !important;
}
h3.archive-year {
display: inline-block;
background-color: #fafafa;
border: 1px solid rgba(0, 0, 0, 0.05);
color: rgba(0, 0, 0, 0.44);
padding: 1px 0;
width: 120px;
margin-left: 40px;
text-align: center;
postion: relative;
border-radius: 3px;
margin-top: 30px;
margin-bottom: 10px;
position: relative;
}
h3.archive-month {
position: relative;
font-weight: 700;
margin:0 0 15px;
padding:0;
font-size: 16px;
line-height: 25px;
color: #999;
}
.archive-month:before,
.archive-month:after {
content: "";
background-color: #fff;
height: 19px;
width: 19px;
border-radius: 100%;
position: absolute;
left: 92px;
top: 3px;
}
.archive-month:after {
height: 15px;
width: 15px;
background-color: #eee;
left: 94px;
top: 5px;
}
.archive-month:hover:after {
background-color: #ec8c35;
}
.wbcss-ul {
margin:0 0 30px 100px !important;
margin-left: 100px !important;
margin-bottom: 30px !important;
}
.wbcss-ul .date {
margin-left: -80px;
width: 80px;
display: inline-block;
}
.wbcss-ul li {
margin:0 !important;
position: relative;
padding-left: 15px;
list-style: none !important;
}
.wbcss-ul li:before,
.wbcss-ul li:after {
content: "";
background-color: #fff;
height: 13px;
width: 13px;
border-radius: 100%;
position: absolute;
left: -5px;
top: 7px;
}
.wbcss-ul li:after {
height: 9px;
width: 9px;
background-color: #eee;
left: -3px;
top: 9px;
}
.wbcss-ul li:hover:after {
background-color: #ec8c35;
}
.wb-paged{
margin: 0;
padding: 0;
text-align: center;
}
.wb-paged a{
display: inline-block;
margin: 0 5px;
font-size: 14px;
color: #555;
line-height: 20px;
padding: 3px 10px;
background: #fff;
border: 1px #ddd solid;
}
.wb-paged a:hover{
background: #eee;
}
.wb-paged span{
display: inline-block;
margin: 0 5px;
font-size: 14px;
line-height: 20px;
color: #555;
padding: 0px;
}
{$css}
</style>
wbox;
$html .= '<div class="wbcss-archive">';
$paged = get_query_var('paged');
$args = array(
'post_type' => 'post',
'posts_per_page' => get_option('wb_time_line_showposts', 20),
'ignore_sticky_posts' => 1,
'category__not_in' => explode(',', get_option('wb_time_line_category_notin')),
'paged' => $paged ? $paged : 1,
);
$the_query = new WP_Query($args);
$posts_rebuild = array();
while ($the_query->have_posts()): $the_query->the_post();
$post_year = get_the_time('Y');
$post_mon = get_the_time('m');
$posts_rebuild[$post_year][$post_mon][] = '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a> <em>(' . get_comments_number('0', '1', '%') . ')</em></li>';
endwhile;
wp_reset_postdata();
foreach ($posts_rebuild as $key => $value) {
$output .= '<h3 class="archive-year">' . $key . '</h3>';
$year = $key;
foreach ($value as $key_m => $value_m) {
$output .= '<h3 class="archive-month">' . $year . ' - ' . $key_m . '</h3><ul class="wbcss-ul">';
foreach ($value_m as $key => $value_d) {
$output .= $value_d;
}
$output .= '</ul>';
}
}
$html .= $output;
$html .= '</div>';
$html .= wbox_paged_nav($the_query, $paged, 2);
return wbox_compress_html($html);
}
function wbox_paged_nav($query, $paged, $p = 2) {
$html = '';
$max_page = $query->max_num_pages;
if ($max_page > 1) {
if (empty($paged)) {
$paged = 1;
}
$html .= '<div class="wb-paged">';
if ($paged > $p + 1) {
$html .= wboxp_link(1, '最前页', '«');
}
if ($paged > 1) {
$html .= wboxp_link($paged - 1, '上一页', '‹');
}
if ($paged > $p + 2) {
$html .= '... ';
}
for ($i = $paged - $p; $i <= $paged + $p; $i++) {
if ($i > 0 && $i <= $max_page) {
if ($i == $paged) {
$html .= "<span class='page-numbers current'>{$i}</span>";
} else {
$html .= wboxp_link($i);
}
}
}
if ($paged < $max_page - $p - 1) {
$html .= '<span class="page-numbers">...</span>';
}
if ($paged < $max_page) {
$html .= wboxp_link($paged + 1, '下一页', '›');
}
if ($paged < $max_page - $p) {
$html .= wboxp_link($max_page, '最后页', '»');
}
$html .= '</div>';
}
return $html;
}
function wboxp_link($i, $title = '', $linktype = '') {
if ($title == '') {
$title = "第 {$i} 页";
}
if ($linktype == '') {
$linktext = $i;
} else {
$linktext = $linktype;
}
return "<a class='page-numbers' href='" . esc_html(get_pagenum_link($i)) . "' title='{$title}'>{$linktext}</a> ";
}
function wbox_compress_html($string) {
$string = str_replace("\r\n", '', $string); //清除换行符
$string = str_replace("\n", '', $string); //清除换行符
$string = str_replace("\t", '', $string); //清除制表符
$pattern = array(
"/> *([^ ]*) *</", //去掉注释标记
"/[\s]+/",
"/<!--[^!]*-->/",
"/\" /",
"/ \"/",
"'/\*[^*]*\*/'",
);
$replace = array(
">\\1<",
" ",
"",
"\"",
"\"",
"",
);
return preg_replace($pattern, $replace, $string);
}
//后台设置页面
function wbox_time_line_add_menu() {
add_menu_page('时间轴设置 - BY 西部盒子', '时间轴设置', 'edit_themes', 'wbox_time_line_setings', 'wbox_time_line_display_function', '', 999);
}
add_action('admin_menu', 'wbox_time_line_add_menu');
function wbox_time_line_display_function() {
$update = false;
if ($_POST['wb_time_line_showposts']) {
update_option('wb_time_line_showposts', trim($_POST['wb_time_line_showposts']));
update_option('wb_time_line_category_notin', trim($_POST['wb_time_line_category_notin']));
update_option('wb_time_line_css', trim($_POST['wb_time_line_css']));
$update = true;
}
?>
<div class="wrap" id="profile-page">
<?php if ($update) {
echo '<div class="notice notice-info"><p>更新成功</p></div>';
}
?>
<form method="post" name="wbox_seting" id="wbox_seting">
<h2>时间轴设置</h2>
<table class="form-table">
<tbody>
<tr class="form-field">
<th scope="row"><label for="wb_time_line_showposts">每页显示条数</label></th>
<td>
<input name="wb_time_line_showposts" type="text" id="wb_time_line_showposts" value="<?php echo get_option('wb_time_line_showposts'); ?>" style="max-width: 500px;" />
<p>不设置默认显示 20 条,设置为-1 显示全部。</p>
</td>
</tr>
<tr class="form-field">
<th scope="row"><label for="wb_time_line_category_notin">要排除的分类</label></th>
<td>
<input name="wb_time_line_category_notin" type="text" id="wb_time_line_category_notin" value="<?php echo get_option('wb_time_line_category_notin'); ?>" style="max-width: 500px;" />
<p>多个分类 ID 请用英文逗号分开,请对照下面分类对照表进行设置。</p>
</td>
</tr>
<tr class="form-field">
<th scope="row"><label for="wb_time_line_css">额外的 CSS 样式</label></th>
<td>
<textarea name="wb_time_line_css" id="wb_time_line_css" rows="5" cols="30"><?php echo get_option('wb_time_line_css'); ?></textarea>
<p>自定义 CSS 区域,会在时间轴上方的 CSS 区域调用,前后不用添加 style 标签。</p>
</td>
</tr>
</tbody>
</table>
<?php submit_button('保存设置');?>
</form>
<h3>插件使用方法:</h3>
<p>新建一个页面,在内容区域输入简码: <code>[wboxtimeline]</code></p>
<h3>分类对照表:<small style="color: #e00">分类 - id</small></h3>
<style>.wb-cat{margin-right: 20px;background: #d2e9f3;padding: 5px}</style>
<p><?php
foreach (get_categories() as $cat) {
echo '<span class="wb-cat">' . $cat->cat_name . ' <code>' . $cat->cat_ID . '</code></span>';
}
?></p>
<p style="position: fixed;bottom: 20px;right: 20px;">时间轴插件由 <a href="https://blog.wbox8.com/" target="_blank">西部盒子</a> 提供</p>
</div>
<?php }
使用方式是新建个页面,将程序短代码[wboxtimeline]
扔进去,发布就行。
[…] 前段时间把WordPress 文章归档页面、网站分类、文章标签以及导航菜单等进行了优化,但目前在实际使用过程中仍觉得“分类”不够清晰。思来想去,还是觉得用“标签归档”来作为分类导航比较直观。于是 Kevin 着手创建一个新的 WordPress 标签归档页面…嗯,还是觉得原来 Tiny 主题用的标签页好看,扒下来吧。 […]