Posts aus Kategorien in WordPress extrahieren, Entwicklerhandbuch

Posts aus Kategorien in WordPress extrahieren, Entwicklerhandbuch

Zuletzt überprüft: 12. Oktober 2026
30 Min. Lesezeit
Tutorial
500+ WP-Projekte
Full-Stack-Entwickler

Eine der häufigsten Aufgaben für WordPress-Entwickler ist das Anzeigen einer Liste von Beiträgen aus einer bestimmten Kategorie. Ob Sie einen Nachrichtenbereich, eine Blogseite mit thematischen Beiträgen oder ein Portfolio erstellen möchten, die Fähigkeit, Inhalte aus bestimmten Kategorien zu filtern und abzurufen, ist grundlegend wichtig. WordPress bietet mehrere robuste Methoden, um dies zu erreichen, von einfachen Funktionsaufrufen bis hin zu komplexen Datenbankabfragen. In diesem umfassenden Leitfaden werden wir alle diese Methoden im Detail untersuchen, mit Fokus auf Best Practices, Optimierung und häufige Fehler, auf die Entwickler stoßen.

Es gibt drei Hauptmethoden zum Abrufen von Beiträgen aus Kategorien in WordPress: get_posts() für einfache Listen ohne vollständige Schleifensteuerung, WP_Query für volle Kontrolle mit Paginierung und erweiterten Filtern, sowie query_posts(), das generell nicht empfohlen wird, da es die Hauptschleife beeinträchtigt. Wir werden jede Methode im Detail durchgehen, mit praktischen Codebeispielen, die Sie direkt in Ihren eigenen Projekten verwenden können.

#Was sind Taxonomien und Kategorien in WordPress

Bevor wir uns in die Codebeispiele vertiefen, ist es wichtig, die grundlegenden Konzepte hinter dem Kategoriensystem in WordPress zu verstehen. Kategorien sind eine Art von Taxonomie, eine Möglichkeit, Inhalte in WordPress zu organisieren. Die Standardtaxonomien umfassen Kategorien für Beiträge und Tags, aber Sie können auch benutzerdefinierte Taxonomien für komplexere Inhaltsstrukturen erstellen. Eine Kategorie in WordPress ist hierarchisch, was bedeutet, dass Sie Unterkategorien haben können, die wiederum eigene Unterkategorien haben können. Diese Hierarchie ist wichtig zu berücksichtigen, wenn Sie Beiträge abrufen möchten, da Sie entscheiden müssen, ob Sie nur Beiträge aus einer bestimmten Kategorie oder auch Beiträge aus deren Unterkategorien anzeigen möchten.

Wenn Sie mit Kategorien in WordPress arbeiten, werden Sie häufig auf die Begriffe „Category ID” und „Category Slug” stoßen. Die Category ID ist eine eindeutige Identifikationsnummer, die WordPress jeder Kategorie zuordnet, während der Category Slug eine URL-freundliche Zeichenfolge ist, die die Kategorie identifiziert. Beide können zum Filtern von Beiträgen verwendet werden, haben aber unterschiedliche Vor- und Nachteile. Die Category ID ist genauer, da sie eindeutig ist, während der Category Slug lesbarer ist und ohne größere Auswirkungen auf bestehende Links geändert werden kann. Es wird empfohlen, den Category Slug zu verwenden, wo immer dies praktisch möglich ist, da dies den Code wartungsfreundlicher macht.

#Wie get_posts() Beiträge einer Kategorie lädt

Die Funktion get_posts() ist der einfachste Weg, Beiträge aus einer Kategorie abzurufen, und eignet sich perfekt für Situationen, in denen Sie eine einfache Liste ohne erweiterte Schleifensteuerung benötigen. Diese Funktion gibt ein Array von Beitragsobjekten zurück, über das Sie dann iterieren können. Ein Vorteil von get_posts() ist, dass es die Hauptschleife in WordPress nicht beeinflusst, was bedeutet, dass Sie es sicher in der Seitenleiste, im Footer oder anderen Teilen der Seite verwenden können, ohne das Hauptinhält zu stören.

<?php
$args = array(
    'posts_per_page'   => 5,
    'category_name'    => 'nachrichten',
    'orderby'          => 'date',
    'order'            => 'DESC',
    'suppress_filters' => true,
);

$posts_array = get_posts( $args );

foreach ( $posts_array as $post ) :
    setup_postdata( $post );
    ?>
    <li>
        <a href="<?php the_permalink(); ?>">
            <?php the_title(); ?>
        </a>
        <span class="post-date"><?php echo get_the_date(); ?></span>
    </li>
<?php endforeach;
wp_reset_postdata();
?>

Dieses Beispiel zeigt die grundlegenden Parameter, die Sie häufig verwenden werden: posts_per_page bestimmt, wie viele Beiträge abgerufen werden sollen, category_name filtert nach dem Kategorie-Slug, und orderby und order steuern die Sortierung. Beachten Sie, dass wir setup_postdata() verwenden, um globale Beitragdaten für jeden Beitrag in der Schleife einzurichten, und wp_reset_postdata() verwenden, um diese Daten zurückzusetzen, nachdem die Schleife abgeschlossen ist. Dies ist entscheidend, um zu verhindern, dass spätere Funktionsaufrufe falsche Beitragdaten verwenden.

Um Beiträge aus einer bestimmten Kategorie mit der Category ID anstelle des Slugs abzurufen, können Sie den cat-Parameter verwenden:

<?php
$args = array(
    'posts_per_page' => 10,
    'cat'            => 12, // Kategorie-ID
    'orderby'        => 'title',
    'order'          => 'ASC',
);

$posts = get_posts( $args );

foreach ( $posts as $post ) {
    setup_postdata( $post );
    echo '<h3>' . get_the_title() . '</h3>';
    echo '<p>' . get_the_excerpt() . '</p>';
}

wp_reset_postdata();
?>

#Was get_posts gegenüber WP_Query ändert

get_posts() ist eine dünne Hülle, die ein WP_Query mit eigenen Standardwerten baut. Der Quellcode der Funktion zeigt vier Unterschiede, die bei Kategorielisten zählen:

  • numberposts steht standardmäßig auf 5, ein Aufruf ohne Limit liefert also stillschweigend fünf Beiträge.
  • post_status steht auf publish und suppress_filters auf true, daher laufen posts_where und ähnliche SQL-Filter von Plugins nicht. Die Action pre_get_posts feuert trotzdem.
  • ignore_sticky_posts und no_found_rows werden immer auf true gezwungen. Eine nummerierte Paginierung lässt sich auf get_posts() nicht aufbauen, weil die Gesamtzahl nie berechnet wird.
  • include setzt posts_per_page auf die Anzahl der übergebenen IDs und überschreibt Ihr eigenes Limit.

