Blog

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

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

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

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

141028-archives-page-template-2014

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

1. 归档函数

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

/* 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'); // 新发表文章/修改文章时

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

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

/* 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' => 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

声明: 除非注明,ZWWoOoOo文章均为原创,转载请以链接形式标明本文地址
本文地址: http://zww.me/wordpress-archive-page-template-wp-primary-function-2014-edition.z-turn

90 comments

  1. 大肥羊 大肥羊 Firefox 32 Firefox 32 Windows 7 Windows 7

    :mrgreen: 已修改成功。

    沙发
    • zwwooooo zwwooooo Firefox 32 Firefox 32 Windows 8.1 Windows 8.1

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

    • 大肥羊 大肥羊 Firefox 32 Firefox 32 Windows 7 Windows 7

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

    • 调皮鬼 调皮鬼 Firefox 33 Firefox 33 Windows 7 Windows 7

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

    • zwwooooo zwwooooo Firefox 33 Firefox 33 Windows 8.1 Windows 8.1

      @调皮鬼
      文囧罢了……

  2. Angely Angely Firefox 32 Firefox 32 Windows 8.1 Windows 8.1

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

    板凳
  3. 不亦乐乎 不亦乐乎 Google Chrome 36 Google Chrome 36 Windows XP Windows XP

    板凳!!

    地板
  4. 不亦乐乎 不亦乐乎 Google Chrome 36 Google Chrome 36 Windows XP Windows XP

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

    4楼
  5. Xiaolong Xiaolong Google Chrome 38 Google Chrome 38 Windows 7 Windows 7

    主题一个比一个好看

    5楼
  6. wyst wyst Google Chrome 38 Google Chrome 38 Windows 7 Windows 7

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

    6楼
    • zwwooooo zwwooooo Firefox 32 Firefox 32 Windows 8.1 Windows 8.1

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

  7. 大发 大发 Firefox 33 Firefox 33 Windows 7 Windows 7

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

    7楼
    • zwwooooo zwwooooo Firefox 32 Firefox 32 Windows 8.1 Windows 8.1

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

  8. allan allan Internet Explorer 8 Internet Explorer 8 Windows XP Windows XP

    看见代码就头疼 :mrgreen:

    8楼
  9. 甜菜 甜菜 Sogou Explorer Sogou Explorer Windows 8.1 Windows 8.1

    哈哈,看看哦.

    9楼
  10. 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

    10楼
    • zwwooooo zwwooooo Firefox 32 Firefox 32 Windows 8.1 Windows 8.1

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

    • 郑永 郑永 WebView 4 WebView 4 Android 4.4.2 Android 4.4.2

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

    • zwwooooo zwwooooo Firefox 33 Firefox 33 Windows 8.1 Windows 8.1

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

    • 郑永 郑永 WebView 4 WebView 4 Android 4.4.2 Android 4.4.2

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

    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

    • zwwooooo zwwooooo Firefox 33 Firefox 33 Windows 8.1 Windows 8.1

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

    • zwwooooo zwwooooo Firefox 33 Firefox 33 Windows 8.1 Windows 8.1

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

      /* 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'); // 新发表文章/修改文章时
    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

      @zwwooooo
      4个#注释。

    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

    • 大肥羊 大肥羊 Firefox 30 Firefox 30 Windows 7 Windows 7

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

    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

    • 大肥羊 大肥羊 Firefox 30 Firefox 30 Windows 7 Windows 7

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

    • 郑永 郑永 Google Chrome 38 Google Chrome 38 Windows XP Windows XP

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

  11. Louis Han Louis Han Firefox 33 Firefox 33 Windows 7 Windows 7

    还是原生的好啊

    11楼
    • zwwooooo zwwooooo Firefox 33 Firefox 33 Windows 8.1 Windows 8.1

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

  12. blackgold blackgold Google Chrome 31 Google Chrome 31 Windows 7 Windows 7

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

    12楼
  13. 有点蓝 有点蓝 Maxthon 4 Maxthon 4 Windows 7 Windows 7

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

    13楼
  14. 安心 安心 Firefox 34 Firefox 34 Windows 7 Windows 7

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

    14楼
  15. 网赚巴巴 网赚巴巴 Firefox 32 Firefox 32 Windows 7 Windows 7

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

    15楼
  16. 歌词大全 歌词大全 Google Chrome 38 Google Chrome 38 Windows 7 Windows 7

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

    16楼
  17. hokyin hokyin Google Chrome 38 Google Chrome 38 Windows 8 Windows 8

    终于来个技术文章了

    17楼
  18. 王望奎博客 王望奎博客 Firefox 33 Firefox 33 Windows 7 Windows 7

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

    18楼
  19. 微信公众帐号导航 微信公众帐号导航 Firefox 33 Firefox 33 Windows 7 Windows 7

    我只是来膜拜大神的

    19楼
  20. 优美拍 优美拍 Google Chrome 37 Google Chrome 37 Windows 7 Windows 7

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

    20楼

Leave a Reply