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即可。

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

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

0

评论0

请先

没有账号? 注册  忘记密码?

社交账号快速登录