Eine weitere Falle betrifft get_posts() innerhalb einer Funktion oder eines Shortcode-Callbacks. setup_postdata() bereitet die Template-Tags vor, aber the_title() und the_permalink() lesen weiterhin das globale $post. Deklarieren Sie global $post; vor der Schleife foreach ( $posts as $post ), wie es die Beispiele der Funktionsreferenz tun, und schließen Sie mit wp_reset_postdata() ab. Ohne diese Deklaration gibt jeder Listeneintrag den Titel der Seite aus, auf der der Shortcode steht.

#Wie WP_Query Kategorie-Beiträge mit Paginierung holt

Für fortgeschrittene Anwendungsfälle, in denen Sie Paginierung, komplexe Filter oder vollen Zugriff auf alle WordPress-Schleifenfunktionen benötigen, ist WP_Query die beste Wahl. Diese Klasse gibt Ihnen viel mehr Kontrolle über die Abfrage und ermöglicht es Ihnen, komplexe Ansichten zu erstellen, die mit get_posts() fast unmöglich wären. WP_Query ist auch die am besten dokumentierte und flexibelste Methode für benutzerdefinierte Templates.

<?php
$category_query = new WP_Query( array(
    'category__in'      => array( 12, 15, 18 ),
    'posts_per_page'    => 6,
    'ignore_sticky_posts' => true,
    'paged'             => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
) );

if ( $category_query->have_posts() ) :
    echo '<div class="posts-grid">';

    while ( $category_query->have_posts() ) :
        $category_query->the_post();
        ?>
        <article class="post-item">
            <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
            <div class="post-meta">
                <span class="date"><?php echo get_the_date(); ?></span>
                <span class="author"><?php echo get_the_author(); ?></span>
            </div>
            <div class="post-excerpt">
                <?php the_excerpt(); ?>
            </div>
            <a href="<?php the_permalink(); ?>" class="read-more">
                Weiterlesen
            </a>
        </article>
        <?php
    endwhile;

    echo '</div>';

    // Paginierung
    echo '<div class="pagination">';
    echo paginate_links( array(
        'total'     => $category_query->max_num_pages,
        'current'   => max( 1, get_query_var( 'paged' ) ),
        'prev_text' => __( '&laquo; Zurück' ),
        'next_text' => __( 'Weiter &raquo;' ),
    ) );
    echo '</div>';

    wp_reset_postdata();
endif;
?>

Dieses Beispiel demonstriert mehrere erweiterte Funktionen. Der Parameter category__in ermöglicht es Ihnen, mehrere Kategorie-IDs als Array anzugeben, was bedeutet, dass Beiträge aus allen aufgeführten Kategorien einbezogen werden. ignore_sticky_posts stellt sicher, dass angeheftete Beiträge keine spezielle Behandlung erhalten, es sei denn, Sie wünschen dies explizit. Der Parameter paged ruft die aktuelle Seite aus der URL ab, was für die Paginierung wesentlich ist.

Für eine präzisere Kontrolle können Sie category__and verwenden, wenn Sie nur Beiträge haben möchten, die ALLEN angegebenen Kategorien angehören, nicht nur einer davon:

<?php
$args = array(
    'category__and'     => array( 12, 15 ),
    'posts_per_page'    => 10,
    'orderby'           => 'comment_count',
    'order'             => 'DESC',
);

$query = new WP_Query( $args );

if ( $query->have_posts() ) {
    while ( $query->have_posts() ) {
        $query->the_post();
        // Inhalt anzeigen
    }
    wp_reset_postdata();
}
?>

#Kategorie-Abfrage auf einer statischen Startseite paginieren

Eine eigene Schleife paginiert über paged, das Sie mit get_query_var( 'paged' ) auslesen. Die Ausnahme ist ein Seiten-Template, das als statische Startseite eingestellt ist: Dort legt WordPress die Seitenzahl in der Variable page ab, deshalb verweist die WP_Query-Referenz auf get_query_var( 'page' ). Mit der falschen Variable zeigt jeder Klick auf “weiter” wieder Seite eins.

$paged = ( is_front_page() && is_page() ) ? get_query_var( 'page' ) : get_query_var( 'paged' );
$paged = max( 1, (int) $paged );

$query = new WP_Query( array(
    'category_name'  => 'nachrichten',
    'posts_per_page' => 10,
    'paged'          => $paged,
) );

#Unterkategorien in Abfragen einbeziehen

Eine häufige Frage von Entwicklern ist, wie man Unterkategorien einbezieht, wenn man eine übergeordnete Kategorie abfragt. Bei cat und category_name übernimmt WordPress das selbst: Beide Parameter liefern Beiträge der Kategorie und aller ihrer Unterkategorien. category__in, category__and und category__not_in gleichen dagegen nur die genannten IDs ab. Wer Unterkategorien gezielt ausschließen will, nutzt category__in oder eine tax_query mit include_children auf false.

Die ID-Liste einer Kategorie samt Unterkategorien brauchen Sie trotzdem, sobald die Abfrage nicht über cat läuft, etwa für category__in, für den REST-Parameter categories oder für einen Query-Loop-Block, die Unterkategorien nicht von selbst einbeziehen. Diese Hilfsfunktion sammelt die IDs:

<?php
function get_category_with_children( $category_slug ) {
    $category = get_category_by_slug( $category_slug );

    if ( ! $category ) {
        return array();
    }

    $args = array(
        'taxonomy'     => 'category',
        'child_of'     => $category->term_id,
        'hide_empty'   => true,
    );

    $child_categories = get_categories( $args );
    $category_ids = array( $category->term_id );

    foreach ( $child_categories as $child ) {
        $category_ids[] = $child->term_id;
    }

    return $category_ids;
}

// In WP_Query verwenden
$parent_slug = 'produkte';
$category_ids = get_category_with_children( $parent_slug );

$args = array(
    'category__in'     => $category_ids,
    'posts_per_page'   => 12,
    'orderby'          => 'date',
    'order'            => 'DESC',
);

$products_query = new WP_Query( $args );

if ( $products_query->have_posts() ) {
    while ( $products_query->have_posts() ) {
        $products_query->the_post();
        // Produkte anzeigen
    }
    wp_reset_postdata();
}
?>

Diese Funktion get_category_with_children() nimmt einen übergeordneten Kategorie-Slug, findet über child_of alle Unterkategorien jeder Ebene und gibt ein Array aller Kategorie-IDs zurück. In WP_Query liefert 'cat' => $category->term_id dasselbe Ergebnis mit weniger Code; die Funktion lohnt sich dort, wo eine Schnittstelle Unterkategorien ignoriert. Beachten Sie hide_empty: Eine Unterkategorie ohne eigene Beiträge fällt aus der Liste, auch wenn darunter weitere Ebenen mit Beiträgen liegen. Setzen Sie es auf false, wenn Ihre Hierarchie leere Zwischenebenen hat.

