填写您的邮件地址,订阅我们的精彩内容:

WordPress选择特定的分类 也可以置顶文章

WordPress有个很大的毛病,首页默认情况下是会显示置顶文章的,而分类、标签、归档页等就不能显示置顶。它的逻辑是,人们只在首页需要注意哪些置顶文章,而归档页不需要。

但现实中其实是,我们常常把首页弄成CMS模式,让最新的文章被用户看到,而到了分类页时,为了突出某些文章的重要性,又把它置顶。

为了解决分类标签页不能置顶的问题,我特意找了一下,露兜在一篇文章中总结出了这个解决方案。但这个方案存在一个问题,它让所有的归档页都能实现把置顶文章放在最前面,问题就来了,例如按时间归档的页面,读者当然想知道这个月份的文章发文顺序,如果置顶,那就不伦不类了。

还有一个问题,能不能做到有些分类可以置顶,有些分类不置顶,可以自己控制呢?答案是肯定的,下面的代码可以解决这个问题。

我已经将这个项目托管在GitHub,你可以通过下面的按钮去访问。欢迎Fork哦。

github上的代码有一点问题,我在自己的博客中使用时,发现has_category函数无法正常运行,可能由于某些原因吧,但这说明存在兼容性问题,因此,我把代码进行了改进,完整的代码如下:

<?php

add_filter('the_posts',? 'putStickyOnTop',1,100 );
function putStickyOnTop( $posts ) {
? if(is_home() || !is_main_query() || !is_archive())return $posts;
?
? global $wp_query;

? // 如果这个分类没有开启显示置顶的话
? if($wp_query->is_category == 1 || $wp_query->is_tag == 1) {
??? if($wp_query->is_category == 1)$term_id = $wp_query->query_vars['cat'];
??? else $term_id = $wp_query->query_vars['tag_id'];
??? $show_sticky = get_term_meta($term_id,'show_sticky');
??? if(!$show_sticky)return $posts;
? }
? // 不是分类或标签就不要置顶了
? else {
??? return $posts;
? }

? // 获取所有置顶文章
? $sticky_posts = get_option('sticky_posts');
?
? if ( $wp_query->query_vars['paged'] <= 1 && !empty($sticky_posts) && is_array($sticky_posts) && !get_query_var('ignore_sticky_posts') ) {
??? foreach ( $sticky_posts as $sticky_post ) {
????? // 判断当前是否分类页
????? if($wp_query->is_category == 1) {
??????? $post_cats = wp_get_post_categories($sticky_post);
??????? if(in_array($wp_query->query_vars['cat'],$post_cats))continue;
??????? // 去除不属于本分类的置顶文章
??????? $offset = array_search($sticky_post, $sticky_posts);
??????? unset( $sticky_posts[$offset] );
????? }
????? if($wp_query->is_tag == 1) {
??????? $post_tags = wp_get_post_tags( $sticky_post, array( 'fields' => 'ids' ) );
??????? if(in_array($wp_query->query_vars['tag_id'],$post_tags))continue;
??????? // 去除不属于本标签的文章
??????? $offset = array_search($sticky_post, $sticky_posts);
??????? unset( $sticky_posts[$offset] );
????? }
??? }
?
??? $num_posts = count($posts);
??? $sticky_offset = 0;
??? // Loop over posts and relocate stickies to the front.
??? for ( $i = 0; $i < $num_posts; $i++ ) {
????? if ( in_array($posts[$i]->ID, $sticky_posts) ) {
??????? $sticky_post = $posts[$i];
??????? // Remove sticky from current position
??????? array_splice($posts, $i, 1);
??????? // Move to front, after other stickies
??????? array_splice($posts, $sticky_offset, 0, array($sticky_post));
??????? // Increment the sticky offset. The next sticky will be placed at this offset.
??????? $sticky_offset++;
??????? // Remove post from sticky posts array
??????? $offset = array_search($sticky_post->ID, $sticky_posts);
??????? unset( $sticky_posts[$offset] );
????? }
??? }

??? // If any posts have been excluded specifically, Ignore those that are sticky.
??? if ( !empty($sticky_posts) && !empty($wp_query->query_vars['post__not_in'] ) )
????? $sticky_posts = array_diff($sticky_posts, $wp_query->query_vars['post__not_in']);

??? // Fetch sticky posts that weren't in the query results
??? if ( !empty($sticky_posts) ) {
????? $stickies = get_posts( array(
??????? 'post__in' => $sticky_posts,
??????? 'post_type' => $wp_query->query_vars['post_type'],
??????? 'post_status' => 'publish',
??????? 'nopaging' => true
????? ) );

????? foreach ( $stickies as $sticky_post ) {
??????? array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );
??????? $sticky_offset++;
????? }
??? }
? }
?
? return $posts;
}

