toscho.design
Redaktion, Druck- und Webdesign aus Halle (Saale)

WordPress: Alle Artikel auflisten

WordPress AAA

Vielleicht habe ich mehr Nutzen aus dieser Seite gezogen als meine Leser: Alle Artikel auf einen Blick – das finde ich immer wieder hilfreich, wenn ich mal an meine interne Verlinkung denke.

Und so geht es:

  • Wir legen eine neue PHP-Datei ins Templateverzeichnis und nennen sie ›_all_files.php‹.
  • Dann besorgen wir uns das praktische Skript sorttable.
  • Und zuletzt brauchen wir noch die Funktion end_on_word().
  • Auswahl der Vorlage ›Alle Artikel‹Jetzt legen wir im Backend eine neue Seite an und wählen als Vorlage ›Alle Artikel‹ aus. Ein bißchen Text hinschreiben, veröffentlichen. Fertig.
<?php
/* Template Name: Alle Artikel
 *
 * Onlinebeispiel: http://toscho.de/uebersicht/alle-artikel/
 * Diese Seite als ›_all_files.php‹ im Themeverzeichnis speichern und beim
 * Erstellen einer neuen Seite als Vorlage verwenden.
 */
get_header();

// Text über der Tabelle. Inhalt einer normalen Seite (Page).
if ( have_posts() )
{
    while ( have_posts() )
    {
        the_post();
        the_title('<h1>', '</h1>');
        the_content('<p><strong>Weiterlesen …</strong></p>');
        link_pages('<p><strong>Seiten:</strong> ', '</p>', 'number');
        edit_post_link('Beitrag bearbeiten', '<p>', '</p>');
    }
}

/**
 * @var object $myQuery Liste aller Artikel.
 */
$myQuery = new WP_Query(
    array(
        'nopaging'    => true,
        'post_type'   => 'post',
        'post_status' => 'publish'
    )
);

if ( $myQuery->have_posts() )
{
?>
<table id="allposts" class="sortable">
  <thead>
    <tr>
      <th scope="col">Titel</th>
      <th scope="col">Datum</th>
      <th scope="col">Kommentare</th>
    </tr>
  </thead>
  <tbody>
<?php
    while ( $myQuery->have_posts() )
    {
        $post = $myQuery->next_post();
?>
    <tr>
      <td><a href="<?php the_permalink(); ?>" title="<?php
        if ( !empty($post->post_excerpt) )
        {
            $_my_excerpt = $post->post_excerpt;
            // Für Browser, die keinen Umbruch im Tooltip zeigen:
            $_my_excerpt = str_replace("\r\n", " \r\n ", $_my_excerpt);
            $_my_excerpt = strip_tags($_my_excerpt);
            $_my_excerpt = htmlspecialchars($_my_excerpt, ENT_QUOTES);
        }
        else
        {
            $_my_excerpt = substr( $post->post_content, 0, 100);
            $_my_excerpt = str_replace("\r\n", " \r\n ", $_my_excerpt);
            $_my_excerpt = strip_tags($_my_excerpt);
            $_my_excerpt = htmlspecialchars($_my_excerpt, ENT_QUOTES);
// ANPASSEN!
            // @see http://toscho.de/2009/php-funktion-end_on_word/
            $_my_excerpt = XWP::end_on_word($_my_excerpt) . '&#160;…';
        }
        echo $_my_excerpt;
        ?>"><?php
        the_title();
        ?></a>
        </td>
        <td sorttable_customkey="<?php
        // YYYYMMDDHHMMSS - damit das Javascript nach Datum sortieren kann.
        echo str_replace(array('-', ' ', ':'), '', $post->post_date);
        ?>"><?php
        the_time('d.m.Y');
        ?></td>
        <td><?php
        if ( 'open' == $post->comment_status && 0 < $post->comment_count )
        {
        /**
         * Das Title-Attribut hilft den Nutzern von Screenreadern, gleich-
         * lautende Links (mit nur einer Zahl als Text) zu unterscheiden. */
            echo '<a href="' . get_permalink() . '#comments"'
            . ' title="Kommentiere ›' . $post->post_title . '‹">'
            . $post->comment_count . '</a>';
        }
        else
        {
        /* Leere Zellen werden sonst anders dargestellt, und per CSS
         * läßt sich das nicht sehr zuverlässig reparieren. */
            echo '&#160;';
        }
        ?>
      </td>
    </tr>
<?php
    }
?>
  </tbody>
</table>
<?php
}
else
{// == !$myQuery->have_posts()
    ?><p>Irgendwas läuft gerade entsetzlich schief …</p><?
}
rewind_posts();

