不带插件的主页、搜索、标签和档案上的粘性帖子

时间:2015-04-08 作者:Jornes

我今天有个问题。我正在寻找一个解决方案,使粘性张贴在我的网站上可用。但是,我刚刚在主页上用下面的代码实现了它。

function wpb_latest_sticky() { 

/* Get all sticky posts */
$sticky = get_option( \'sticky_posts\' );

/* Sort the stickies with the newest ones at the top */
rsort( $sticky );

/* Get the 5 newest stickies (change 5 for a different number) */
$sticky = array_slice( $sticky, 0, 5 );

/* Query sticky posts */
$the_query = new WP_Query( array( \'post__in\' => $sticky, \'ignore_sticky_posts\' => 1 ) );
// The Loop
if ( $the_query->have_posts() ) {
    $return .= \'<ul>\';
    while ( $the_query->have_posts() ) {
        $the_query->the_post();
        $return .= \'<li><a href="\' .get_permalink(). \'" title="\'  . get_the_title() . \'">\' . get_the_title() . \'</a><br />\' . get_the_excerpt(). \'</li>\';

    }
    $return .= \'</ul>\';

} else {
    // no posts found
}
/* Restore original Post Data */
wp_reset_postdata();

return $return; 

} 
add_shortcode(\'latest_stickies\', \'wpb_latest_sticky\');
我正在考虑将粘性帖子也显示在搜索、标记和类别上。

有什么解决方案吗?谢谢

3 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

本周早些时候或周末,有人问了同样的问题,这让我思考。这是我想到的想法。

如果你看看source codeWP_Query 类中,您将看到粘性帖子仅添加到主页的第一页。也没有提供过滤器来更改此行为,以便根据您的喜好设置所需的模板。

有很多方法可以通过小部件、自定义查询、短代码(由于使用do_shortcode() 比使用函数本身更慢)或需要显示它们的自定义函数。我选择使用the_posts 过滤器和pre_get_posts 行动

以下是如何使用将帖子ID保存为粘性帖子的方法get_option( \'sticky_posts\' )

使用从主查询中删除此帖子pre_get_posts. 由于主页上包含胶粘物,我们将排除主页。我们还将排除正常页面

在自定义函数中,使用get_posts 将帖子设置为粘滞帖子。

将返回的粘性帖子数组与主查询的当前返回帖子合并为array_merge

将此自定义函数挂接到the_posts 滤器

以下是代码:(需要PHP 5.4+

add_action( \'pre_get_posts\', function ( $q )
{
    if (    !is_admin()
         && $q->is_main_query()
         && !$q->is_home()
         && !$q->is_page()
    ) {

        $q->set( \'post__not_in\', get_option( \'sticky_posts\' ) );

        if ( !$q->is_paged() ) {
            add_filter( \'the_posts\', function ( $posts )
            {
                $stickies = get_posts( [\'post__in\' => get_option( \'sticky_posts\' ), \'nopaging\' => true] );

                $posts = array_merge( $stickies, $posts );

                return $posts;

            }, 10, 2);
        }

    }
});

SO网友:mll

Pieter的答案确实有效,但当我们想显示过滤后的帖子(例如针对给定类别)时,它甚至会在页面上显示所有粘性帖子。

以下内容对我有用。将此添加到函数。php仅显示筛选帖子子集内的粘滞内容:

add_filter(\'the_posts\', \'bump_sticky_posts_to_top\');
function bump_sticky_posts_to_top($posts) {
    $stickies = array();
    foreach($posts as $i => $post) {
        if(is_sticky($post->ID)) {
            $stickies[] = $post;
            unset($posts[$i]);
        }
    }
    return array_merge($stickies, $posts);
(学分:http://pastebin.com/Y5jVrKg4, 稍微更改以防止出现警告:array\\u merge()[函数.array merge]:参数#1不是第9行的数组(错误)

然而,有一个很大的缺陷。如果当前页面中不存在此粘滞帖子,则不会在顶部提升粘滞帖子。

这是一个可以设定目标的系统。将CSS类粘贴到粘贴的帖子上也很好。

SO网友:RedNails

我需要一些修改(原版请参见Pieters的答案)才能让它只在分类页面上工作。此解决方案将显示当前类别(和子类别)的所有粘性帖子,但不会显示在搜索、标记和单个页面上:

add_action( \'pre_get_posts\', function ( $q ) {
    if ( !is_admin()
         && $q->is_main_query()
         && !$q->is_home()
         && !$q->is_tag()
         && !$q->is_search()
         && !$q->is_page()
         && !$q->is_single()
    ) {

      function is_existing_cat($q_catName) {
           $existingCats = get_categories();
           $isExistingCat = false;

           foreach ($existingCats as $cat) {
                if ($cat->name == $q_catName) {
                     $isExistingCat = true;
                }
           }

           return $isExistingCat;
      }

        if ($q->is_category() && !$q->is_paged() && is_existing_cat($q->query[\'category_name\'])) {

            $q->set( \'post__not_in\', get_option( \'sticky_posts\' ) );

            add_filter( \'the_posts\', function ( $posts ) {
                $catName = get_category(get_query_var(\'cat\'))->name;
                $catID = get_cat_ID($catName);

                if ( !empty(get_option( \'sticky_posts\' )) ) {
                    $stickies = get_posts( [
                        \'category\' => $catID,
                        \'post__in\' => get_option( \'sticky_posts\' )
                    ] );

                    $posts = array_merge( $stickies, $posts );
                }

                return $posts;

            }, 10, 2);
        }
    }
});
我添加了一个函数来检查该类别是否是现有类别,因为我遇到了指向该类别的问题。php而不是预期的404。php。链接,如/existing-cat/not-existing-post 工作但链接如下/not-existing-post-or-page-or-cat 没有。

如果您需要该帖子上的css类,可以将此代码添加到显示帖子内容的模板的PHP部分(例如,在2616中:template parts/content.PHP)

<?php
if (is_sticky()) {
    $stickyClass = \'sticky\';
} else {
    $stickyClass = \'\';
}
?>
然后将该类添加到帖子的css类中post_class($stickyClass); (此函数将通过几个类和您添加的类向HTML元素添加class属性)。您可以在以下文章中找到此功能:

<article id="post-<?php the_ID(); ?>" <?php post_class($stickyClass); ?>>
    ...
</article><!-- #post-## -->

结束

相关推荐

Where is search.php?

我在Wordpress 4.0.1上有一个网站,但我找不到搜索。php。数据库批处理过程已将模板应用于默认搜索结果页面,但我现在找不到该页面以将其更改回原来的页面。如何更改此页面的模板?在我的主题中创建一个新的“search.php”会有帮助吗?如果是,此文件应包含哪些内容?