WordPress 归档页面模板[WP原生函数实现2014版]

» 2014-10-28 WordPress 98条评论

月更成就 Get…… 开博到现在算是最长的一次更新间隔了,人一忙就没时间去折腾,没去折腾就没什么可写,吃喝拉撒的事没习惯写,所以这次终于破纪录了。

这两天稍微空闲点,看到博客草已人高,所以就找找以前有没有没解决的来访朋友评论提到的问题。然后想起我 2012 年写的《代码实现WordPress归档页面模板[WP原生函数篇]》,按照这篇文档折腾的朋友大部分都成功了,但是总是有部分朋友说出现文章排列不对或者文章不全什么的,因为觉得大部分朋友都能成功,所以就一直没去分析。

今天分析了一下,应该是有些月份如果 0 篇文章就会出现问题,这是判断代码没写好的原因,于是自己想了一下,就重写了一个。现已应用到我博客的存档页面:https://zww.me/archives,截个图吧

141028-archives-page-template-2014

简单说下步骤,也可以参考前面提及 2012 年的文章。

1. 归档函数

下面代码放到主题文件 functions.php 里面,另外注意代码里面有中文,所以要把 functions.php 文件编码改为 UTF8 无 BOM 格式

/* Archives list v2014 by zwwooooo | https://zww.me */
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' => 'post', //如果你有多个 post type,可以这样 array('post', 'product', 'news')  
			'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;
			$posts_rebuild[$year][$mon][] = '<li>'. get_the_time('d日: ') .'<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_y => $y) {
			$output .= '<h3 class="al_year">'. $key_y .' 年</h3><ul class="al_mon_list">'; //输出年份
			foreach ($y as $key_m => $m) {
				$posts = ''; $i = 0;
				foreach ($m as $p) {
					++$i;
					$posts .= $p;
				}
				$output .= '<li><span class="al_mon">'. $key_m .' 月 <em> ( '. $i .' 篇文章 )</em></span><ul class="al_post_list">'; //输出月份
				$output .= $posts; //输出 posts
				$output .= '</ul></li>';
			}
			$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'); // 新发表文章/修改文章时

PS: 因为查询度有点大,所以有加数据库缓存,只在文章发表/修改时才会更新缓存数据,所以测试时,可以特意去后台点“快速编辑”文章然后点更新就可以更新缓存数据。

2016.12.07 新增“年份后面显示此年份文章数”版本:

/* Archives list v2014 by zwwooooo | https://zww.me */
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;
			$posts_rebuild[$year][$mon][] = '<li>'. get_the_time('d日: ') .'<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_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'); // 新发表文章/修改文章时

2. 复制一份主题的 page.php 更名为 archives.php,然后在最顶端加入:

<?php
/*
Template Name: Archives
*/
?>

在 archives.php 找到类似 <?php content(); ?>,在其下面加入如下代码

<?php zww_archives_list(); ?>

然后新建页面(如叫:归档),选择模版为 Archives

3. 给主题加载 jQuery 库,没有加载的,把下面这句扔到 functions.php 里面就行了。

wp_enqueue_script('jquery');

4. jQuery 代码:

这次玩了逐个下拉/收缩效果,想着很好,但我博客感觉效果一般,因为文章太多了...如果文章不多,可以把代码里面 2 个 (s-10<1)?0:s-10 改为 s,效果会好看点。

(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);

PS:不知道怎么写 js 文件然后调用的朋友就直接打开 header.php 并找到 <?php wp_head(); ?>,在其下面加上

<script type="text/javascript">上面那段 jQuery 代码</script>

因为是放在主题的 the_content() 下面,所以会默认使用主题写好的 h3 ul li 格式,如果要更加有特色,那么就要自己去修改 css 了


发现自己好久没玩 PC 游戏了,机器配置是个问题,空闲时间不多也是个问题,新游戏要花很多时间研究也是个问题,突然感觉学生时代多好啊……

zww
or
oooo

