smart | Webentwicklung
Alles rund um HTML5, PHP, WordPress & Co.

WordPress Pagination erstellen (ohne Plugin)

18. Juli 2012
Stephan
WordPress-Pagination ohne Plugin erstellen

Da ich in diesem Blog gerade die Pagination überarbeitet habe, möchte ich euch nicht vorenthalten, wie ihr selbst in eurem Blog bzw. in eurem WordPress-Theme eine Pagination ohne Installation eines zusätzlichen Plugins einbinden könnt.

Da WordPress von Haus aus nur zwei Links zum Seitenumblättern anbietet, ist es ratsam eine Pagination-Funktion in eurem Theme zu integrieren, da es gewisse Vorteile mit sich bringt. Beispielsweise kann durch Einsatz einer Pagination eine bessere Benutzerfreundlichkeit für eure Leser und eine verbesserte interne Verlinkung erreicht werden.

Was ist eine Pagination?

Dabei handelt sich einfach gesagt, um die Möglichkeit zwischen verschiedenen Seiten hin- und herzublättern. Wie ihr z.B. auf der Startseite dieses Blog sehen könnt, befindet sich unter der Auflistung der 5 neuesten Blog-Artikel eine Liste mit nummerierten Seitenzahlen, die es euch als Leser ermöglichen, direkt auf eine andere Seite zu “springen„.

Pagination-Beispiel - Startseite Smart-Webentwicklung

Code zum Erstellen der Pagination

Den folgenden Code für die Pagination-Funktionalität könnt ihr so wie er ist in eure functions.php einfügen:

function pagination($range = 3, $show_one_pager = true, $show_page_hint = false)
{
    global $wp_query;
    $num_of_pages = (int)$wp_query->max_num_pages;

    if(!is_single() && $num_of_pages > 1)
    {
        $current_page = get_query_var('paged') === 0 ? 1 : get_query_var('paged');
        $num_of_display_pages = ($range * 2) + 1;        

        $output = '<div id="pagination">';

        if($show_page_hint)
        {
            $output .= '<span>Seite ' . $current_page . ' von ' . $num_of_pages . '</span>';
        }
		
		if($current_page > 2 && $current_page > $range + 1 && $num_of_display_pages < $num_of_pages)
		{
			$output .= '<a href="' . get_pagenum_link(1) . '" title="Seite 1 - Neueste Artikel">«</a>';
		}
		if($show_one_pager && $current_page > 1)
		{
			$output .= '<a href="' . get_pagenum_link($current_page - 1) . '" title="Seite ' . ($current_page - 1) . ' - Neuere Artikel">‹</a>';
		}

		for($i = 1; $i <= $num_of_pages; $i++)
		{
			if($i < $current_page + $range + 1 && $i > $current_page - $range - 1)
            {
				if($current_page === $i)
				{
					$output .= '<span class="current">' . $i . '</span>';
				}
				else
				{
					$output .= '<a href="' . get_pagenum_link($i) . '" title="Seite ' . $i . '" >' . $i . '</a>';
				}
            }
		}
		
		if($show_one_pager && $current_page < $num_of_pages)
		{
			$output .= '<a href="' . get_pagenum_link($current_page + 1) . '" title="Seite ' . ($current_page + 1) . ' - Ältere Artikel">›</a>';
		}
		if($current_page < $num_of_pages - 1 && $current_page + $range < $num_of_pages && $num_of_display_pages < $num_of_pages)
		{
			$output .= '<a href="' . get_pagenum_link($num_of_pages) . '" title="Seite ' . $num_of_pages . ' - Älteste Artikel">»</a>';
		}

		$output .= '</div>';

        return $output;
    }
}

Update: Der Code in Zeile 13 – 16 wurde als Ergänzung zu meinem unten stehenden Kommentar hinzugefügt.

Den dazugehörigen CSS-Code zum Anpassen des Designs der Pagination lasse ich hier weg, da je nach Theme ihr die Pagination sowieso individuell designen könnt.

Erklärung des Codes im Detail

Im Folgenden eine kurze Erklärung zu den jeweiligen Codezeilen:

Zeile 4:
Wir weisen $num_of_pages die Anzahl der Seiten zu.
Zeile 6:
Die Pagination nur anzeigen, wenn die aktuelle Seite keine “Single-Page„ ist und mehr als 1 Seite vorhanden ist.
Zeile 8:
Der Variable $current_page wird die aktuelle Seite zugewiesen. Dabei ist zu beachten, dass wenn die aktuelle Seite die Seite 1 ist, die Funktion get_query_var('paged') 0 zurückliefert.
Zeile 9:
$num_of_display_pages wird die Anzahl der anzuzeigenden Seitenlinks zugewiesen. Dabei gibt $range an, wie viele Seitenlinks links bzw. rechts nebst dem Seitenlink der aktuellen Seite (maximal) angezeigt werden.
Zeile 13 – 16:
Wenn die Variable $show_page_hint wahr ist (true), dann geben wir den Hinweis aus, dass der Leser sich gerade auf „Seite X von Y“ befindet. X ist dabei die aktuelle Seite und Y die Anzahl aller Seiten.
Zeile 18 – 21:
Es wird ein Seitenlink auf der erste Seite (auf der die neuesten Artikel eures Blogs gelistet sind) angezeigt, wenn folgende Bedingungen erfüllt sind:

  • die aktuelle Seite entspricht weder Seite 1 noch Seite 2
  • die aktuelle Seite ist größer als $range + 1
  • die Anzahl der anzuzeigenden Seitenlinks ist kleiner als die Gesamt-Seitenanzahl

Zeile 22 – 25:
Es wird ein Seitenlink auf die vorherige Seite der aktuellen Seite angezeigt, wenn folgende Bedingungen erfüllt sind:

  • $show_one_pager ist true
  • die aktuelle Seite ist nicht die erste Seite (Seite 1)

Zeile 27 – 40:
In einer for-Schleife durchlaufen wir alle Seiten. In Zeile 29 überprüfen wir dann, ob für die jeweilige Seite ($i) ein Seitenlink angezeigt wird. Dabei gilt die Bedingung, dass die Seite sich innerhalb der anzuzeigenden „Seitenrange“ ($range) befinden muss. Wenn das der Fall ist, dann geenrieren wir den dazugehörigen Seitenlink, außer wenn es sich um die aktuelle Seite handelt, da wir dann einfach nur ein <span>-Element ausgeben.
Zeile 42 – 49:
Verhält sich analog zu dem Code aus Zeile 18 – 25:
Zeile 53:
Wir geben unsere generierte Ausgabe ($output) zurück.

Anzeigen der Pagination

Um die Pagination nun in eurem WordPress-Blog anzuzeigen, müsst ihr am Ende eurer sogenannten „WordPress-Loop“, die sich bei vielen Themes in der loop.php befindet (je nach Theme kann das aber abweichen), Folgendes einfügen:

echo pagination();

Über die Parameter $range, $show_one_pager und $show_page_hint könnt ihr die Anzeige der Pagination anpassen.

Beispiele:

Pagination mit $range = 2:

echo pagination(2);

Pagination-Beispiel 1

Pagination mit $range = 2 und $show_one_pager = false:

echo pagination(2, false);

Pagination-Beispiel 2

Pagination mit $range = 2, $show_one_pager = true und $show_page_hint = true:

echo pagination(2, true, true);

WordPress Pagination-Beispiel 3

Fazit

Wir ihr sehen könnt, lässt sich in WordPress eine Pagination-Funktionalität sehr einfach erstellen und ins Theme integrieren ohne, dass extra ein zusätzliches Plugin benötigt wird.

Nutzt ihr in eurem Blog auch eine Pagination? Wenn ja – mit oder ohne Plugin? Habt ihr eventuell auch schon eine eigene Pagination für WordPress erstellt?

Kommentare  
34 Kommentare vorhanden
1 Kathryn Dolling schrieb am 18. Juli 2012 um 18:23 Uhr

Herzlichen Dank für diesen Tipp, das werde ich die Tage in der Sandbox mal ausprobieren. Ich selber nutze dafür bis jetzt ein Plugin, aber ich würde dieses gerne ersetzen (bin da eher Minimalistin).

2 Stephan L. schrieb am 19. Juli 2012 um 11:55 Uhr