// ANPASSEN!
?>
<script src="http://js.toscho.de/sorttable.js" type="text/javascript"></script>
<?php
get_footer();

CSS

Das Auge sortiert mit; also habe ich noch ein, zwei Regeln ins Stylesheet gehämmert:

table
    {
        margin:             1em 0;
        border-collapse:    collapse;
        border-spacing:     0;
        page-break-inside:  avoid;
        background:         #fff;
    }
td,
th
    {
        padding:            .2em .3em;
        border:             1px solid #bbb;
        vertical-align:     top;
        font-size:          1em;
    }
th,
caption
    {
        font-weight:        bold;
    }
tbody tr:nth-child(even)
    {
        background:         #f4f4f4;
    }
tr:nth-child(1n+0) > *
    {
        border-width:       0 1px;
    }

/*  Liste aller Artikel */
.sortable th
    {
        cursor:             pointer;
    }
.sortable th.sorttable_nosort
    {
        cursor:             text;
    }
#allposts
    {
        margin-left:        0;
    }
#allposts td:first-child
    {
        width:              100%;
    }
#allposts a
    {
        text-decoration:    none;
    }
#allposts a:hover
    {
        text-decoration:    underline;
    }
#allposts tr:nth-child(1n+0)
    {
        border:             0;
    }
#allposts tr:nth-child(1n+0) td,
#allposts tr:nth-child(1n+0) th
    {
        border-width:       0;
        padding:            .2em .4em;
    }
#allposts tbody tr:hover
    {
        outline:            1px solid #999;
    }
#allposts th:last-child
    {
        min-width:          3em;
    }
#allposts td:last-child
    {
        text-align:         right;
    }
#allposts td:first-child a
    {
        display:            block;
    }
#allposts td:last-child a
    {
        display:            block;
    }

Nicht sehr effizient, ich weiß. Nach dem nächsten Redesign wird das sicher besser aussehen.