#Welche Kategorie-Parameter Unterkategorien einbeziehen

Dieselbe Kategorie-ID liefert unterschiedliche Beitragslisten, je nachdem, über welche Schnittstelle Sie sie abfragen. Hinter den meisten Meldungen der Art “in der Liste fehlen Beiträge” steckt genau dieses Detail, und die Regeln stehen im Core-Code, nicht in Einstellungen:

SchnittstelleArgumentBeiträge aus Unterkategorien
WP_Querycatenthalten
WP_Querycategory_nameenthalten
WP_Querycategory__in, category__and, category__not_innicht enthalten
WP_Querytax_queryenthalten, außer include_children ist false
get_posts()categoryenthalten (Alias von cat)
REST-APIcategories=5nicht enthalten
REST-APIcategories[terms]=5&categories[include_children]=trueenthalten
Query-Loop-BlockKategoriefilternicht enthalten
WP-CLI--cat, --category_nameenthalten (gehen direkt an WP_Query)

Die WP_Query-Zeilen stammen aus WP_Query::parse_tax_query(): cat wird zu einer Tax Query mit include_children auf true, category__in, category__and und category__not_in werden zu Tax Queries mit include_children auf false. Die WP_Query-Referenz sagt in ihren Beispielen dasselbe: category__in zeigt keine Beiträge aus Unterkategorien. Die Zeile zu get_posts() folgt aus der Funktionsreferenz, die category als Alias von cat beschreibt. Die REST-Zeilen kommen aus dem Posts-Controller, in dem include_children standardmäßig false ist und nur für hierarchische Taxonomien angeboten wird. Die Query-Loop-Zeile kommt aus build_query_vars_from_query_block() in der blocks.php des Cores, die für jeden Taxonomiefilter fest include_children => false setzt.

Die praktische Folge: Ein PHP-Template mit cat => 5 und ein Headless-Frontend, das /wp/v2/posts?categories=5 aufruft, können für dieselbe Elternkategorie verschiedene Beiträge zeigen. Legen Sie fest, welches Verhalten Sie brauchen, und wählen Sie das Argument, das es liefert, statt anzunehmen, dass beide übereinstimmen.

#Kategorien aus Abfragen ausschließen

Ebenso wichtig wie das Einschließen bestimmter Kategorien ist das Ausschließen anderer. WordPress bietet den Parameter category__not_in für diesen Zweck. Dies ist nützlich für Situationen, in denen Sie alle Beiträge ANZEIGEN MÖCHTEN, AUSSER diejenigen, die einer bestimmten Kategorie angehören, beispielsweise um eine „Featured der Woche”-Kategorie von der Hauptliste auszuschließen.

<?php
$args = array(
    'post_type'         => 'post',
    'posts_per_page'    => 10,
    'category__not_in'  => array( 25, 30 ), // Diese Kategorie-IDs ausschließen
    'post_status'       => 'publish',
    'ignore_sticky_posts' => true,
);

$main_query = new WP_Query( $args );

if ( $main_query->have_posts() ) {
    while ( $main_query->have_posts() ) {
        $main_query->the_post();
        // Beitrag anzeigen
    }
    wp_reset_postdata();
}
?>

Ein häufiger Anwendungsfall ist das Ausschließen einer Kategorie von der Startseite:

<?php
if ( is_front_page() ) {
    $args = array(
        'posts_per_page'    => 5,
        'category__not_in'  => array( get_cat_ID( 'featured' ) ),
    );
} else {
    $args = array(
        'posts_per_page'    => 10,
    );
}

$query = new WP_Query( $args );
?>

Ausschließen funktioniert auf zwei Wegen, und beide behandeln Unterkategorien unterschiedlich. Eine negative ID in cat schließt die Kategorie samt Unterkategorien aus, weil der Core eine NOT IN-Tax-Query mit include_children auf true baut. category__not_in schließt nur die genannten Terme aus, Beiträge in einer Unterkategorie erscheinen also weiterhin.

// Schließt Kategorie 12 und alle ihre Unterkategorien aus
$args = array( 'cat' => '-12' );

// Schließt nur Beiträge aus, die direkt in 12 oder 34 liegen
$args = array( 'category__not_in' => array( 12, 34 ) );

Für die Blog-Startseite gibt es eine sauberere Variante als die zweite Abfrage oben: Ändern Sie die Hauptabfrage selbst. Die Referenz zu pre_get_posts empfiehlt genau diese Bedingungen:

add_action( 'pre_get_posts', function ( $query ) {
    if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
        $query->set( 'cat', '-12' );
    }
} );

#Kategoriearchive mit pre_get_posts anpassen

Wenn Sie ändern wollen, welche Beiträge auf den Kategoriearchiven erscheinen, verwenden Sie die Action pre_get_posts statt einer zweiten Abfrage im Template.

function modify_category_queries( $query ) {
    // Nur Kategoriearchive in der Hauptabfrage ändern
    if ( $query->is_category() && $query->is_main_query() && ! is_admin() ) {
        // 20 Beiträge pro Seite statt des Standardwerts
        $query->set( 'posts_per_page', 20 );

        // Auf dem Archiv "featured" die Kategorie-ID 10 ausschließen
        $current_cat = get_queried_object();
        if ( 'featured' === $current_cat->slug ) {
            $query->set( 'category__not_in', array( 10 ) );
        }
    }
}
add_action( 'pre_get_posts', 'modify_category_queries' );

Verwenden Sie im Callback die Methodenversionen der Conditional Tags ($query->is_category(), $query->is_main_query()). Die freien Funktionen prüfen das globale $wp_query und nicht das Abfrageobjekt, das der Hook übergibt, worauf die Hook-Referenz ausdrücklich hinweist.

#Warum query_posts zum Filtern nach Kategorie ungeeignet ist

Ältere Anleitungen setzen query_posts( 'cat=5' ) an den Anfang eines Templates. Der Docblock von query_posts() im Core sagt, dass die Funktion die Hauptabfrage vollständig überschreibt, nicht für Plugins oder Themes gedacht ist und in den meisten Fällen durch die Action pre_get_posts ersetzt werden sollte. Der Funktionskörper ist eine einzige Zeile, die dem globalen $wp_query ein neues WP_Query zuweist. Ein Template läuft nach der Hauptabfrage, der Aufruf wiederholt also die Datenbankarbeit und ersetzt das Objekt, aus dem Paginierung und Conditional Tags lesen. Jede Kategorie-Aufgabe, die query_posts() nutzte, lässt sich mit pre_get_posts (Archiv ändern) oder einem separaten WP_Query (zweite Liste) lösen.

#Wie man Beiträge aus eigenen Taxonomien abruft