Hallo Kathryn,

danke für deinen Kommentar! 🙂

Falls du die Pagination so haben möchtest wie auf deiner angegebenen Website (Schnaeppchenfund) mit der Anzeige „Seite 1 von X“ ist das auch schnell erledigt. Dazu einfach den Code nach Zeile 11 und vor Zeile 13 wie folgt anpassen:

$output .= '<span>Seite ' . $current_page . ' von ' . $num_of_pages . '</span>';

Edit: Habe den Artikel dahingehend mal aktualisiert (siehe Zeile 13 – 16).

Grüße Stephan

3 Marco schrieb am 30. September 2012 um 11:46 Uhr

Ein nicht nur inhaltlich sehr schöner Artikel! Kein geschwafel, Infos pur und der Code sicht zudem auch noch schick aus.

Da ich gerade dabei bin mein eigenes Theme zu programmieren und so viel wie möglich nativ implementiere, wird diese „Pagination“ im Feldtest ihre Chance bekommen.

Vielen Dank!

4 Stephan L. schrieb am 30. September 2012 um 12:54 Uhr

Hallo Marco,

freut mich, dass dir der Artikel gefällt und weiterhilft. Falls im Rahmen deines Tests noch Probleme/Fragen bzgl der Pagination auftauchen, dann schreib mir einfach! 😉

Gruß Stephan

5 Marco schrieb am 30. September 2012 um 13:35 Uhr

Wird gemacht Stephan 😉

6 Nicksi schrieb am 27. Oktober 2012 um 11:04 Uhr

Vielen Dank, läuft sehr gut 🙂

7 Viktor schrieb am 5. November 2012 um 15:34 Uhr

Hallo Stephan,
hab zwar andere Variante genutzt, aber deine scheint mir besser zusein.
Danke.Getauscht und Repostet.
MfG
Viktor

8 Stephan T. schrieb am 8. Januar 2013 um 10:50 Uhr

Hallo.
Danke für den Artikel. Er hat mir schon mal Erkenntnisse geliefert, die ich für die Lösung eines Problems benötige.
Leider stecke ich fest.
Die Verweise der index Seite meiner HP führen immer wieder auf die gleichen Inhalte zurück – die aktuellsten Artikel.

Ich dachte zuerst es liegt an der Pagination, denke aber nun das es am Link bzw. der Linkstruktur liegt.

Suche nun schon eine ganze Weile, finde aber nicht den richtigen Ansatz.

Kennt du einen Artikel der gut beschreibt wie der Inhalt der Seiten mit den älteren Posts zusammengestellt wird?

Gruß
StephanT.

9 Stephan L. schrieb am 11. Januar 2013 um 11:08 Uhr

An der Pagination scheint es nicht zu liegen. Auf deinen Tag(Schlagwort)-Seiten funktioniert die Pagination. Kann es sein, dass du im index.php-Template einen individuellen Query (irgendwas mit z.B. query_posts) drin hast, der immer nur die aktuellsten Artikel ausgibt?

Gruß Stephan

10 Karsten Zarth schrieb am 20. Januar 2013 um 21:05 Uhr

Hi Stephan,

ich habe als WP-Neuling begonnen ein Child-Theme zu erstellen, läuft auch alles super, nur mein Parent-Theme (twentytwelve) hat gar keine loop.php. Kannst du mir sagen, wo ich statt dessen den 2. Codeabschnitt (den zum Anzeigen der Pagination) unterbringen müsste?

Gruß

Karsten

11 Stephan L. schrieb am 20. Januar 2013 um 21:22 Uhr

Hey Karsten,

beim Twenty Twelve Theme einfach anstatt loop.php die content.php-Datei bearbeiten:

Ersetze:

wp_link_pages( array( 'before' => '<div class="page-links">' . __( 'Pages:', 'twentytwelve' ), 'after' => '</div>' ) )

durch:

echo pagination();

Dann sollte die Pagination auch in deinem Theme angezeigt werden. 😉

Gruß

Stephan

12 Karsten Zarth schrieb am 20. Januar 2013 um 22:17 Uhr

