最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to hide protected posts from archive?

programmeradmin10浏览0评论

Im trying to hide protected posts in WP from loop:

function hideProtectedPosts( $where = '' ) {
    if (!is_single() && !is_admin()) {
        $where .= " AND post_password = ''";
    }
    return $where;
}
add_filter( 'posts_where', 'hideProtectedPosts' );

works fine, but except archive. For eg. I have one post in June. In calendar widget I still can see that is post at this date, but when I get there, then I get 404.

Im trying to hide protected posts in WP from loop:

function hideProtectedPosts( $where = '' ) {
    if (!is_single() && !is_admin()) {
        $where .= " AND post_password = ''";
    }
    return $where;
}
add_filter( 'posts_where', 'hideProtectedPosts' );

works fine, but except archive. For eg. I have one post in June. In calendar widget I still can see that is post at this date, but when I get there, then I get 404.

Share Improve this question asked Oct 5, 2020 at 11:14 D_PD_P 1531 gold badge3 silver badges12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

There are 2 answers depending on where you want to do this. One has good news, the other has bad news

Anywhere That Uses Post Queries

Modifying the SQL is rarely necessary here and usually a sign that something was overlooked. In this case, WP_Query already provides a simple parameter to do this named has_password.

With this in mind, we can modify the main loop to hide passworded/protected posts easily via pre_get_posts:

add_action( 'pre_get_posts', function ( \WP_Query $q ) {
    if ( is_admin() || $q->is_singular() ) {
        return;
    }
    $q->set( 'has_password', false );
} );

Anywhere That uses the get_calendar function

This includes the calendar widget and block, I'm afraid the news is not great.

get_calendar doesn't use WP_Query, but instead uses raw SQL queries to count posts ( it doesn't retrieve the posts ). It doesn't provide filters for the SQL either.

It does provide 2 opportunities however:

  • The get_calendar filter gives you the final HTML, allowing you to make some modifications to the final string. With this you could completely replace the HTML by re-implementing get_calendar and returning new HTML that excludes private posts in the SQL
  • The query filter. Because get_calendar calls WPDB query directly, you could filter on this, however, this filter runs on all queries WP makes, not just those for the calendar. You will need to figure out if a query is coming from get_calendar or not, which may be difficult or impossible. If you modify a query that isn't from get_calendar you could cause problems that lead to instability. There is also a potential bug, get_calendar does a check if there are any posts and returns an empty string if none are found, if that post is a passworded post then this could lead to a calendar that has no posts. Be careful to make any filter on this run as fast as possible or you'll slow down WP a lot, this means no new DB queries in the filter, no fetching data, no making http requests or loading files. There's also the danger of recursive loops.

Note that get_calendar caches by both month and year, so you need to flush caches to see updated output

Why Didn't posts_where work?

It didn't work because that filter is a part of WP_Query, which isn't used by get_calendar. I would advise against using this though as it breaks the post_password parameter of WP_Query and the functions that depend on it ( e.g get_posts or areas of the admin )

发布评论

评论列表(0)

  1. 暂无评论