15 Kommentare

  1. Frank am 06.01.2010 15:22:

    Ich nutze eine kleine Übrgabe an den Loop, mache aber auch keine Tabelle darus und dann ist es recht schlank, auch für NichtPHPler zu lesen, denke ich.

    
    <ul>
    <?php
    query_posts("posts_per_page=-1");
    if (have_posts()) : while (have_posts()) : the_post(); ?>
    	<li><small>#<?php the_ID(); ?>, <?php the_time('m/y') ?> </small> <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link zu <?php echo htmlentities( get_the_title() ); ?>"><?php the_title(); ?></a> <small>(<?php comments_number('0','1','%');?>)</small></li>
    <?php endwhile; ?>
    </ul>
    
  2. [asterix] am 06.01.2010 16:24:

    Sehr praktisch vielen Dank. Ich denke, ich werde das bei gelegenheit auch auf meinem Blog einbauen.

  3. Struppi am 06.01.2010 18:44:

    In dem zusammenhang hatte ich, soweit ich mich erinnere, schon einmal meine Version von sorttable angepriesen. Damit sparst du den customkey, da es auch mit dem deutschen Zeitformat zurecht kommt. Und es ist darüber hinaus, um einiges schneller. http://javascript.jstruebig.de/javascript/74/

  4. Thomas Scholz am 06.01.2010 19:24:

    @Struppi: Danke, das sehe ich mir am Wochenende mal genau an.
    Ich habe eigentlich vor, beim nächsten Redesign all meine lose zusammengestückelten Scripte zugunsten jQuerys aufzugeben; deshalb habe ich mich um Ersatz bisher nicht weiter gekümmert, obwohl mir die Grenzen meiner aktuell verwendeten Skripte durchaus bewußt sind.

    Bei deinem Skript irritiert mich die separate ltrim.js: Sie prüft nicht, ob der Browser das schon nativ kann; und warum das zwei getrennte Dateien sind oder sein müssen, verstehe ich auch nicht so recht. Naja, das kriege ich auch selber noch raus. ☺

  5. [asterix] am 06.01.2010 20:13:

    jQuery lädt beim Benutzer mit seinen 50 Kilobytes (komprimierte Version) aber auch nicht gerade schnell. Das war für mich bisher der einzige Grund, es nicht zu verwenden.

    Bedeutend interessanter finde ich dagegen schon «midori JS», da dieses unkomprimiert nur zwanzig Kilobytes auf die Waage bringt. Ich habe mir dieses Framework jedoch noch nicht genauer angeschaut und nehme an, es kann aufgrund seiner leichtheit nicht mit denselben Funktionen auftrumpfen wie jQuery.

    Schade.

  6. Thomas Scholz am 06.01.2010 20:47:

    @[asterix]: Ich werde jQuery ohnehin aus dem Google-CDN einbinden. Dave Ward hat dazu mal einen guten Artikel geschrieben: 3 reasons why you should let Google host jQuery for you.
    Gerade beim Publikum dieses Blogs habe ich gute Chancen, daß die Datei schon im Cache des Lesers liegt.

    Ansonsten ist es bei jQuery wie bei WordPress: Sicher hat es auch Nachteile, aber ich habe die größte Auswahl an Plugins und Informationen, was es mir wiederum erleichtert, das bestmögliche Ergebnis für meine Leser hinzustellen.

  7. Struppi am 08.01.2010 10:06:

    Du hast recht, als ich das Skript geschrieben hatte wußte ich noch nicht, dass manche Browser die trim Funktionen in ihren Wortschatz aufnehmen wollen. Aber das sind sowieso nur ein paar Zeilen, die natürlich auch in sort_table eingebaut werden könnte. Es müssen also nicht zwei getrennte Dateien sein, es dient einfach nur der wiederverwendbarkeit.

  8. David am 22.03.2010 14:36:

    Wenn ich das so nutze, wirft the_permalink() mir immer den Link zur Aktuellen Seite zurück und nicht den, der innerhalb des neuen Loops zu sehen sein sollte. Dito für the_title().
    Nur echo get_permalink($post->ID) liefert das gewünschte Ergebnis. Allerdings sieht diese Methode so aus, als würde da jedes mal noch einmal eine DB-Anfrage losgelassen. Warum steht der Permalink eigentlich nicht in $post->permalink?

  9. Thomas Scholz am 22.03.2010 14:54:

    @David: the_permalink() ist nur ein Container für get_permalink():

    function the_permalink() {
          echo apply_filters('the_permalink', get_permalink());
    }

    Ich würde hier zunächst vermuten, daß du irgendeinen Filter auf 'the_permalink' sitzen hast, der die Ausgabe verändert. Ein Plugin oder ein unausgereifter Hack in der functions.php vielleicht.

    Warum steht der Permalink eigentlich nicht in $post->permalink?

    Weil man Informationen zur Adresse nicht immer braucht, wenn man mit dem Post-Objekt arbeitet – das auch eine Seite oder ab Version 3.0 ein Menupunkt sein kann. Die »Umrechnung« geschieht also nur dann, wenn der Bedarf klar feststeht.

  10. David am 22.03.2010 19:32:

    Weil man Informationen zur Adresse nicht immer braucht,

    Der Shortlink steht doch auch drin?

    Egal, get_permalink() funktioniert auch nur dann, wenn ich manuel die ID mitgebe. Filter sind definitiv keine drauf.

    Wenn ich es herausgefunden habe, sag ich bescheid.

  11. Thomas Scholz am 23.03.2010 00:04:

    @David: Der Shortlink steht nicht drin – nur die unvermeidliche Post-ID, aus der man die Short-URI bilden kann.

    Falls du es brauchst oder einer der anderen Leser:

    print_r $GLOBALS['wp_filter']

    … liefert alle Filter. Eine erschreckend lange Liste, aus der man aber doch einiges lernen kann.

  12. David am 01.04.2010 19:44:

    @David: Der Shortlink steht nicht drin – nur die unvermeidliche Post-ID, aus der man die Short-URI bilden kann.

    Was ist dann $post->guid? Dort steht bei mir genau der Shortlink drin.

  13. Thomas Scholz am 02.04.2010 10:30:

    @David: Du hast recht; das hatte ich komplett übersehen.

  14. David am 02.04.2010 14:04:

    Und auch wieder nicht. Denn dort steht der Shortlink (so ein unsinniges Wort) drin, wie er zum Zeitpunkt der Veröffentlichung geheißen hat. Nach einem Umzug auf eine andere Domain ist das Feld nicht mehr zu gebrauchen. Ich frage mich, wozu das überhaupt da ist. Ein Permalinkfeld, dass die Request-URI speichert würde ich für sinnvoller halten.

    Egal, angenehmes Oster-Wochenende allerseits.

  15. dueddel am 07.09.2010 08:23:

    Super, danke!

    Für WordPress-Unerfahrene wie mich, die vorher nicht wussten, wie man überhaupt eigene Templates baut, ein schneller und unkomplizierter Weg ans Ziel.
    Ich habe zwar keine Artikelliste, sondern eine Übersicht für Kategorien gemacht, aber der Denkanstoß war der richtige.

    Viele Grüße nach Halle.
    Arvid

Was sagst du dazu?

RSS-Feed für diese Kommentare · Hinweise zum Datenschutz
Nur das ist Pflicht, der Rest … nicht.
Bitte maskiere < und > mit und , sonst werden sie gefressen.