Nachtrag: Wenn ich den Code zur Anzeige der Pagination in mein eigenes News-Template (news.php, das hat ja auch eine Loop) einfüge, passiert rein gar nichts. Ich weiß echt nicht, was ich falsch mache…

Gruß

Karsten

13 Karsten Zarth schrieb am 20. Januar 2013 um 22:30 Uhr

Hab ich gemacht, genauer durch echo pagination(2, true, true); da passiert rein gar nichts.

14 Stephan L. schrieb am 21. Januar 2013 um 09:57 Uhr

Also ich habs bei mir ausprobiert mit Twenty Twelve Theme und klappt einwandfrei. Hast du denn auch in deine functions.php den eigentlichen Code für die Pagination eingefügt?

15 Karsten Zarth schrieb am 23. Januar 2013 um 11:52 Uhr

Ja, ich hab’s heute nochmal ausprobiert. Und zwar in der functions.php meines Childthemes; die wird doch, soweit ich weiß, mit der functions.php des Parentthemes zusammengeschmissen, will sagen: vereint.

Und in der content.php von Twenty Twelve hab ich den code (echo pagination(2, true, true);) eingefügt. Da ist nichts zu machen im Moment leider. Angezeigt wird mir immer noch keine Pagination.

16 Karsten Zarth schrieb am 23. Januar 2013 um 12:49 Uhr

Habe grad mal die content.php leergemacht; die Seiten News und Mitarbeiter funktionierten trotzdem noch. Vielleicht liegt es daran, dass ich für jede Seite ein eigenes Template gemacht habe und ich müsste in diese Templates den Code für die Pagination einbinden.

Hier mal meine beiden Templates:

employees.php

<?php
/*
Template Name: Mitarbeiter
*/
get_header();
?>
<div class="mitarbeiter">
    <h2>Mitarbeiter</h2>
    <?php $mitarbeiter = new WP_Query( array( 'post_type' => 'mitarbeiter', 'paged' => $paged ) ); ?>
    <?php if ($mitarbeiter->have_posts()) : ?>
    <div class="mitarbeiter-box">
        <?php while ($mitarbeiter->have_posts()) : $mitarbeiter->the_post(); ?>
        <div id="post-<?php the_ID(); ?>" class="mitarbeiter-thumbnail">
            <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?><div class="title"><?php the_title(); ?></div></a>
        </div>
        
        <?php endwhile; ?>
        
    </div>
    <?php endif; ?>
</div>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

news.php:

<?php
/*
Template Name: News
*/
get_header();
?>

<div class="news">
    <h2>News</h2>
    <?php $news = new WP_Query( array( 'post_type' => 'news', 'paged' => $paged ) ); ?>
    <?php if ($news->have_posts()) : ?>
    <div class="news-box">
        <?php while ($news->have_posts()) : $news->the_post(); ?>
        <?php
			global $more;
			$more = 0;
		?>

        <div id="post-<?php the_ID(); ?>" class="news-thumbnail">
            <a href="<?php the_permalink(); ?>"><?php if(has_post_thumbnail()){ the_post_thumbnail('thumbnail'); } ?>
            <div class="title"><?php the_title(); ?></div></a>
			<div class="content"><?php the_content('weiterlesen'); ?></div>
        </div>

        
        <?php endwhile; ?>
        
    </div>
    <?php endif; ?>
    
</div>



<?php get_sidebar(); ?>
<?php get_footer(); ?>
17 Stephan L. schrieb am 23. Januar 2013 um 15:53 Uhr

Hey Karsten,

sry dann hatte ich dich wohl falsch verstanden oder nicht richtig gelesen. In deinem Fall hat content.php dann wirklich nichts damit zu tun. Hab egedacht du rufst innerhalb deines News-Template das Content-Template auf.

Im Normalfall müsstest du dann einfach in deinem News-Template die Pagination aufrufen. Wie das mit der functions.php bei Child-Themes ist kann ich dir um ehrlich zu sein gar nicht wirklich sagen, da ich bis jetzt noch nicht mit Child-Themes gearbeitet habe.

Ansonsten kannst du mir auch dein Child-Theme mal per Mail (kontakt@smart-webentwicklung.de) schicken und ich schau kurz drüber, woran es hapert.

