Na forum i grupach WP często pojawia się pytanie o to, jak sprawić, aby wpisy z wybranej kategorii nie pojawiały się na stronie głównej. Jak to zrobić poprawnie? Wbrew pozorom nie jest to wcale takie trudne – realizuje to poniższy fragment kodu:

function prefiks_exclude_category_from_homepage( $query ) {
    if ( !is_admin() && $query->is_main_query() && is_home() ) {
        $category_not_in = $query->get( 'category__not_in', array() );

        if ( is_scalar($category_not_in) ) {
            $category_not_in = array( $category_not_in );
        } elseif ( !is_array($category_not_in) ) {
            $category_not_in = array();
        }

        $category_not_in[] = 3;  // <- zmień 3 na ID kategorii, którą chcesz ukryć

        $query->set( 'category__not_in', $category_not_in );
    }
}
add_filter( 'pre_get_posts', 'prefiks_exclude_category_from_homepage' );

Dodatkowe warianty i pytania

Jak ukryć więcej niż jedną kategorię?

Wystarczy, że powielisz wiersz, w którym wymieniony jest ID kategori. Na przykład poniższa modyfikacja ukryje wpisy z kategorii 3 i 5.

...
        $category_not_in[] = 3;
        $category_not_in[] = 5;
...

Co się stanie z wpisami z kategorii podrzędnych?

Ukryte zostaną tylko wpisy, które są bezpośrednio przypisane do wybranej kategorii. Wpisy z kategorii podrzędnych wymienionej kategorii będą nadal wyświetlane. Jeśli chcesz ukryć także te wpisy, musisz wymienić wszystkie te kategorie.

Spotkałem rozwiązanie oparte o query_posts() lub własne wp_query w szablonie. Dlaczego nie powinienem go używać?

Z dwóch powodów. Przede wszystkim dlatego, że wykonujesz wtedy zupełnie niepotrzebnie dodatkowe zapytanie do bazy danych. Ponadto uniemożliwiasz w ten sposób wtyczkom i motywowi ingerencję w zawartość tego zapytania.