Viele WordPress-Installationen verwenden benutzerdefinierte Taxonomien zusätzlich zu Standardkategorien. Beispielsweise könnte eine Website für Bücher eine „Genre”-Taxonomie haben, die ähnlich wie Kategorien funktioniert. Um Beiträge basierend auf benutzerdefinierten Taxonomien abzufragen, müssen Sie den tax_query-Parameter anstelle der regulären Category-Parameter verwenden.

<?php
$args = array(
    'post_type'      => 'buch',
    'posts_per_page' => 12,
    'tax_query'      => array(
        array(
            'taxonomy' => 'genre',
            'field'    => 'slug',
            'terms'    => 'thriller',
            'operator' => 'IN',
        ),
    ),
);

$thriller_books = new WP_Query( $args );

if ( $thriller_books->have_posts() ) {
    while ( $thriller_books->have_posts() ) {
        $thriller_books->the_post();
        // Bücher anzeigen
    }
    wp_reset_postdata();
}
?>

Sie können auch mehrere Taxonomieabfragen mit AND- oder OR-Operatoren kombinieren:

<?php
$args = array(
    'post_type'      => 'buch',
    'posts_per_page' => 20,
    'tax_query'      => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'genre',
            'field'    => 'slug',
            'terms'    => array( 'thriller', 'krimi' ),
        ),
        array(
            'taxonomy' => 'autor',
            'field'    => 'name',
            'terms'    => array( 'Jo Nesbø' ),
            'operator' => 'NOT IN',
        ),
    ),
);

$query = new WP_Query( $args );
?>

#Wie man Kategorie-Abfragen in WordPress beschleunigt

Datenbankabfragen können eine erhebliche Quelle für langsame Ladezeiten auf WordPress-Websites sein, insbesondere wenn Sie viele Beiträge oder komplexe Filter haben. Glücklicherweise gibt es mehrere Techniken, die Sie verwenden können, um Ihre Abfragen zu optimieren und die Belastung der Datenbank zu reduzieren.

Die erste und wichtigste Optimierung besteht darin, zu begrenzen, welche Daten aus der Datenbank abgerufen werden. WordPress ruft standardmäßig alle Beitragsfelder ab, einschließlich Inhalt, Auszüge und aller Metaboxen. Wenn Sie nur Titel und Permalinks benötigen, können Sie Zeit sparen, indem Sie nur diese Felder anfordern:

<?php
$args = array(
    'category_name'    => 'nachrichten',
    'posts_per_page'   => 5,
    'fields'           => 'ids', // Nur Beitrag-IDs
    'no_found_rows'    => true,  // Gesamtzahl der Zeilen nicht zählen
);

$post_ids = get_posts( $args );

foreach ( $post_ids as $id ) {
    $title = get_the_title( $id );
    $link = get_permalink( $id );
    echo '<li><a href="' . esc_url( $link ) . '">' . esc_html( $title ) . '</a></li>';
}
?>

'fields' => 'ids' teilt WordPress mit, dass Sie nur ein Array mit Beitrag-IDs anstelle vollständiger Beitragsobjekte wünschen. 'no_found_rows' => true deaktiviert die Zählung der Gesamtzahl der Treffer. Bei get_posts() ist die Zeile allerdings überflüssig, weil die Funktion no_found_rows ohnehin immer auf true setzt; in einem eigenen WP_Query ohne Paginierung ist sie dagegen eine echte Ersparnis.

Das Argument fields akzeptiert laut WP_Query-Referenz genau drei Werte: all (Standard), ids und id=>parent. Jeder andere Wert, auch ein Array mit Spaltennamen, liefert stillschweigend vollständige Beitragsobjekte. Zwei weitere Schalter sparen Arbeit bei Listen, die nur Titel und Link ausgeben:

$args = array(
    'category_name'          => 'nachrichten',
    'posts_per_page'         => 5,
    'no_found_rows'          => true,  // kein SQL_CALC_FOUND_ROWS, keine Paginierung nötig
    'update_post_meta_cache' => false, // benutzerdefinierte Felder werden nicht ausgegeben
    'update_post_term_cache' => false, // Terme werden nicht ausgegeben
);

no_found_rows verhindert, dass WordPress die Gesamtzahl der Treffer zählt, die es nur für die Paginierung braucht. Die beiden Cache-Flags stehen im Core standardmäßig auf true; laut Referenz muss man sie normalerweise nicht anfassen, doch abgeschaltet sparen sie die zusätzlichen Meta- und Term-Abfragen, wenn die Liste diese Daten nie liest. Lassen Sie sie an, wenn die Schleife Kategorien, Schlagwörter oder benutzerdefinierte Felder ausgibt, denn das Vorladen in einer Abfrage ist günstiger als eine Abfrage pro Beitrag.

#Wie die Transient API Kategorie-Abfragen cached

Für Abfragen, die sich nicht häufig ändern, können Sie die Leistung dramatisch verbessern, indem Sie die Ergebnisse mit der Transient API zwischenspeichern. Dies speichert die Abfrageergebnisse in der Datenbank (oder einem anderen Cache-Backend) für einen bestimmten Zeitraum, sodass Sie vermeiden, dieselbe Abfrage immer und immer wieder auszuführen.

<?php
function get_cached_category_posts( $category_slug, $posts_per_page = 5, $cache_time = HOUR_IN_SECONDS ) {
    $cache_key = 'category_posts_' . $category_slug . '_' . $posts_per_page;
    $cached_posts = get_transient( $cache_key );

    if ( false !== $cached_posts ) {
        return $cached_posts;
    }

    $args = array(
        'category_name'    => $category_slug,
        'posts_per_page'   => $posts_per_page,
        'orderby'          => 'date',
        'order'            => 'DESC',
    );

    $posts = get_posts( $args );

    set_transient( $cache_key, $posts, $cache_time );

    return $posts;
}

// Die gecachte Funktion verwenden
$latest_news = get_cached_category_posts( 'nachrichten', 5, 15 * MINUTE_IN_SECONDS );

foreach ( $latest_news as $post ) {
    setup_postdata( $post );
    echo '<div class="news-item">';
    the_title( '<h3>', '</h3>' );
    the_excerpt();
    echo '</div>';
}
wp_reset_postdata();
?>

Diese Funktion prüft zunächst, ob eine zwischengespeicherte Version der Abfrageergebnisse vorhanden ist. Falls ja, werden sie sofort zurückgegeben, ohne eine neue Abfrage auszuführen. Falls nicht, wird die Abfrage ausgeführt, die Ergebnisse werden mit set_transient() zwischengespeichert und dann zurückgegeben. Der cache_time-Parameter bestimmt, wie lange die Ergebnisse gültig sind, in diesem Beispiel 15 Minuten.

Für fortgeschrittenes Caching, das automatisch invalidiert wird, wenn neue Beiträge veröffentlicht werden, können Sie Hooks hinzufügen:

<?php
function clear_category_posts_cache( $post_id ) {
    // Nur cachen, wenn es ein veröffentlichter Beitrag ist
    if ( get_post_status( $post_id ) !== 'publish' ) {
        return;
    }

    $categories = get_the_category( $post_id );

    foreach ( $categories as $category ) {
        delete_transient( 'category_posts_' . $category->slug . '_5' );
        delete_transient( 'category_posts_' . $category->slug . '_10' );
    }
}

add_action( 'save_post', 'clear_category_posts_cache' );
add_action( 'delete_post', 'clear_category_posts_cache' );
?>

#Shortcodes für Kategorieansichten erstellen

Eine der flexibelsten Möglichkeiten, Kategorieansichten zu implementieren, ist durch WordPress-Shortcodes. Dies ermöglicht es Redakteuren, Kategorielisten einfach zum Inhalt hinzuzufügen, ohne Code schreiben zu müssen.

<?php
function category_posts_shortcode( $atts ) {
    global $post; // Template-Tags lesen das globale $post

    $atts = shortcode_atts( array(
        'category'     => '',
        'limit'        => 5,
        'orderby'      => 'date',
        'order'        => 'DESC',
        'show_date'    => 'yes',
        'show_excerpt' => 'yes',
        'template'     => 'default',
    ), $atts, 'kategorie_posts' );

    if ( empty( $atts['category'] ) ) {
        return '<p class="error">Bitte geben Sie eine Kategorie an.</p>';
    }

    $args = array(
        'category_name'    => $atts['category'],
        'posts_per_page'   => intval( $atts['limit'] ),
        'orderby'          => $atts['orderby'],
        'order'            => $atts['order'],
        'ignore_sticky_posts' => true,
    );

    $posts = get_posts( $args );

    if ( empty( $posts ) ) {
        return '<p>Keine Beiträge in dieser Kategorie gefunden.</p>';
    }

    ob_start();
    ?>
    <div class="category-posts category-posts--<?php echo esc_attr( $atts['template'] ); ?>">
        <?php foreach ( $posts as $post ) :
            setup_postdata( $post );
            ?>
            <article class="category-post-item">
                <h3 class="post-title">
                    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                </h3>
                <?php if ( 'yes' === $atts['show_date'] ) : ?>
                    <time class="post-date" datetime="<?php echo esc_attr( get_the_date( 'c' ) ); ?>">
                        <?php echo esc_html( get_the_date() ); ?>
                    </time>
                <?php endif; ?>
                <?php if ( 'yes' === $atts['show_excerpt'] ) : ?>
                    <div class="post-excerpt">
                        <?php the_excerpt(); ?>
                    </div>
                <?php endif; ?>
            </article>
        <?php endforeach;
        wp_reset_postdata();
        ?>
    </div>
    <?php
    return ob_get_clean();
}

add_shortcode( 'kategorie_posts', 'category_posts_shortcode' );
?>

Jetzt können Redakteure den Shortcode in ihrem Inhalt verwenden:

[kategorie_posts category="nachrichten" limit="5" orderby="date" show_date="yes"]

Für noch mehr Flexibilität können Sie Unterstützung für mehrere Kategorien hinzufügen:

<?php
function advanced_category_shortcode( $atts ) {
    $atts = shortcode_atts( array(
        'categories'   => '',
        'operator'     => 'IN', // IN, AND, NOT IN
        'limit'        => 6,
        'columns'      => 2,
        'show_thumb'   => 'yes',
    ), $atts, 'kategorien' );

    $categories = array_filter( array_map( 'trim', explode( ',', $atts['categories'] ) ) );

    if ( empty( $categories ) ) {
        return '<p class="shortcode-error">Bitte geben Sie mindestens eine Kategorie an.</p>';
    }

    $category_ids = array();
    foreach ( $categories as $cat_slug ) {
        $cat = get_category_by_slug( $cat_slug );
        if ( $cat ) {
            $category_ids[] = $cat->term_id;
        }
    }

    if ( empty( $category_ids ) ) {
        return '<p class="shortcode-error">Ungültige Kategorien angegeben.</p>';
    }

    $args = array(
        'category__in'      => $category_ids,
        'posts_per_page'    => intval( $atts['limit'] ),
        'ignore_sticky_posts' => true,
    );

    if ( 'AND' === $atts['operator'] ) {
        $args['category__and'] = $category_ids;
        unset( $args['category__in'] );
    }

    $query = new WP_Query( $args );

    ob_start();
    ?>
    <div class="posts-grid columns-<?php echo esc_attr( $atts['columns'] ); ?>">
        <?php if ( $query->have_posts() ) :
            while ( $query->have_posts() ) : $query->the_post();
                ?>
                <article class="post-card">
                    <?php if ( 'yes' === $atts['show_thumb'] && has_post_thumbnail() ) : ?>
                        <div class="post-thumbnail">
                            <a href="<?php the_permalink(); ?>">
                                <?php the_post_thumbnail( 'medium', array( 'loading' => 'lazy' ) ); ?>
                            </a>
                        </div>
                    <?php endif; ?>
                    <div class="post-content">
                        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                        <?php the_excerpt(); ?>
                    </div>
                </article>
                <?php
            endwhile;
            wp_reset_postdata();
        endif; ?>
    </div>
    <?php
    return ob_get_clean();
}

add_shortcode( 'kategorien', 'advanced_category_shortcode' );
?>

#AJAX-Laden von Kategoriebeiträgen

Für große Websites mit vielen Beiträgen kann AJAX-Laden eine viel bessere Benutzererfahrung bieten, indem weitere Beiträge asynchron geladen werden, ohne die Seite neu zu laden. Dies ist besonders nützlich für „Mehr laden”-Funktionalität.

Zuerst registrieren Sie das JavaScript:

<?php
function enqueue_category_ajax_scripts() {
    wp_enqueue_script(
        'category-ajax',
        get_template_directory_uri() . '/js/category-ajax.js',
        array( 'jquery' ),
        '1.0',
        true
    );

    wp_localize_script( 'category-ajax', 'categoryAjax', array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
        'nonce'   => wp_create_nonce( 'category_ajax_nonce' ),
    ) );
}

add_action( 'wp_enqueue_scripts', 'enqueue_category_ajax_scripts' );
?>

Dann erstellen Sie den AJAX-Handler:

<?php
function load_more_category_posts() {
    check_ajax_referer( 'category_ajax_nonce', 'nonce' );

    $page = isset( $_POST['page'] ) ? intval( $_POST['page'] ) : 1;
    $category = isset( $_POST['category'] ) ? sanitize_text_field( $_POST['category'] ) : '';
    $posts_per_page = isset( $_POST['posts_per_page'] ) ? intval( $_POST['posts_per_page'] ) : 6;

    $args = array(
        'category_name'    => $category,
        'posts_per_page'   => $posts_per_page,
        'paged'            => $page,
        'post_status'      => 'publish',
    );

    $query = new WP_Query( $args );

    if ( $query->have_posts() ) :
        while ( $query->have_posts() ) : $query->the_post();
            get_template_part( 'template-parts/post', 'card' );
        endwhile;
        wp_reset_postdata();
    endif;

    wp_die();
}

add_action( 'wp_ajax_load_category_posts', 'load_more_category_posts' );
add_action( 'wp_ajax_nopriv_load_category_posts', 'load_more_category_posts' );
?>

JavaScript für die Handhabung der „Mehr laden”-Schaltfläche:

jQuery(document).ready(function($) {
    var currentPage = 1;
    var isLoading = false;
    var hasMore = true;

    $('.load-more-category').on('click', function(e) {
        e.preventDefault();

        if (isLoading || !hasMore) return;

        var $button = $(this);
        var category = $button.data('category');
        var postsPerPage = $button.data('posts-per-page') || 6;

        isLoading = true;
        $button.addClass('loading').text('Lädt...');

        $.ajax({
            url: categoryAjax.ajaxurl,
            type: 'POST',
            data: {
                action: 'load_category_posts',
                nonce: categoryAjax.nonce,
                page: currentPage + 1,
                category: category,
                posts_per_page: postsPerPage
            },
            success: function(response) {
                if (response.trim()) {
                    $('.posts-grid').append(response);
                    currentPage++;
                } else {
                    hasMore = false;
                    $button.hide();
                }
            },
            error: function() {
                alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
            },
            complete: function() {
                isLoading = false;
                $button.removeClass('loading').text('Mehr laden');
            }
        });
    });
});

#Welche Fehler bei Kategorie-Abfragen häufig sind

Selbst erfahrene WordPress-Entwickler stoßen regelmäßig auf Probleme bei der Arbeit mit Kategorieabfragen. Hier sind die häufigsten Probleme und ihre Lösungen.

Problem: Leere Ergebnisse, obwohl Beiträge vorhanden sind. Dies liegt oft daran, dass post_status nicht korrekt eingestellt ist. Standardmäßig zeigt WP_Query nur veröffentlichte Beiträge an, aber wenn Sie in einer Entwicklungsumgebung testen, können Beiträge den Status „Entwurf” oder „Ausstehend” haben.

<?php
// Alle veröffentlichten Beiträge anzeigen
$args = array(
    'category_name' => 'nachrichten',
    'post_status'   => 'publish',
);

// Zum Testen: Alle Beiträge anzeigen, unabhängig vom Status
$test_args = array(
    'category_name' => 'nachrichten',
    'post_status'   => array( 'publish', 'draft', 'pending', 'private' ),
);
?>

Problem: Beiträge werden mit falscher Kategorie angezeigt. Prüfen Sie, ob Sie den richtigen Parameter verwenden. category_name nimmt einen Kategorie-Slug (Zeichenfolge), während cat eine Kategorie-ID (ganze Zahl) nimmt. Ein häufiger Fehler ist, cat mit einer Zeichenfolge zu verwenden oder umgekehrt.

<?php
// Falsch - cat erwartet eine Zahl
$args = array( 'cat' => 'nachrichten' ); // Funktioniert nicht!

// Richtig - category_name nimmt eine Zeichenfolge
$args = array( 'category_name' => 'nachrichten' );

// Richtig - cat nimmt eine Zahl
$args = array( 'cat' => 42 ); // Angenommen, 42 ist eine gültige Kategorie-ID

// Kategorie-ID zuerst prüfen
$category = get_category_by_slug( 'nachrichten' );
if ( $category ) {
    $args = array( 'cat' => $category->term_id );
}
?>

Problem: Angeheftete Beiträge werden zuerst angezeigt. Laut WP_Query-Referenz schiebt ignore_sticky_posts mit dem Standardwert false angeheftete Beiträge an den Anfang der Ergebnismenge. Mit true erscheinen sie an ihrer natürlichen Position, mit zusätzlichem post__not_in verschwinden sie ganz. Achtung: post__in mit der Liste der angehefteten Beiträge würde die Abfrage auf genau diese Beiträge beschränken, nicht sie hinzufügen.

<?php
$args = array(
    'category_name'         => 'nachrichten',
    'ignore_sticky_posts'   => true, // Angeheftete Beiträge ignorieren
    'posts_per_page'        => 10,
);

// Alternative: Angeheftete Beiträge ganz aus der Kategorieliste entfernen
$args = array(
    'category_name'         => 'nachrichten',
    'ignore_sticky_posts'   => true,
    'post__not_in'          => get_option( 'sticky_posts' ),
    'posts_per_page'        => 10,
);
?>

Problem: Paginierung funktioniert nicht. Dies ist ein sehr häufiges Problem, das oft auf eine fehlerhafte Konfiguration des paged-Parameters zurückzuführen ist oder dass WP_Query nicht korrekt mit der Hauptschleife verwendet wird.

<?php
// Korrekte Paginierung in WP_Query
$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;

$args = array(
    'category_name'    => 'nachrichten',
    'posts_per_page'   => 10,
    'paged'            => $paged,
);

$query = new WP_Query( $args );

if ( $query->have_posts() ) :
    while ( $query->have_posts() ) : $query->the_post();
        // Beitrag anzeigen
    endwhile;

    // Paginierung
    echo paginate_links( array(
        'total'   => $query->max_num_pages,
        'current' => $paged,
    ) );

    wp_reset_postdata();
endif;
?>

#Benutzerdefinierte Templates für Kategorieansichten

WordPress ermöglicht es Ihnen, benutzerdefinierte Templates für bestimmte Kategorien zu erstellen, was Ihnen die volle Kontrolle darüber gibt, wie Beiträge aus verschiedenen Kategorien angezeigt werden.

Erstellen Sie eine Datei in Ihrem Theme-Ordner mit dem Namen category-{slug}.php, wobei {slug} der Kategorie-Slug ist. Beispielsweise erstellen Sie für die Kategorie „nachrichten” die Datei category-nachrichten.php. In dieser Datei können Sie eine vollständig angepasste Ansicht erstellen:

<?php
/**
 * Archiv-Template für die Kategorie mit dem Slug "nachrichten",
 * die Template-Hierarchie wählt es über den Dateinamen aus
 */

get_header();

$category = get_category_by_slug( 'nachrichten' );
?>