Gruß Stephan

18 Max schrieb am 14. Februar 2013 um 15:31 Uhr

Ich arbeite ebenfalls derzeit an einem eigenen Theme. Ich benutze Seitentemplates und Kategorie-Templates – In beiden wird leider nichts angezeigt, trotz der Platzierung vor dem endif; des Loops.

Hat hier jemand eine Idee? Der Functions.php-Teil steht natürlich in der Functionsfile. Ich komm nicht mehr weiter. Auch eine normale Anzeige von „ältere Artikel“ oder „neuere Artikel“ funktioniert nicht.

19 Dennis H schrieb am 7. März 2013 um 14:05 Uhr

Hallo Stephan,

Zunächst mal vielen Dank für das tolle Tutorial, hat direkt auf Anhieb geklappt mit der Integration. Eine Frage hätte ich allerdings trotzdem:

Ich habe einen u.a. Custom Post Type namens „Tänze“ und würde die Anzahl der Einträge in archive-taenze.php gerne anpassen, also nicht auf die max_num_pages von WordPress zurückgreifen. Gibt’s eine Möglichkeit, der Funktion eine bzw. mehrere Ausnahmen für diesen CPT hinzuzufügen oder den Wert direkt über archive-taenze zu manipulieren? Habe bereits mehrere Plugins probiert (Custom Limit Posts etc.) und die „posts_per_page“ in einem angepassten Query geändert, aber geholfen hat davon leider nichts. Hast du vlt. eine Idee wie man das lösen könnte?

Viele Grüße

20 Stephan L. schrieb am 7. März 2013 um 15:28 Uhr

Hi Dennis,

da fällt mir jetzt auf die Schnelle leider auch nichts passendes ein. Das Custom Limit Posts klingt doch aber eigentlich genau nach dem was du suchst – und das funktioniert nicht damit?

Grüße

Stephan

21 Dennis H schrieb am 7. März 2013 um 16:03 Uhr

Leider werden meine CPT’s (über functions.php erstellt) nicht vom Plugin erkannt, ich kann leider nur für die WordPress-Standartseiten eigene Werte angeben. Ich werde mich aber später nochmal dahinterklemmen wenn ich mehr Zeit habe und bei Bedarf meine Lösung hier posten.

Grüße

22 Dennis H schrieb am 7. März 2013 um 18:32 Uhr

Habe es hinbekommen. Offensichtlich gibt es einen Bug in WP, der hier genauer beschrieben wird: http://ilikekillnerds.com/2012/11/fixing-wordpress-404-custom-post-type-archive-pagination-issues-with-posts-per-page/

Nachdem ich den dort genannten Code in der functions.php hinzugefügt habe ging deine Pagination auch im Custom Post Type mit einer eigenen Anzahl an Posts 🙂

23 Stephan L. schrieb am 7. März 2013 um 18:57 Uhr

Da muss man auch erst mal drauf kommen, dass scheinbar ein WordPress-Bug dran Schuld ist. Aber wer weiß: Was aus Sicht des Nutzers ein Bug ist, war vielleicht aus Sicht der Entwickler ein gewolltes Feature. ;P

Danke dir, dass du die Lösung für dein Problem hier noch mal gepostet hast! 😉

24 Dennis H schrieb am 7. März 2013 um 19:08 Uhr

Da sagt du was! Ist mein erstes Projekt mit WordPress und ich habe so gut wie keine PHP/MySQL-Kenntnisse. Und wenn dann solche Fehler auftreten ist das harter Tobak 😉

Zu erwähnen sei noch, dass ich in allen Templates nun einen angepassten Query einbauen musste, erst dann haben alle Unterseiten mit der Pagination funktioniert. Dieser musste (!) so aussehen, die Argumente über ein array($args) zu übergeben hat nicht funktioniert:

query(’showposts=20&post_type=POSTTYPENAME&orderby=title&order=ASC‘.’&paged=‘.$paged);
?>

Grüße

25 Rachid schrieb am 21. März 2013 um 12:12 Uhr

Herzlichen Dank für diesen schlichten aber sehr hilfreichen Artikel!

26 Ola schrieb am 2. Mai 2013 um 11:36 Uhr

