免插件实现 WordPress 文章归档页面

文章目录
文章目录
  1. 1. 利用 WordPress 原生函数实现文章归档
  2. 2. 时间轴样式的 WordPress 文章归档页面

虽说 Web 已经日薄西山,流量式微,但作为自己的一亩三分地偶尔看看还是不错的。于是这几日疯狂折腾现用的主题,包括代码修改及功能补齐,本文分享两个免插件实现 WordPress 文章归档页面的方法。

1. 利用 WordPress 原生函数实现文章归档

此方式和代码来自国内知名博主@Zwwooooo,是一个经典的、简单的、广为流传的方式,我本人之前就用过,记录此处只是怕以后找不到代码。具体效果可以参考我的文章归档页面

免插件实现WordPress文章归档页面
免插件实现 WordPress 文章归档页面

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 归档页面所需的完整代码集成在了一个文件中,并且可以作为插件适用,简单方便。真实效果查看这个页面

时间轴样式的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]扔进去,发布就行。

1200 600 Kevin's
「免插件实现 WordPress 文章归档页面」有 33 条评论
  • […] 前段时间把WordPress 文章归档页面、网站分类、文章标签以及导航菜单等进行了优化,但目前在实际使用过程中仍觉得“分类”不够清晰。思来想去,还是觉得用“标签归档”来作为分类导航比较直观。于是 Kevin 着手创建一个新的 WordPress 标签归档页面…嗯,还是觉得原来 Tiny 主题用的标签页好看,扒下来吧。 […]

  • semty
    04/21/2024 at 12:06 回复

    搞不定,不知道哪里问题

  • semty
    04/20/2024 at 17:39 回复

    我用的是Weisay Box v5.0.5 主题,用了第一个方案之后,点开归档页面之后,顶部会出现一条空白的横条,不知道是什么问题

    • 的头像
      Kevin
      04/20/2024 at 22:13 回复

      css的原因吧,隐藏即可

      • semty
        04/20/2024 at 22:35 回复

        怎么隐藏呢,CSS要怎么写呢

        • 的头像
          Kevin
          04/20/2024 at 22:55 回复

          这没看到我咋说。。趁我在,发链接我看看

          • semty
            04/20/2024 at 23:30 回复

            贴上网址发不出

          • semty
            04/20/2024 at 23:32 回复

            这样应该能看到网址

  • Lvtu
    04/17/2024 at 18:05 回复

    如果加个分页就完美了。。。

    • 的头像
      Kevin
      04/17/2024 at 21:04 回复

      那个功能应该是不难~

  • […] 免插件实现WordPress文章归档页面 – Kevin’s (shephe.com) […]

  • B2B海外商城系统
    09/21/2023 at 13:32 回复

    感谢分享

  • 的头像
    Jeffer.Z
    08/16/2023 at 14:21 回复

    进来感觉也没有点卡。啥情况

    • 的头像
      Kevin
      08/16/2023 at 21:22 回复

      啥意思?

      • 的头像
        Jeffer.Z
        08/17/2023 at 09:42 回复

        首页有点卡,也可能是我电脑问题吧,反正感觉滑动网页有点慢。

        • 的头像
          Kevin
          08/17/2023 at 10:16 回复

          e,可能是我的加载项太多了

  • 的头像
    obaby
    08/06/2023 at 22:53 回复

    这个效果不错~~

  • 如是乎
    07/31/2023 at 22:56 回复

    又是代码,看不懂,赞一个

  • Dr.Drunker
    07/29/2023 at 23:25 回复

    新主题不错啊!代码我mark一下,有空试试。

    • 的头像
      Kevin
      08/19/2023 at 21:47 回复

      比较经典,之所以经典也是因为简单易操作啊哈哈哈

  • wu先生
    07/25/2023 at 22:07 回复

    折腾代码挺麻烦啊,还是插件舒服一些。

  • Lvtu
    07/17/2023 at 11:35 回复

    我之前用的和你一样的样式,但有个问题就是不能分页。。。

    • 的头像
      Kevin
      07/17/2023 at 14:01 回复

      第二个代码可以分页的。

  • 子痕
    07/08/2023 at 14:50 回复

    主题不错哟,耳目一新。
    这个先收藏,等想动手的时候在去折腾。

  • 2broear
    07/08/2023 at 13:09 回复

    赞?~

  • 网友小宋
    07/06/2023 at 17:24 回复

    我那个是typecho的归档,不过和wordpress差不多。

    • Mr.Chou
      07/07/2023 at 08:50 回复

      是的,大致意思差不多~我的也是纯代码实现。

  • S̆̈
    07/06/2023 at 13:09 回复

    不错。我也是用的这些。

    • 的头像
      Kevin
      08/19/2023 at 21:49 回复

      正所谓 英雄所见略同啊~

      • S̆̈
        08/19/2023 at 22:04 回复

        说到所见略同,qiniu的头像缓存五年没更新了,要不要换成cravatar?

        • 的头像
          Kevin
          08/19/2023 at 22:28 回复

          主打的就是一个怀旧,据说 cravatar 的分辨率低图像模糊?我试试看先

发表评论

请输入关键词…