<div class="news-archive">
    <header class="archive-header">
        <h1><?php echo esc_html( $category->name ); ?></h1>
        <?php if ( category_description( $category->term_id ) ) : ?>
            <div class="archive-description">
                <?php echo wp_kses_post( category_description( $category->term_id ) ); ?>
            </div>
        <?php endif; ?>
    </header>

    <div class="news-grid">
        <?php
        $news_args = array(
            'cat'            => $category->term_id,
            'posts_per_page' => 12,
            'paged'          => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
        );

        $news_query = new WP_Query( $news_args );

        if ( $news_query->have_posts() ) :
            while ( $news_query->have_posts() ) : $news_query->the_post();
                ?>
                <article class="news-item">
                    <?php if ( has_post_thumbnail() ) : ?>
                        <div class="news-thumbnail">
                            <a href="<?php the_permalink(); ?>">
                                <?php the_post_thumbnail( 'medium_large', array( 'loading' => 'lazy' ) ); ?>
                            </a>
                        </div>
                    <?php endif; ?>
                    <div class="news-content">
                        <span class="news-date"><?php echo get_the_date(); ?></span>
                        <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                        <?php the_excerpt(); ?>
                    </div>
                </article>
                <?php
            endwhile;
            wp_reset_postdata();
        else :
            ?>
            <p class="no-news">Keine Nachrichten gefunden.</p>
        <?php endif; ?>
    </div>

    <?php if ( $news_query->max_num_pages > 1 ) : ?>
        <nav class="pagination">
            <?php
            echo paginate_links( array(
                'total'   => $news_query->max_num_pages,
                'current' => max( 1, get_query_var( 'paged' ) ),
                'format'  => '?paged=%#%',
                'prev_text' => '&laquo; Zurück',
                'next_text' => 'Weiter &raquo;',
            ) );
            ?>
        </nav>
    <?php endif; ?>
</div>

<?php get_footer(); ?>

#Wie man Kategorien mit Meta und Taxonomien kombiniert

Oft müssen Sie die Kategoriefilterung mit anderen Kriterien wie benutzerdefinierten Feldern, Suchbegriffen oder Autorschaft kombinieren. WordPress WP_Query unterstützt all diese Kombinationen durch meta_query und andere Parameter.

<?php
$args = array(
    'post_type'      => 'event',
    'posts_per_page' => 10,
    'category__in'   => array( get_cat_ID( 'konferenzen' ), get_cat_ID( 'workshops' ) ),
    'meta_query'     => array(
        'relation' => 'AND',
        array(
            'key'     => 'event_datum',
            'value'   => date( 'Y-m-d' ),
            'compare' => '>=',
            'type'    => 'DATE',
        ),
        array(
            'key'     => 'event_ort',
            'value'   => 'Berlin',
            'compare' => '=',
        ),
    ),
    'orderby'        => 'meta_value',
    'meta_key'       => 'event_datum',
    'order'          => 'ASC',
);

$events = new WP_Query( $args );

if ( $events->have_posts() ) {
    while ( $events->have_posts() ) {
        $events->the_post();
        // Event anzeigen
    }
    wp_reset_postdata();
}
?>

#Wie man Kategorien über die REST-API abruft

In modernen Webanwendungen mit Astro, Next.js oder mobilen Apps werden WordPress-Beiträge häufig über die integrierte REST-API konsumiert:

  • Effiziente Filterung über Endpunkte: Der Endpunkt /wp/v2/posts?categories=12 liefert Beiträge einer spezifischen Kategorie direkt als JSON-Objekt aus. Durch den Parameter _fields=id,title,slug,date,excerpt lässt sich die Nutzlast drastisch reduzieren, da unnötige Metadaten gar nicht erst über das Netzwerk übertragen werden.
  • Embedded-Daten für Beitragsbilder: Um zusätzliche API-Aufrufe für Autorenprofile und Beitragsbilder zu vermeiden, sorgt der Parameter _embed dafür, dass verknüpfte Medienobjekte direkt im Haupt-Payload eingebettet ausgeliefert werden.
  • Edge-Caching für REST-Antworten: Mit einem vorgeschalteten CDN und passenden Cache-Control-Headern beantwortet der Edge-Cache wiederholte Anfragen, ohne dass WordPress die Abfrage erneut ausführt.

Drei Details aus dem REST-Handbuch entscheiden, ob eine Headless-Liste vollständig ist:

  • Unterkategorien brauchen die Objektform. categories=5 trifft nur den Term 5. Um seine Unterkategorien einzuschließen, senden Sie categories[terms]=5&categories[include_children]=true. Dasselbe Objekt akzeptiert categories[operator]=AND, wenn ein Beitrag alle genannten Terme tragen muss.
  • Eine Seite liefert höchstens 100 Einträge. Der Paginierungsleitfaden begrenzt per_page auf Werte von 1 bis 100. Lesen Sie die Antwort-Header X-WP-Total und X-WP-TotalPages aus und fordern Sie page=2, page=3 an, bis alles da ist.
  • _fields versteht verschachtelte Schlüssel. Seit WordPress 5.3 akzeptiert der Parameter _fields Pfade wie meta.event_datum, eine Liste kann also einen registrierten Meta-Schlüssel ohne das ganze Meta-Objekt anfordern. WordPress berechnet die nicht angeforderten Felder dann gar nicht, was auch die Antwortzeit verkürzt.

#Wie WPGraphQL Kategorie-Abfragen für Headless liefert

Für Frontends, die viele verknüpfte Daten in einem Aufruf brauchen, ist das Plugin WPGraphQL eine Alternative zur REST-API:

  • Vermeidung von Over-Fetching und Under-Fetching: Mit einer einzigen GraphQL-Abfrage lassen sich Kategorie-Metadaten, verknüpfte Beiträge, Tags und Beitragsbilder in genau der benötigten Struktur anfordern, ohne mehrere HTTP-Rundreisen zu initiieren.
  • Cursor-basierte Paginierung: Statt Seitennummern übergibt der Client den Cursor des zuletzt geladenen Eintrags, was sich für unendliches Scrollen (Infinite Scroll) eignet.

#Datenbank-Optimierung und Vermeidung von N+1-Abfrageproblemen

Auf stark besuchten Kategorieseiten entscheiden Details der Datenbankabfrage über die Serverlast:

  • Einsatz von update_post_meta_cache: Wenn in einer Kategorie-Schleife benutzerdefinierte Felder (Post Meta) benötigt werden, sollte der Parameter update_post_meta_cache auf true belassen werden. Dadurch lädt WordPress alle Metadaten für alle Beiträge der Schleife in einem einzigen SQL-Query vorab in den Speicher, anstatt pro Beitrag eine separate Datenbankabfrage auszulösen.
  • Objekt-Caching mit Redis: Komplexe Taxonomie-Abfragen sollten stets durch einen persistenten Redis Object Cache abgesichert sein. Dadurch werden wiederkehrende Abfragen direkt aus dem RAM bedient und belasten die relationale MySQL-Datenbank nicht.

#Gutenberg Query Loop Block in modernen Full Site Editing (FSE) Themes