Hallo Stephan,

vielen Dank für diese leicht verständliche Anleitung!
Mit Hilfe deines HowTo’s konnte ich endlich eine numerische Seiten-Navigation in unsere kleine LG Optimus 4X HD-Fanpage integrieren.

Danke & Gruß
Ola

27 Stephan L. schrieb am 5. Mai 2013 um 13:48 Uhr

Hallo Ola,

schön, dass ich dir mit dem Artikel weiterhelfen konnte.

Du hast die Pagination vom Aussehen her ja auch gleich super in dein Blog-Design integriert! 🙂

Grüße

Stephan

28 Ola schrieb am 6. Mai 2013 um 10:55 Uhr

Hi Stephan,

danke für dein Lob, was die Einbindung in das Blog-Design betrifft! 😉

Eine Frage hätte ich da noch an Dich:
Gibt es die Möglichkeit diese Pagination auch in die Kommentar-Seiten einzubauen? Wenn ja, dann wäre es super wenn du ein Tutorial dazu machen könntest.

Danke & Gruß
Ola

29 Stephan L. schrieb am 7. Mai 2013 um 14:49 Uhr

Hallo Ola,

puh, also ohne Anpassungen des Codes wird das für die Kommentarseiten nicht funktionieren.

Ich würde dir jetzt einfach zum Einsatz der paginate_comments_links-Funktion raten.

In deinem Theme-Verzeichnis müsste sich in deiner comments.php irgendwo ein Eintrag mit previous_comments_link und next_comments_links finden. Den Eintrag bzw. die entsprechenden Zeilen kannst du dann mit der paginate_comments_links-Funktion ersetzen. Die angezeigte Pagination weicht dann zwar ein wenig von der Artikel/Post-Pagination ab, aber funktioniert tadellos. 🙂

Grüße

Stephan

30 Ola schrieb am 7. Mai 2013 um 18:10 Uhr

Super Tipp, Stephan – Danke Dir!

Hab’s hinbekommen und per CSS an deine Artikel/Post-Pagination angepasst.
Hier ist ein Beispiel: http://goo.gl/uKUwH

Danke nochmal & Gruß
Ola

31 Michael schrieb am 19. Februar 2014 um 12:04 Uhr

Hi , Di eseitenzahl ist super .

leider hab eich das Problem das ich 6 Seiten habe : Es steht Seite 1 von 6 udn daneben werden aber nur die ersten 3 Seiten angezeigt.

Kann ich gleich von anfang an das 6 Seiten statt 3 Seiten angezeigt werden bzW alle Seiten

32 Sam schrieb am 12. August 2014 um 16:23 Uhr

Hallo Stephan vielen Dank für den Code-Schnippsel! Ich habe ihn auch prompt in meiner Seite verwertet, allerdings wird mir für jede Blogseite (von Seite 1 bis 27) immer die gleichen 5 Artikel angezeigt. Muss ich neben dem einbinden in die functions.php und der Ausgabe in meiner Blog-Page (home.php) noch etwas beachten?

Ich habe in meiner Loop zwar ein WP_Query, aber das sortiert nur nach ‚post_type‘ => ‚post‘.. mehr nicht 🙁

33 Edelmut Struth schrieb am 23. April 2015 um 09:39 Uhr

Hab auch das Problem gehabt, dass 25 Beiträge mit posts_per_page=3 –> 9 Seiten ergeben, ab wp_query nur die ersten 3 Seiten mit Inhalt füllt, ab Seite 4 wird nicht angezeigt. Die Lösung: wp_query bekommt die Anzahl der Beiträge pro Seite vom Dashboard > Einstellungen > lesen. Dort steht Beiträge gleich 10. Diese sind nur noch zu ändern nach seinen Wünschen.

34 Sascha schrieb am 23. März 2016 um 10:43 Uhr

Super übersichtlicher und verständlicher Code. Dazu kurz und präzise erklärt. Genau mein Ding 🙂 vielen Dank!

2 Trackbacks/Pingbacks vorhanden
Du bist herzlich eingeladen auch ein Kommentar zu hinterlassen!
Kommentar schreiben

Vielen Dank für dein Kommentar!