/**
下方的代码用以实现term_meta
**/

add_action('category_add_form_fields','extra_term_show_sticky__fields');
add_action('edit_category_form_fields','extra_term_show_sticky__fields');
add_action('add_tag_form_fields','extra_term_show_sticky__fields');
add_action('edit_tag_form_fields','extra_term_show_sticky__fields');
function extra_term_show_sticky__fields($term){
? $metas = array(
??? array('meta_name' => '置顶文章','meta_key' => 'show_sticky'),
? );
? $term_id = $term->term_id;
? foreach($metas as $meta) {
??? $meta_name = $meta['meta_name'];
??? $meta_key = $meta['meta_key'];
??? $meta_value = get_option("term_{$term_id}_meta_{$meta_key}");
??? ?>
<tr class="form-field">
? <th scope="row" valign="top"><label for="term_<?php echo $meta_key; ?>"><?php echo $meta_name; ?></label></th>
? <td><input type="text" name="term_meta_<?php echo $meta_key; ?>" id="term_<?php echo $meta_key; ?>" class="regular-text" value="<?php echo $meta_value; ?>"></td>
</tr>
??? <?php
? }
}

add_action('created_category','save_extra_term_show_sticky__fileds');
add_action('edited_category','save_extra_term_show_sticky__fileds');
add_action('created_post_tag','save_extra_term_show_sticky__fileds');
add_action('edited_post_tag','save_extra_term_show_sticky__fileds');
function save_extra_term_show_sticky__fileds($term_id){
? if(!empty($_POST))foreach($_POST as $key => $value){
??? echo $key;
??? if(strpos($key,'term_meta_') === 0 && trim($value) != '') {
????? $meta_key = str_replace('term_meta_','',$key);
????? $meta_value = trim($value);
????? update_option("term_{$term_id}_meta_{$meta_key}",$meta_value) OR add_option("term_{$term_id}_meta_{$meta_key}",$meta_value);
??? }
? }
}

if(!function_exists('get_term_meta')) :
function get_term_meta($term_id,$meta_key){
? if(is_object($term_id))$term_id = $term_id->term_id;
? $term_meta = get_option("term_{$term_id}_meta_{$meta_key}");
? if($term_meta){
??? return $term_meta;
? }else{
??? return null;
? }
}
endif;

注意:上面这段代码和github中代码有一个简单的区别,已经用红色区分开来。当然还有一些区别,例如github上的代码有在日期归档列表中也生效的代码,但是我们这篇文章说的是,可以通过后台来控制,而且也强调了没有必要让归档页都使用该功能,所以仅仅把这个置顶功能限定在分类列表页和标签归档列表页。

将所有的代码拷贝到你的主题functions.php中,上传覆盖即可。

进入后台,如果你想让某一个分类或标签实现该功能,那么进入这个分类或标签的编辑页,在下方你可以找到如下图的选项,填1即可。

2014-10-29-235721

更新之后去这个分类看下,是否有置顶文章被放上来了?

还有一种情况,你希望所有的分类标签都置顶,但是可以控制某几个分类不置顶。这当然可以办到,稍作修改即可。如果你有相关需要可以通过下方评论框回复给我哦。对了,大赏给我呀!

下面我简单说几句