castle 1158201 1920
Quelle: Pixabay, extrabrandt

WordPress: eine oder mehrere Kategorien aus dem Blog separieren

Um ein paar Beiträge für eine besondere Darstellung zu reservieren, zum Beispiel als Testimonials auf einer Seite, kann man einen zusätzlichen Inhaltstypen (Custom Post Type) definieren und einsetzen. Dieser hat automatisch sein eigenes Archiv ( http://example.com/posttypename ). Wenn man das nicht will, erreicht man die Separierung ausgewählter Beiträge auch, indem man eine oder mehrere Kategorien aus dem öffentlichen Blogteil ausschließt.

Das Beispiel entstand aus der Herausforderung, eine Kategorie (die für eine Testimonialseite reserviert werden sollte) aus dem öffentlichen Blogteil möglichst umfassend zu entfernen, und geht davon aus, dass Kategorien mit den IDs 6, 7 und 8 auszuschließen sind.

Falls nicht anders erwähnt, werden die Funktionen in der functions.php des Themes eingesetzt.

Der Loop

Über pre_get_posts werden Kategorien wie folgt aus dem Loop, dem »Letzte Beiträge«-Widget und der Posts-Pagination ausgefiltert (Achtung, nicht aus der Post Navigation, die meist im Template single.php zu finden ist, dazu später).

function pptf_exclude_categories_from_queries( $query ) { 
    if ( !is_admin() && !$query->get( 'cat' ) ) {
        $query->set( 'category__not_in', array(6,7,8) ); // Array ID oder IDs der Kategorie(n)
    }
}
add_action( 'pre_get_posts', 'pptf_exclude_categories_from_queries' );
Um die Kategorie direkt zu verwenden, if ( !is_admin() && !$query->get( 'cat' ) ) { ändern in if ( !is_admin() && !$query->get( 'cat' ) && !is_category() ) {, ansonsten sind die Beiträge nur über einen Custom Query verfügbar. Auf der Kategorieseite verhält sich das »Neueste Beiträge«-Widget dann entsprechend.

Das Kategorien-Widget

Der nächste Filter schließt Kategorie(n) aus dem »Kategorien«-Widget aus.

function pptf_exclude_categories_from_widget( $args ) {
     $args['exclude'] = array(6,7,8); // Array ID oder IDs der Kategorie(n)
     return $args;
}
add_filter( 'widget_categories_args', 'pptf_exclude_categories_from_widget', 10, 1 );

Das »Letzte Kommentare«-Widget

Nicht ganz so glatt geht das Filtern von Kommentaren vor sich, da get_comments kein Argument für Kategorien anbietet, allerdings post__not_in für auszufilternde Post IDs. Um die IDs zu ermitteln, ging ich den Weg über get_posts. An der Stelle bleibt allerdings abzuwägen, ob das Filtern von Kommentaren überhaupt erforderlich ist. Gibt man niemandem Gelegenheit dazu, Kommentare zu Beiträgen in versteckten Kategorien zu verfassen, erübrigt sich der nachfolgende Teil.

function pptf_get_post_ids_from_category() { 
    $args = array('category' => 6,7,8); // ID oder kommagetrennte Liste von IDs der Kategorie(n)
    $filter = get_posts($args);
    $post_ids = array();
    foreach($filter as $post) {
       $post_ids[] = $post->ID;
    }
    return($post_ids);
}

Anschließend entfernt der Filter die Kommentare zu den gesammelten Post-IDs aus dem »Letzte Kommentare«-Widget.

/* get_comments args */
function pptf_exclude_categories_from_comments( $args ) {
$args['post__not_in'] = pptf_get_post_ids_from_category(); 
    return $args;
}
add_filter( 'widget_comments_args', 'pptf_exclude_categories_from_comments', 10, 1 );

Das Archive Widget

function pptf_archives_join( $sql ) {
    global $wpdb;
    return $sql . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
}
add_filter( 'getarchives_join', 'pptf_archives_join' );
 
function pptf_archives_where( $sql ) {
    global $wpdb;
    $exclude = '6,7,8'; // kommgetrennte Kategorie-IDs.Liste
 return $sql . " AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id NOT IN ($exclude)";
}
add_filter( 'getarchives_where', 'pptf_archives_where' );

Post Navigation (single.php oder singular.php)

Bis hierher findet alles in der functions.php statt. Der letzte Filter betrifft die Post Navigation (Links zum jeweils vorherigem und nächstem Beitrag). Neuere Theme-Versionen verwenden hier vermutlich bereits die Funktion the_post_navigation.
Diese Funktion bekommt als zusätzliches Argument 'excluded_terms' => array(6,7,8),, Beispiel:

// Previous/next post navigation.
the_post_navigation( array(
    'next_text' => '<span class="meta-nav" aria-hidden="true">' . __( 'Next', 'my-theme-textdomain' ) . '</span> ' .
        '<span class="screen-reader-text">' . __( 'Next post:', 'my-theme-textdomain' ) . '</span> ' .
        '<span class="post-title">%title</span>',
    'prev_text' => '<span class="meta-nav" aria-hidden="true">' . __( 'Previous', 'my-theme-textdomain' ) . '</span> ' .
        '<span class="screen-reader-text">' . __( 'Previous post:', 'my-theme-textdomain' ) . '</span> ' .
        '<span class="post-title">%title</span>',
    'excluded_terms' => array(6,7,8),
 ) );

Andernfalls erhalten die beiden Funktionen next_post_link() und previous_post_link() das Argument zum Filtern der Kategorie(n).

Das Kalender-Widget

Dieses bietet mit <a href="https://developer.wordpress.org/reference/functions/get_calendar/" target="_blank">get_calendar()</a> nur einen Filter für den gesamten Output. Wer also Posts bestimmter Kategorien aus Kalenderlinks heraushalten will (Links auf Tage an denen ausschließlich Beiträge in versteckten Kategorien verfasst wurden, geben dann 404 zurück), hat derzeit keine andere Wahl (sofern es kein Plugin gibt, dass mehr Flexibilität bietet), als den Output zu kopieren und entsprechend umzuschreiben, oder auf den Gebrauch des Kalender-Widgets zu verzichten.

Über Gabriele Lässer

WordPress Sorgen? - Nicht mit mir! Ich freue mich auf spannende Herausforderungen

Kommentar schreiben

E-Mail-Adresse wird nicht veröffentlicht.

Overlay background for modal content