WordPress & Webwork

WordPress: erster Artikel lang, der Rest gekürzt

Eine recht häufige Frage von WordPress-Nutzern ist nach der individuellen Strukturierung des Loops: also der Ausgabe der Artikel. So kam auch in Rahmen meiner Aktion Frag den WordPress-Experten, die Frage wie man den Loop bzw. die Ausgabe der Artikel so anpasst, dass der erste Artikel in voller Länge oder als Auszug und der Rest entweder als Auszug oder lediglich als anklickbare Überschrift aufgelistet wird. Dabei sollte es natürlich keine Doubletten geben.

Hier eine mögliche Lösung:

<h2>Loop 1</h2>
<div class="erster-artikel">
<?php
    query_posts("showposts=1");
    $ids = array();
    while (have_posts()) : the_post();
    the_title();
    the_excerpt();
    $ids[]= $post->ID;
    endwhile;
?>
</div>

<h2>Loop 2</h2>
<ul>
<?php
    query_posts("showposts=9");
    while (have_posts()) : the_post(); ?>
    <?php if (!in_array($post->ID, $ids)) { ?>
    <li><?php the_title(); ?></li>
    <?php } endwhile;
?>
</ul>

Mit Hilfe des Template-Tags query_posts holt man sich die entsprechende Anzahl an Artikeln und setzt die ID des Artikel ein Array. Im zweiten Abschnitt holt man sich wieder per query_posts die gewünschte Anzahl an Artikel, aber es werden nur die aufgelistet, die nicht (if (!in_array($post->ID, $ids))) zu dem oben definierte Array dazugehören.

Verbesserungsvorschläge und Optimierungstipps bzw. Alternativen sind herzlich willkommen.

