年前实现的一个小功能,实现按英文标题首字母A-Z排序,jQuery+ajax载入文章列表。比如点击字母A,就会ajax载入以A开头的文章列表,如下图所示:
估计只能用于字母或数字做标题博客,一些CMS项目估计用得上。下面是主要js和相应部分。
放在function.php里的:
首先是输出A-Z的链接,包含0~9的数字开头的文章,去数据库里查询是否存在以各个字母开头的文章,(这一步可能对文章很多的站点是个问题,因为遍历了所有文字,目前还没有好的想法,大概优化的思路是数据库新建一个表专门用来存储文章首字母数据)
<?php function aznav(){ $num=array('0','1','2','3','4','5','6','7','8'.'9'); $alphabet=array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'); global $wpdb; $myposts = $wpdb->get_results(" SELECT post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post' ORDER BY post_title "); $n[]=''; foreach($myposts as $mypost) { $n[]=strtoupper(SUBSTR(trim($mypost->post_title),0,1)); } $outpot='<div id="aznav"><ol><li class="home">A-Z index:</li><li class="back" style="display:none;"><a href="javascript:void(0);">Back</a></li>'; for ($i=0; $i < count($num); $i++) {if(in_array($num[$i],$n)){$number=true;break;}} if($number){ $outpot .='<li><a href="javascript:void(0);" class="azindex" rel="num">0-9</a></li>'; }else{ $outpot .='<li>0-9</li>'; } for ($i=0; $i < count($alphabet); $i++) { if(in_array($alphabet[$i],$n)){ $outpot .='<li><a href="javascript:void(0);" class="azindex" rel="'.$alphabet[$i].'">'.$alphabet[$i].'</a></li>'; }else{ $outpot .='<li>'.$alphabet[$i].'</li>'; } } $outpot .='</ol></div><div style="clear:both"></div>'; echo $outpot; }
其次是对ajax处理的响应部分,从数据库里面取出对应字母开头的文章列表,对数字和字母分别进行处理,在这了用了wp自带的缓存”wp_cache_get”,减少数据库查询,提高性能:
<?php /** * Ajaxletter * * @by winy 2011.2.6 */ function Ajaxletter(){ if( isset($_GET['action'])&& $_GET['action'] == 'Ajaxletter' ){ nocache_headers(); //(FIX for IE) $letter = isset($_GET['letter']) ? $_GET['letter'] : null; if(!$letter){ fail(__('Error post letter.')); }else{ if($output = wp_cache_get('index_'.$letter, 'Winy')){//use the cache function for better performance echo $output; die(); } global $wpdb; // This query is the KEY to find the post! if ($letter=='num'){//for numbers $myposts = $wpdb->get_results(" SELECT ID, post_title, post_name FROM $wpdb->posts WHERE SUBSTRING(LOWER(post_title),1,1) BETWEEN '0' AND '9' AND post_status = 'publish' AND post_type = 'post' ORDER BY post_title ASC "); }else{//For alphabet $myposts = $wpdb->get_results(" SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_title LIKE '".$letter."%' AND post_status = 'publish' AND post_type = 'post' ORDER BY post_title ASC "); } $output = '<div id="azload" class="hentry">'; if(empty($myposts)){ $output.='Apologies, but no results were found for the requested archive. Perhaps searching will help find a related post.'; }else{ foreach($myposts as $mypost) { $output .='<div><a href="'. get_permalink($mypost->ID). '">'.$mypost->post_title .'</a></div>'; } wp_cache_add('index_'.$letter, $output, 'Winy');//add a cache } $output .= '</div>'; echo $output; die(); } }else{ return; } } add_action('init', 'Ajaxletter');
最后用的是jQuery的ajax过程,这个就简单了:
jQuery(document).ready(function($) { $('.azindex').click(function(){ if ($(this).parent().hasClass("active")){ return false; } var contentCache =false; var letter=$(this).attr("rel"); //alert(letter);//for test $.ajax({ url : base+ "?action=Ajaxletter&letter="+letter,//base url must be defined type: 'get', beforeSend: function() { document.body.style.cursor = 'wait'; var load='<h1 class="page-title">Loading...Please wait for a while</h1>'; $(this).parent().addClass("active").siblings().removeClass(); $('#aznav li.home').hide(); $('#aznav li.back').show(); contentCache = $('#content')[0].innerHTML; $('#content').empty().html(load); }, error: function(request) { alert(request.responseText); }, success:function (data) { document.body.style.cursor = 'auto'; $('#content').empty().html(data); $('#aznav li.back a').click( function() { $('#content').empty().html(contentCache); $('#aznav li.back').hide(); $('#aznav li.home').show(); return false; }); } }); return false; }); });
思路是很简单,主要是php响应部分,涉及到数据库查询,这个比较麻烦一点。另外,只适合英文首字母,对于中文的博客就没那么简单了。需要把汉字编码转换成拼音,再来排序存储在一个新的表里面,按拼音首字母排序,想想就麻烦..