WordPress Inhaltsverzeichnis automatisch erstellen – ohne Plugin!

WordPress Inhaltsverzeichnis automatisch erstellen – ohne Plugin! Thumbnail
Veröffentlicht am 19. Mai 2020Zuletzt aktualisiert am 3. November 2020

Bei vielen WordPress Blog-Einträgen oder Seiten kann ein Inhaltsverzeichnis wahre Wunder wirken und dem Besucher einen schnellen Überblick über die Gliederung der Inhalte geben.

Anzeige

Es ist einfach zu umständlich ein Inhaltsverzeichnis in jedem Beitrag neu zu erstellen oder bei Änderungen zu aktualisieren. Für so eine „Kleinigkeit“ ein Plugin (z.B. Easy Table Of Contents) zu installieren ist auch keine gute Lösung, da es die Seite nur langsamer macht und man es – wie Du gleich sehen wirst – auch ganz einfach selber coden kann.

Falls Du keine oder wenig Programmiererfahrung hast, kannst Du dieses Inhaltsverzeichnis trotzdem verwenden. Das ist kein Problem! Falls noch Fragen offen bleiben, kann ich auch über die Kommentare versuchen Hilfestellung zu geben.

So wird unser Endergebnis aussehen:

Den kompletten Code habe ich selbst programmiert und darf kostenlos für jegliche Zwecke (auch kommerziell) verwendet und auch nach belieben verändert werden!

Anzeige

1. Inhaltsverzeichnis generieren (PHP Skript)

Der folgende Code generiert aus den Überschriften <h2> und <h3> das Inhaltsverzeichnis.

Für Programmiererfahrene: Dieser Code muss in die functions.php des verwendeten Themes (falls verwendet ins Child-Theme) eingefügt werden.

Für Programmierunerfahrene: Im Backend-Menü (linker Rand) gibt es einen Punkt „Design“. Navigiere dort zum Unterpunkt „Theme-Editor“ und wähle dann am rechten Rand unter „Theme-Dateien“ die „Theme-Funktionen“ (functions.php) aus. Dort kannst Du bis ganz ans Ende scrollen und nach der letzten Zeile Code 2-3 Leerzeilen einfügen und dann den untenstehenden PHP-Code 1:1 einfügen und abspeichern.

// filter function to generate the table of content (from webdeasy.de)
function add_table_of_content($content) {
    ob_start();

    preg_match_all("/<h[2,3](?:\sid=\"(.*)\")?(?:.*)?>(.*)<\/h[2,3]>/", $content, $matches);
    $tags = $matches[0];
    $ids = $matches[1];
    $names = $matches[2];

    ?>
    <ul class="table-of-contents">
        <li><strong>Inhaltsverzeichnis</strong></li>
        <!-- Table of contents by webdeasy.de (LH) -->
        <?php for($i = 0; $i < count($names); $i++) { ?>
            <?php if(strpos($tags[$i], "h2") === false || strpos($tags[$i], "class=\"nitoc\"") !== false) continue; ?>
            
                <li>
                    <?php if(!empty($ids[$i])) { ?>
                        <a href="#<?php echo $ids[$i]; ?>"><?php echo $names[$i]; ?></a>
                    <?php } else { ?>
                        <?php echo $names[$i]; ?>  
                    <?php } ?>
        
                    <?php if($i !== count($names) && strpos($tags[$i+1], "h3") !== false) { ?>
                        <ul>
                            <?php for($j = 0; $j < count($names) - 1; $j++) { ?>
                                <?php $sub_index = $i + $j; ?>
                                <?php if($j != 0 && strpos($tags[$sub_index], "h2") !== false) break; ?>
                                <?php if(strpos($tags[$sub_index], "h3") === false || strpos($tags[$sub_index], "class=\"nitoc\"") !== false) continue; ?>

                                <li>
                                    <?php if(!empty($ids[$sub_index])) { ?>
                                        <a href="#<?php echo $ids[$sub_index]; ?>"><?php echo $names[$sub_index]; ?></a>
                                    <?php } else { ?>
                                        <?php echo $names[$sub_index]; ?>  
                                    <?php } ?>
                                </li>
                            <?php } ?>
                        </ul>
                    <?php } ?>
                </li>

        <?php } ?>
    </ul>
    <?php
    return str_replace("<p>{{TABLE_OF_CONTENTS}}</p>", ob_get_clean(), $content);
}
// add our table of contents filter (from webdeasy.de)
add_filter('the_content', 'add_table_of_content');

Der reguläre Ausdruck zum Auslesen der Überschriften ist wie folgt aufgebaut:

<h[2,3](?:\sid=\"(.*)\")?(?:.*)?>(.*)<\/h[2,3]>

Damit suchen wir alle HTML-Tags die eine h2 oder h3 sind. Der Teil (?:\sid=\"(.)\")?(?:.)? gruppiert uns die ID (falls vorhanden) und gruppiert außerdem alle weiteren Attribute (falls vorhanden), die der HTML-Tag noch hat.

Anzeige

Kleiner Tipp: Wenn Du mit Deiner Website oder Deinem Blog nebenbei etwas Geld verdienen möchtest, erfährst Du in diesem Beitrag alles wichtige über Google Adsense, einer der größten Werbedienste im Internet.

2. Inhaltsverzeichnis aufhübschen (CSS)

Mit dem bisherigen Code wird Dein Inhaltsverzeichnis bereits generiert. Allerdings würde es als normale Liste <ul> ausgegeben werden. Damit das Ganze etwas schöner aussieht, spendieren wir dazu auch noch ein paar Zeilen CSS.

Für Programmiererfahrene: Dieser Code muss in eine CSS Datei des verwendeten Themes (falls verwendet ins Child-Theme) eingefügt werden. Oft ist das Standardmäßig die style.css auf oberster Ebene im Theme-Ordner.

Für Programmierunerfahrene: Im gleichen Menüpunkt wie schon beim PHP-Code kannst Du einfach rechts „Stylesheet“ (style.css) auswählen. Dort gehst Du auch wieder ans Ende und fügst nach der letzten Zeile den folgenden Code ein und speicherst die Datei dann ab.

ul.table-of-contents {
  padding: 1rem;
  border-left: 3px solid #cecece;
  background-color: #e6e6e6;
}
ul.table-of-contents > li:first-child {
    margin-bottom: 0.5rem;
    font-size: 110%;
}
table-of-contents li {
  list-style: none;
}

Damit sieht das Inhaltsverzeichnis nun besser aus und ist auch als solches erkennbar. Das kannst Du natürlich alles an Dein Theme und Deinen Wünschen entsprechend anpassen (lassen).

Anzeige

3. Verzeichnis in einzelne Beiträge einbinden

Um das Inhaltsverzeichnis nun auf einer Seite auszugeben, kannst Du einfach im Backendeditor des jeweiligen Beitrags als normalen Absatz {{TABLE_OF_CONTENTS}} einfügen.

Inhaltsverzeichnis Selektor in Backend-Ansicht

Zusätzlich solltest Du jede Überschrift mit einem HTML-Anker versehen. Dazu klickst Du die Überschrift an und fügst unter „Erweitert“ einen Anker ein. Dieser wird dann mit einer Raute (#) an die URL gehängt und ermöglicht das Springen im Inhaltsverzeichnis. Den Namen kannst Du Dir frei überlegen, sollte aber zur Überschrift passen.

Erweitertes Überschriftenmenü

Das ist alles! Wenn Du Dir die Seite jetzt anschaust, sollte das Inhaltsverzeichnis entsprechend den <h2> und <h3> Tags ausgegeben werden.

Menüpunkte ausschließen

Falls Du ein oder mehrere Menüpunkte ausschließen möchtest (wie diese Überschrift :)), so dass sie nicht im Inhaltsverzeichnis angezeigt werden, kannst Du der jeweiligen Überschrift zusätzlich die CSS Klasse nitoc geben. Das Skript ignoriert diese dann.

Fazit

Du hast es geschafft! Durch ein paar Zeilen Code kannst Du Dir jetzt immer Dein eigenes Inhaltsverzeichnis generieren lassen und musst nicht mehr auf fertige Plugins zurückgreifen. Oder noch schlimmer: die Inhaltsverzeichnisse immer selber schreiben und aktualisieren. Viel Spaß damit! 🙂

Ähnliche Beiträge
Beteilige dich an der Unterhaltung

2 Kommentare

  1. Hallo Zusammen !

    Das geht aber noch eleganter mit einer rekursiven Lösung (bis h5):

    // filter function to generate the table of content
    function add_table_of_content_sub($tags, $ids, $names, $ii, $level) {
    $heads = array(‚h2‘, ‚h3‘, ‚h4‘, ‚h5‘);
    $ul = 0;
    $i = $ii;

    if( $level > 3) return $ii – 1;

    for(; $i 0 && $ul == 1 ) echo „\n“;
    return add_table_of_content_sub($tags, $ids, $names, $i, $level+1);
    }

    if( $level > 0 && $ul == 0 ) {
    echo „\n“;
    $ul = 1;
    }

    if ( empty($names[$i]) ) continue;

    echo „\n“;

    if(!empty($ids[$i])) {
    echo „„. $names[$i] . „\n“;
    } else {
    echo $names[$i];
    }

    $i = add_table_of_content_sub($tags, $ids, $names, $i+1, $level+1);

    echo „\n“;
    }

    if( $level > 0 && $ul == 1 ) echo „\n“;

    return $i;
    }

    function add_table_of_content($content) {
    ob_start();
    preg_match_all(„/(.*)/“, $content, $matches);
    $tags = $matches[0];
    $ids = $matches[1];
    $names = $matches[2];
    ?>
    Inhalt

    <?PHP
    return str_replace("{{TABLE_OF_CONTENTS}}“, ob_get_clean(), $content);
    }

    Viele Grüße

    Michael

    1. Hi, super Lösung! Ich hatte bereits an einer rekursiven Version gearbeitet, ist allerdings noch nicht fertig geworden, daher noch die iterative Lösung. Sobald meine Version vollendet ist, werde ich sie hier auch veröffentlichen. Trotzdem vielen Dank, dass Du Deine Lösung hier teilst! 🙂

      Viele Grüße
      LH

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.