13 Reaktion(en)

  1. Pingback: Tweets that mention Peruns Weblog -- Topsy.com

  2. Eddie

    Hi,

    ginge es nicht auch über die Offset-Variable:


    <h2>Loop 1</h2>
    <div class="erster-artikel">
    <?php
    query_posts("showposts=1");
    while (have_posts()) : the_post();
    the_title();
    the_excerpt();
    endwhile;
    ?>

    und dann für Loop 2


    <h2>Loop 2</h2>
    <ul>
    <?php
    query_posts("offset=2");
    while (have_posts()) : the_post();
    ?>
    <li><?php the_title(); ?<>/li>
    <?php endwhile;
    ?>

    Gruß,
    Eddie

  3. Micha

    Am einfachsten geht das mit einem Zähler. Man braucht keine 2 queries. Hier mal ne Schnellversion:

    if(have_posts()):
      $i = 0;
      while (have_posts()) : the_post();
        $i++;
        if($i === 1):
          the_title()
          the_excerpt();
        else:
          the_title();
        endif;
      endwhile;
    endif;
  4. Perun

    @Micha,

    super, kürzer geht es kaum :-)

    @Frank,

    das ist PHP for Runaways :-)

    @Edie,

    offset=3 überspringt die ersten zwei Beiträge (einer Kategorie) und zeigt erst ab dem dritten Beitrag an

    da steht etwas von der gleichen bzw. einer Kategorie und das passt nicht zu der oberen Fragestellung.

  5. Wolf Larsen

    Danke Perun, Dein Weblog ist immer sehr interessant. Viel habe ich von Dir, Micha, Monika oder Frank schon angewendet. Bei dem Code weiß ich nun aber nicht mehr richtig weiter. Deshalb habe ich hier einen Tread mit meiner jetzigen Schleife eröffnet: http://forum.wordpress-deutschland.org/konfiguration/63365-erster-artikel-lang-der-rest-auszug.html Vielleicht hat jemand einen feinen Tipp parat.

    Wolf

  6. Ralf

    Ich würde es auch wie Micha machen, jedoch eine Bedingung hinzufügen:

    $counter = 1;
    $numFullposts = 3;
    
    if(have_posts()):
      while(have_posts() : the_post()
        if($counter =< $numFullposts):
          the_title();
          the_excerpt();
        else:
            the_title();
        endif;
      $counter++;
      endwhile;
    endif;

    So kann man dann z.B. die ersten 3 Beiträge komplett anzeigen und den Rest gekürzt. Ist ggf. etwas flexibler.

  7. Pingback: WordPress: erster Artikel lang, der Rest gekürzt (2) | Peruns Weblog

  8. Eddie

    @Perun
    Das mit der Kategorie steht in Klammern und bezieht sich darauf, dass das auch innerhalb einer Kategorie funktioniert, wenn man den cat=xy-Parameter übergeben hat.

    Also nicht das Auslassen der ersten beiden Beiträge aus der Liste aller Beiträge, sondern wenn man nur eine(zwei, x) Kategorie(n) ausgeben will auch das Auslassen der ersten beiden Beiträge aus der Liste der Beiträge dieser Kategorie(n).

    Kürzer: Das Auslassen der ersten n-1 Beiträge des Queries mit dem Parameter offset=n.

    Auf der engl. Codex-Seite sthet nichts mehr von Kategorien, sondern nur, dass die angegebene Anzahl an Beträgen übersprungen/ausgelassen wird:
    http://codex.wordpress.org/…]#Offset_Parameter

  9. Eddie

    Das mit den zwei Loops kann manchmal praktisch sein, wenn man die Liste mit den folgenden Einträgen an einer anderen Stelle positionieren möchte.

    Ansonsten ist die kürzere Methode natürlich sehr viel einfacher.

    Viele Grüße,
    Eddie

  10. Ralf

    @Eddie: Ich habe es gerade ausprobiert. Geht zwar, jedoch nicht mit n-1, sondern mit n. Also offset=1 überspringt den ersten Beitrag; offset=2 überspringt die ersten beiden Beiträge.

    Die Liste an "anderer Stelle" ausgeben? Wo? Also wenn die "andere Stelle" auf der gleichen Seite ist, dann würde ich es unbedingt mit CSS machen. Wenn die "andere Stelle" auf einer anderen Seite liegt, macht es wenig Sinn.
    Wenn die "andere Stelle" z.B. sich im Footer befindet, könnte man dir bedingt Recht geben.

    Aber! Man darf nicht vergessen das aus Sicht einer guten Performance alles bisher gesagte Mumpitz ist. In der Loop werden jedesmal die kompletten Artikel übertragen, mit allem Drum&Dran, mit allem Brimborium. Also Überschrift, Metadaten, Text, Excerpt, Bilder usw. usf. Davon verwendet wird am Ende jedoch lediglich ein Bruchteil (der Titel bzw. Titel & Excerpt).
    Wer sich mit MySQL beschäftigt, lernt recht schnell das "SELECT *" böse ist. Man soll nur die Daten abfragen, die man benötigt. Deswegen wäre für die zweite Loop auf alle Fälle eine Abfrage über die MySQL-Klasse von WP zu bevorzugen.

    Demnach wäre etwa folgendes optimaler:
    1. Loop wie gehabt.

    2. Loop:

    $secondPosts = $wpdb->get_results("SELECT ID,post_date
    FROM $wpdb->posts
    WHERE post_status='publish'
    ORDER BY post_date DESC
    LIMIT 2,5");
    if($secondPosts){
    echo "[ol]";
    foreach($secondPosts as $post){
    $permaLink = get_permalink($post->ID);
    $theTitle = get_the_title($post->ID);
    echo '[li][a href="'.$permaLink.'"]'.$theTitle.'[/a][/li]';
    }
    echo "[/ol]";
    }
    else echo "[h2]Leeres Ergebnis...[/h2]";

    Damit wird wirklich nur ein Minimum an Daten abgefragt, was bei Blogs mit sehr langen Texten bzw. großen Fotos einiges an Ressourcen und somit Zeit (bzw. Serverlast) einspart.
    Hat man hingegen ein Blog mit wenig Grafiken/Fotos und relativ kurzen Texten, sind die bisher genannten Wege genauso effektiv.

  11. Eddie

    @Ralf
    das stimmt natürlich mit dem Überspringen der n Beiträge bei offset=n. Hab da was durcheinander gebracht :-)
    Meinte eigentlich das der n+1. Beitrag angezeigt wird.

Die Kommentare in diesem Beitrag sind geschlossen.