In Block-Themes stellen Redakteure Kategorielisten ohne PHP zusammen:

  • Visuelle Konfiguration ohne PHP-Code: Der native core/query-Block (Abfrageschleife) erlaubt es, Beitragslisten direkt im Site-Editor nach Kategorien, Schlagwörtern und Autoren zu filtern. Entwickler können wiederverwendbare Block-Patterns vordefinieren, sodass Marketing-Mitarbeiter eigenständig ansprechende Kategorieseiten gestalten können.
  • Template-Hierarchie für Block-Themes: In reinen Block-Themes steuern HTML-Vorlagen wie category.html oder spezialisierte Vorlagen wie category-nachrichten.html das Layout. Die Vorlagen liegen als Dateien im Theme und lassen sich wie PHP-Templates mit Git versionieren.

Der Kategoriefilter des Blocks trifft nur die ausgewählten Terme. Der Core wandelt ihn in eine Tax Query mit include_children auf false um, eine ausgewählte Elternkategorie zieht also keine Beiträge nach, die nur in ihren Unterkategorien liegen; nehmen Sie die Unterkategorien zusätzlich in den Filter auf.

#Beiträge einer Kategorie mit WP-CLI auflisten

Für Audits, Migrationen und einmalige Exporte führt wp post list dasselbe WP_Query auf der Kommandozeile aus. Jede Option --<feld>=<wert> geht als Argument an WP_Query, die Kategorie-Regeln aus der Tabelle oben gelten also unverändert:

# Term-ID und Beitragszahl jeder Kategorie
wp term list category --fields=term_id,name,slug,count

# Veröffentlichte Beiträge in "nachrichten" und ihren Unterkategorien als CSV
wp post list --category_name=nachrichten --post_status=publish --fields=ID,post_title,post_date --format=csv

# Nur IDs, Beiträge direkt in Kategorie 12 (ohne Unterkategorien)
wp post list --category__in=12 --post_status=publish --format=ids

# Wie viele Beiträge ein Template für Kategorie 12 samt Unterkategorien zeigt
wp post list --cat=12 --post_status=publish --format=count

Zwei Standardwerte weichen von einer Template-Schleife ab. Der Quellcode des Befehls setzt posts_per_page auf -1 und post_status auf any, ohne --post_status=publish enthält die Ausgabe also auch Entwürfe, ausstehende und private Beiträge. Die Standardspalten sind ID, post_title, post_name, post_date und post_status, und --format akzeptiert table, csv, ids, json, count und yaml. Ein Vergleich von --format=count für --cat und --category__in mit derselben ID zeigt schnell, wie viele Beiträge nur in Unterkategorien liegen.

#get_posts() oder WP_Query für Kategorie-Listen

Das Abrufen und Anzeigen von Beiträgen aus Kategorien in WordPress ist eine grundlegende Fähigkeit, die alle Entwickler beherrschen sollten. Die wichtigsten Punkte zu beachten sind:

Für einfache Listen ohne Paginierungsbedarf ist get_posts() die beste Wahl aufgrund der Einfachheit und weil es die Hauptschleife nicht beeinflusst. Für komplexe Ansichten mit Paginierung und erweiterten Filtern ist WP_Query das bevorzugte Werkzeug. Vermeiden Sie query_posts(), es sei denn, Sie müssen explizit die Hauptschleife modifizieren.

Optimierung ist entscheidend für große Websites. Verwenden Sie 'fields' => 'ids', wenn Sie nur IDs brauchen, no_found_rows, wenn Sie die Gesamtzahl der Ergebnisse nicht benötigen, und die Transient API zum Zwischenspeichern der Ergebnisse. Für dynamische Websites sollten Sie AJAX-Laden für eine bessere Benutzererfahrung in Betracht ziehen.

Denken Sie immer daran, die Beitragdaten mit wp_reset_postdata() zurückzusetzen, nachdem Sie WP_Query oder get_posts() verwendet haben, und validieren und bereinigen Sie alle Benutzereingaben, um Sicherheitsprobleme zu vermeiden.


#Häufige Fragen zu Kategorie-Abfragen in WordPress

Wie rufe ich Beiträge aus mehreren Kategorien gleichzeitig ab?

Sie können den category__in-Parameter mit einem Array von Kategorie-IDs verwenden. Zum Beispiel: 'category__in' => array( 12, 15, 18 ). Dies zeigt Beiträge an, die mindestens einer der aufgeführten Kategorien angehören. Wenn Sie Beiträge möchten, die ALLEN Kategorien angehören, verwenden Sie stattdessen category__and.

Wie beziehe ich Unterkategorien in die Abfrage ein?

Mit cat oder category_name geschieht das automatisch, beide Parameter schließen Unterkategorien ein. category__in tut es nicht. In der REST-API brauchen Sie die Objektform categories[terms]=5&categories[include_children]=true, im Query-Loop-Block müssen Sie die Unterkategorien selbst auswählen.

Wie paginiere ich die Ergebnisse einer benutzerdefinierten Abfrage?

Verwenden Sie WP_Query mit dem paged-Parameter, der auf get_query_var( 'paged' ) gesetzt ist. Verwenden Sie dann die Funktion paginate_links() mit max_num_pages aus der Abfrage. Beachten Sie, dass die Paginierung von WP_Query unabhängig von der Hauptschleife ist.

Wie cache ich Kategorieabfragen für bessere Leistung?

Verwenden Sie die WordPress Transient API. Speichern Sie die Abfrageergebnisse mit set_transient() und rufen Sie sie mit get_transient() ab. Setzen Sie eine passende Ablaufzeit basierend darauf, wie oft der Inhalt aktualisiert wird. Denken Sie daran, den Cache zu invalidieren, wenn neue Beiträge veröffentlicht werden.

Wie schließe ich bestimmte Beiträge von der Kategorieansicht aus?

Verwenden Sie den post__not_in-Parameter mit einem Array von Beitrag-IDs, die Sie ausschließen möchten. Sie können auch category__not_in verwenden, um ganze Kategorien von der Abfrage auszuschließen.

Nächster Schritt

Machen Sie aus dem Artikel eine echte Umsetzung

Dieser Block stärkt die interne Verlinkung und führt Nutzer gezielt zum nächsten sinnvollen Schritt im Service- und Content-System.

Soll das Thema auf Ihrer Website umgesetzt werden?

Wenn Sie aus dem Artikel konkrete Maßnahmen für Website, Relaunch oder Weiterentwicklung ableiten wollen, definiere ich den Scope und setze ihn um.

Relevanter Cluster

Weitere WordPress-Dienste und Wissensbasis entdecken

Stärken Sie Ihr Unternehmen mit professionellem technischen Support in den Kernbereichen des WordPress-Ökosystems.

Ähnliche Artikel