mermshaus: Verlinkung ausgehend von Seitennamen

Beitrag lesen

@VivienSchiller @Matthias Apsel @Gunnar Bittersmann

Ich habe mal die beiden vorgeschlagenen Varianten zur Demonstration/Inspiration zusammengestöpselt.

Alle Dateien liegen im gleichen Verzeichnis.

index.php, kontakt.php, journal.php und dergleichen:

<h1>index.php</h1>

<?php
require __DIR__ . '/_navigation.php';
echo createNavigation(basename(__FILE__));
?>

_navigation.php:

<?php

/**
 * @param $activeFile
 * @return string
 */
function createNavigation($activeFile)
{
    // Hier je nach gewünschtem Mechanismus eine Zeile auskommentieren

    //$list = _generateListFromDirectory(__DIR__);
    $list = _generateListFromFile(__DIR__ . '/list.json');

    return _createNavigationFromList($activeFile, $list);
}

/**
 * @param $file
 * @return array
 */
function _generateListFromFile($file)
{
    $ret = json_decode(file_get_contents($file), true);

    return (is_array($ret)) ? $ret : array();
}

/**
 * @param $dir
 * @return array
 */
function _generateListFromDirectory($dir)
{
    // Liste aller *.php-Dateien im Verzeichnis ermitteln. Einträge, die mit
    // "_" beginnen, ignorieren

    $tmp = glob($dir . '/*.php');

    $files = array();

    foreach ($tmp as $item) {
        $basename = basename($item);

        if ('_' === substr($basename, 0, 1)) {
            continue;
        }

        $files[] = array(
            'url'   => $basename,
            'title' => pathinfo($basename, PATHINFO_FILENAME)
        );
    }

    return $files;
}

/**
 * @param $file
 * @param array $list
 * @return string
 */
function _createNavigationFromList($file, array $list)
{
    // Wenn keine Einträge in Liste, Rückgabe

    $count = count($list);

    if (0 === $count) {
        return '<p>Keine Einträge in Liste.</p>';
    }

    // Wenn aktive Datei nicht in Liste, Rückgabe

    $pos = -1;

    foreach ($list as $index => $item) {
        if ($file === $item['url']) {
            $pos = $index;
            break;
        }
    }

    if (-1 === $pos) {
        return '<p>Datei nicht in Liste.</p>';
    }

    // Wenn aktive Datei einzige in Liste, Rückgabe

    if (1 === $count) {
        return '<p>Keine weiteren Dateien in Liste.</p>';
    }

    // Vorherige/nächste Datei in Liste ermitteln (-1, wenn letzte/erste)

    $prev = ($pos > 0)          ? $list[$pos - 1] : array();
    $next = ($pos < $count - 1) ? $list[$pos + 1] : array();

    // HTML-Ausgabe der Navigation zusammenbauen (exaktes HTML-Markup und CSS
    // und dergleichen bitte nicht auf die Goldwaage legen)

    $escape = function ($s) {
        return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
    };

    $ret = '';

    if (!empty($prev)) {
        $ret .= sprintf(
            '<a class="nav nav-prev" href="%1$s" title="Zurück zu: %2$s">&larr; %2$s</a>',
            $escape($prev['url']),
            $escape($prev['title'])
        );
    }

    if (!empty($next)) {
        $ret .= sprintf(
            '<a class="nav nav-next" href="%1$s" title="Weiter nach: %2$s">%2$s &rarr;</a>',
            $escape($next['url']),
            $escape($next['title'])
        );
    }

    $ret = '<p>' . $ret . '</p>';

    $styles = <<<'CSS'
.nav {
    padding: 5px;
    margin: 5px;
    text-decoration: none;
    border: 1px solid #ccc;
    border-radius: 3px;
}
CSS;

    $ret .= '<style>' . $styles . '</style>';

    return $ret;
}

list.json:

[
  { "url": "journal.php", "title": "Journal" },
  { "url": "foo.php",     "title": "Foo" },
  { "url": "kontakt.php", "title": "Kontakt" },
  { "url": "index.php",   "title": "Index" }
]