“WordPress 归档页面模板[WP原生函数实现2014版]”有98条评论

  1. 大肥羊 says:

    :mrgreen: 已修改成功。

    1. zwwooooo says:

      @大肥羊
      真手快,还把样式都搬过去了

    2. 大肥羊 says:

      @zwwooooo
      因为本来就是用你以前那版本的,样式也差不多。 :mrgreen: :mrgreen:

    3. 调皮鬼 says:

      @zwwooooo
      我还以为你也销声匿迹了,今天一看,好家伙,这篇文章太给力了。我使用的是mg12的那个插件,回头在制作新主题的时候就用你这个了,懒人有懒人的办法 :mrgreen:

      1. zwwooooo says:

        @调皮鬼
        文囧罢了……

  2. Angely says:

    这个效果好,比默认好看多了。

    1. zwwooooo says:

      @Angely
      这个没带样式的,哈。

    2. @Angely
      还可以这样插队,你有VIP卡么? :mad:

    3. Angely says:

      @不亦乐乎
      我是免检的。

      1. zwwooooo says:

        @Angely
        还是申请个头像吧……

    4. zwwooooo says:

      @不亦乐乎
      他的被审核了,因为没头像,但时间比你先。

  3. 板凳!!

    1. 大肥羊 says:

      @不亦乐乎
      变地板了,哈哈 :mrgreen:

  4. 老大,请教个问题,如果文章非常多,像你这样的,这么多数据强插到数据库options表里,会不会影响速度呢?

    1. zwwooooo says:

      @不亦乐乎
      一般没事,这点只是标题的文本不大

  5. Xiaolong says:

    主题一个比一个好看

  6. wyst says:

    如果能点击某个月份在加载这个月份下面的文章那就更好了,对于文章超过3000的人来说,打开有点慢啊。 :cry:

    1. zwwooooo says:

      @wyst
      其实是可以的,可以加 ajax 处理,有兴趣可以自己尝试下。

  7. 大发 says:

    这个就需要查询一次吧,把文章读出来然后进行的都是数组操作了。

    1. zwwooooo says:

      @大发
      对,其实不太需要再缓存,习惯性地放 option,这样也省点微不足道的资源。

  8. allan says:

    看见代码就头疼 :mrgreen:

    1. zwwooooo says:

      @allan
      研究研究就不头疼了

  9. 甜菜 says:

    哈哈,看看哦.

  10. 郑永 says:

    为什么在我那就是显示不出来呢?汗。

    1. zwwooooo says:

      @郑永
      假如如前面同学所讲,我一贴出他就折腾成功了,那么:
      1. 你主题代码问题(兼容性或者有错)
      2. 你折腾时的代码问题(包括css和jQ)
      3. RP

    2. 郑永 says:

      @zwwooooo
      你和我想的一样,也许是rp问题,往往越觉得会的,就越想不通哪里出问题了。明明就3步,可每部可能都正好吻合你说的3个原因。 :arrow:

      1. zwwooooo says:

        @郑永
        说明你对php和wp函数不熟……无法找出原因

      2. 郑永 says:

        @zwwooooo
        我对php和wp的确不熟,从头到尾真没认真去学过,今天接触到哪,就去参考一下这方面的代码,我很依赖搜索,以前折腾过得东西,稍长一点时间,转移注意力就全忘了,以至于连我自己主题有时候都感觉陌生,不想深入学习,原因也在这里,你这个function里的代码的确问题出在这里,在我脑海里,总觉得为什么这段代码在你们那里可以,我这里不可以,那么问题又似乎不是这段代码问题,难道是冲突,唯一没排查就是没有去掉functions里的所有代码试试行不行,你这么一说,我还真想自己找出原因,一会去试试。

      3. 郑永 says:

        @zwwooooo
        好吧,我再次回来了。 刚去我的demo.xptt.com试了一下,马上可以。这demo的代码和我的主题是完全一样的,只是服务器不同。 而我目前的站,就是不行~~~
        我想现在问题应该不是我主题问题了吧?
        我觉得应该是 数据库或则php版本问题了。。。

      4. zwwooooo says:

        @郑永
        这个代码没用什么php冷门函数什么的,就是用了:
        1. WP函数 WP_Query():只查询了一次
        2. 中间全部是字符串操作而已,最基本的
        3. WP函数:读取数据表 wp_options 某字段 - get_option()
        4. WP函数:写入/更新数据表 wp_options 某字段 - update_option()

      5. zwwooooo says:

        @郑永
        你可以去掉数据库缓存试试。把这几行注释掉变成:

        /* Archives list v2014 by zwwooooo | http://zww.me */
        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' => 'post', //如果你有多个 post type,可以这样 array('post', 'product', 'news')  
        			'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;
        			$posts_rebuild[$year][$mon][] = '<li>'. get_the_time('d日: ') .'<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_y => $y) {
        			$output .= '<h3 class="al_year">'. $key_y .' 年</h3><ul class="al_mon_list">'; //输出年份
        			foreach ($y as $key_m => $m) {
        				$posts = ''; $i = 0;
        				foreach ($m as $p) {
        					++$i;
        					$posts .= $p;
        				}
        				$output .= '<li><span class="al_mon">'. $key_m .' 月 <em> ( '. $i .' 篇文章 )</em></span><ul class="al_post_list">'; //输出月份
        				$output .= $posts; //输出 posts
        				$output .= '</ul></li>';
        			}
        			$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'); // 新发表文章/修改文章时
      6. 郑永 says:

        @zwwooooo
        好滴,马上试试,谢谢哈。

      7. 郑永 says:

        @zwwooooo
        去掉if那层么?就是 # 两行,还是不行啊。

      8. 郑永 says:

        @zwwooooo
        4个#注释。

      9. 郑永 says:

        @zwwooooo
        我记得以前试过好多种,都不行,那时候不是这个服务器,也不行,所以我觉得应该是我的数据库问题吧。。。那个demo网站唯一不同的是服务器和数据库,我觉得最大凶手是数据库。

    3. 大肥羊 says:

      @郑永
      应该是JQ有问题,firebug看看。 :mrgreen:
      TypeError: addListener(...) is not a function

    4. 郑永 says:

      @大肥羊
      我真的不知道,如何让网页一片空白,但是这段代码做到了。

    5. 郑永 says:

      @zwwooooo
      也许第一条吧~~汗。。。打开归档,一片空白,网页源代码没加载任何东西。

    6. 大肥羊 says:

      @郑永
      这代码放进去不会这么猛的,是不是没有保存成UTF8 无 BOM 格式?

    7. 郑永 says:

      @大肥羊
      不是的,我刚测试两个服务器同一个主题,一个可以一个不行,我想问题不在主题上了,也许php版本。。。。。。

  11. Louis Han says:

    还是原生的好啊

    1. zwwooooo says:

      @Louis Han
      嗯,这个只查询了一次,然后全部是php的字符串操作,所以算很省资源的了,而且还写入 options,所以没更新文章就只是读取一次。

  12. blackgold says:

    除了好,我没有其他可说的拉。好~

  13. 有点蓝 says:

    页面还是太长了,要是做成日历那样的,不知道会不会很难弄。

    1. zwwooooo says:

      @有点蓝
      都可以吧,改改调用就行,或者写成ajax 加载

  14. 安心 says:

    我使用的是大前端的代码。

    1. zwwooooo says:

      @安心
      原理差不多

  15. 都是玩转WP的大神,向你们学习。

  16. 关注一下,好像蛮复杂的。

  17. hokyin says:

    终于来个技术文章了

  18. 望奎来逛逛,还是一如既往的火热哇。加油。

  19. 我只是来膜拜大神的

  20. 优美拍 says:

    博主大神一更新就是福利。

回复给 大肥羊 ¬
取消回复

昵称 *

网址

B em del U Link Code Quote