Sticky Posts auf Category-Listen

Das Sticky-Post-System von WordPress ist ein wenig komisch. Sticky Posts sind Posts, die immer oben gehalten werden auf der Startseite. Eigentlich sollte man erwarten, dass die zentrale Eigenschaft dieser Posts ist, dass sie oben sind. Weit gefehlt.

Die zentrale Eigenschaft dieser Posts ist es, dass sie auf der Startseite oben sind. Sonst gar nichts. In den Category-Listen sind sie dagegen brav einsortiert nach Datum. Wenn man WordPress als Mini-CMS nutzt und die Kategorien nutzt, um auf verschiedenen Bereichen der Seite News anzuzeigen nervt das ganz schön – weil man auf verschiedenen Bereichen der Seite oben gehaltene Posts haben will. Was tun? Ein hässlicher Hack.

Verbunden habe ich dies mit der Eigenschaft der Startseite, nur Posts einer einzigen Kategorie anzuzeigen. So können Inhalte sehr spezifisch dahin gesteuert werden, wo man sie hinhaben möchte. Um die Eigenarten der Sticky Posts zu erläutern zunächst ein paar Beispiele wie es nicht geht. Als Basis fand ich diesen Post.

function my_post_queries( $query ) {
// only homepage and is the main query
if ($query->is_home() && $query->is_main_query()){
// display only posts in category with id=32
$query->set('cat', 32);
// avoid sticky posts
$query->set('post__not_in', get_option( 'sticky_posts' ) );
}
}
add_action( 'pre_get_posts', 'my_post_queries' );

Das erste $query->set sorgt dafür, dass alle Posts mit der Kategorie-ID 32 angezeigt werden – und zusätzlich alle Sticky Posts mit beliebiger Kategorie. Wenn man das zweite $query->set dazunimmt, bekommt man alle Posts mit der Kategorie-ID 32 – ausser die Posts, die Sticky Posts sind. Ich wollte aber alle Posts mit Kategorie 32, egal, ob Sticky Post oder nicht. Und die Sticky Posts sollten dann auch noch oben sein. Das ist mit dem normalen Query-System von WordPress aber schlichtweg nicht möglich. Zeit für einen hässlichen Hack:

add_action('pre_get_posts', 'modify_main_query');
function modify_main_query( $query ) {
  if ($query->is_main_query()) {
    $query->set('post__not_in', get_option( 'sticky_posts' ) );
    if ($query->is_home()) {
      $query->set('cat', 32);
    }
    else if ($query->is_category()) { }
  }
}

add_action('wp', 'add_sticky_posts');
function add_sticky_posts() {
  global $wp_query;
  $args = array( 'post__in' => get_option( 'sticky_posts' ), 'ignore_sticky_posts' => 1 );
  if (is_home())
    $args['cat'] = 32;
  else if (is_category())
    $args['cat'] = $wp_query->query_vars['cat'];
  else
    return;
  $sticky_post_query = new WP_Query($args);
  $wp_query->posts = array_merge($sticky_post_query->posts, $wp_query->posts);
}

Was habe ich gemacht? Ich habe zunächst alle Sticky Posts herausgefiltert und auf der Startseite nur nach Kategorie-ID 32 gesucht. Die Sticky Posts habe ich anschließend gesucht – und dabei ihre Eigenschaft als Sticky Posts zwar als Bedingung genommen, aber in der Positionierung ignoriert. Anschliessend habe ich die Sticky Posts einfach vor die anderen Posts eingesetzt.

Das ganze ist ein ziemlich hässlicher Hack, aber er funktioniert und dürfte auch recht stabil sein. Hässlich ist er vor allem deshalb, weil die restlichen Daten im $wp_query Objekt dem ursprünglichen Query entsprechen, dies aber nicht mehr der Realität von $wp_query->posts entspricht.

2 Antworten zu “Sticky Posts auf Category-Listen”

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.