Überarbeitung einer klassischen statischen Website (Teil 2)

Dieser Beitrag beschreibt recht detailliert, wie eine antike HTML-Webseite in eine moderne PHP-Seite umgewandelt wurde. Im ersten Teil wurde die Umstellung auf PHP und UTF-8 behandelt, hier geht es nun um die Modernisierung des HTML-Codes.

Achtung: Dieser zweite Teil ist naturgemäß stärker auf die konkrete Webseite ausgerichtet, anhand derer ich diesen Text 2009 geschrieben habe. Wenn ihr das mit einer eigenen Seite machen wollt, müsst ihr die nötigen Anpassungen vornehmen. Dieser Beitrag ist nicht als 1:1 zu befolgende Anleitung gedacht, sondern mehr als eine Anleitung, was man mit vergleichsweise wenig Aufwand erreichen kann. 😉

Frameset auflösen (Startseite)

Die bisherige Seite benutzt ein Frameset. Ein Frame enthält links das Menü, ein zweiter Frame oben den Seitenheader und der dritte Frame enthält den eigentlichen Seiteninhalt. Bei der statischen HTML-Seite ersparte es mir das, das Menü und den Header immer wieder in jeder Datei einzubinden. Heutzutage löst man das natürlich ganz einfach mit PHP-Includes.

Zuerst einmal lege ich im includes-Ordner die Dateien header.php, navigation.php und footer.php an. In die header.php kommt dabei der HTML-Header sowie der Seitentitel mit rein, die footer.php enthält die Fußzeile sowie die schließenden body- und html-Tags. Die bisherigen Frames werden dabei zu divs mit den IDs #header, #navigation und #contentarea, welche sich per CSS auf die bisherigen Größen der Frames stylen lassen. Die Navigation wird dabei absolut am linken Rand positioniert, ihr Background-Bild verschiebe ich an den Body, da die Navigation sich nun nicht mehr bis zum unteren Bildschirmrand erstreckt. Die anderen drei Bereiche (#header, #contentarea und #footer) haben jeweils einen linken Abstand in der Breite der Navigation.

Die alten Frameset-Dateien können nun weg. Statt dessen binde ich in der index.php die neuen include-Dateien ein:

<?php require_once($baseDirectory . "header.php"); ?>

<!-- Seiteninhalt -->

<?php require_once($baseDirectory . "navigation.php"); ?>
<?php require_once($baseDirectory . "footer.php"); ?>

Und das war es tatsächlich schon für die Startseite. Nachdem die Pfade bei der Einbindung der CSS-Datei angepasst sind, sieht die Startseite genauso wie mit Frames aus, außer dass sich die Scrollbar jetzt über die ganze Höhe erstreckt.

Frameset auflösen (Einzelseiten)

Alle Dateien erhalten am Anfang drei weitere Variablen: $pageTitle, $pageDescription und $created. Hier müssen die Werte des Titel-Tags und des Meta-Description-Tags sowie das Erstellungsdatum (welches sich bei meiner Webseite am Ende der Seite im Text findet) eingetragen werden. Die header.php wird so modifiziert, dass sie $pageTitle und $pageDescription ausgibt anstatt fester Werte. Ebenso gibt die footer.php neben $lastUpdate auch $created aus.

Die drei include-Dateien können analog zur index.php ebenfalls recht einfach per Auto-Ersetzen eingefügt werden. Nicht mehr benötigte Tags wie die meisten meta-Tags können per Auto-Ersetzen entfernt werden.

Schwieriger ist es, die benötigten Werte für die Variablen aus den Tags auszulesen und in die Variablen zu schreiben. Hier meine Regular Expression für das Kopieren des Titel-Wertes. Hier ist ggf. etwas Experimentieren angesagt. In UltraEdit funktionierte das übrigens nur mit der Perl-RegExp-Engine.

Replace: pageTitle = '';([^§]*)<TITLE>([^<]+)</TITLE>
With: pageTitle = '\2';\1

Und für das description-Metatag:

Replace: pageDescription = '';([^§]*) <meta name="description" content="([^"]+)">\r\n
With: pageDescription = '\2';\1

Für das Erstellungsdatum von weiter unten in den Dateien:

Replace: created = '';([^§]*)<td>\(c\) by Johannes Ruthenberg, ([^<]+)</td>
With: created = '\2';\1<td>(c) by Johannes Ruthenberg, <?php print $created; ?></td>

Zum Transport des Pfades aus einer JavaScript-Anweisung in den Header:

Replace: pathNav = '';([^§]*)   var pfad_frame = '([^']+)';\r\n
With: pathNav = '\2';\1

Dabei gilt es Seiten zu beachten, in deren Titel oder Beschreibung ein einfaches Anführungszeichen vorkommt. Dieses muss in den neuen PHP-Variablen maskiert werden (als \‘). Finden kann man diese Seiten im nachhinein so:

\$([^=]+) = '.*'(.*').*';

Automatisches Ersetzen würde ich da jetzt eher nicht probieren, jedenfalls nicht ganz allgemein auf allen Seiten. Dann lieber auf bestimmte Fälle zugeschnitten.

Was auch noch weg kann: Target-Parameter an Links, sowohl mit den Namen meiner Framesets als auch mit dem Wert „_top“. Also durch einen leeren String zu ersetzen:

target="inhalt"
target="_top"

Und dann muss ganz oben noch eine Page-ID eingeführt werden:

Replace: // set the page title\r\n  \$pageTitle =
With: // set the page ID\r\n  $pageId = '';\r\n  // set the page title\r\n  $pageTitle =

Und:

Replace: pageId = '';([^§]*)   myValue = "([^"]+)";\r\n
With: pageId = '\2';\1

target=“_blank“ entfernen

Externe Links hat man früher gern mit target=“_blank“ belegt. Mittlerweile gibt es aber Tabs und jeder vernünftige Browser hat Optionen an Links, die Links so zu öffnen wie der Besucher es möchte (gleiches Fenster, neues Tab, neues Fenster). Das target-Attribut mit dem Wert „_blank“ kann man also ersatzlos streichen (Auto-Ersetzen durch leeren String).

CSS-Hacks entfernen

Die neue Stylesheet-Datei wird auf Hacks durchgesehen. CSS-Hacks können in Ausnahmefällen nötig sein, sollten generell jedoch vermieden werden. Falls sich Sachen wie der Star-Hack im CSS-File finden, sollten diese lieber in ein eigenes IE-Stylesheet verschoben werden (ohne den Hack natürlich), welches nach dem normalen Stylesheet mit einem passenden Conditional Comment eingebunden wird. Jedenfalls falls der Hack auf den IE abzielt, was aber fast immer der Fall sein dürfte.

In meinem Fall entstand meine Highlanderseite bevor mir die Bugs im IE so richtig bewusst wurden und ich von den verschiedenen Hacks erfahren habe. Deshalb ist da erst mal nichts weiter zu tun. Ein IE-Stylesheet lege ich ggf. später an, falls das nötig wird.

Doctype berichtigen und auf XHTML umstellen

Die alten Dateien fingen mit diesem Doctype an:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

Das ist gut gemeint, allerdings völlig wirkungslos, da der Doctype keine URL enthält. Die Browser behandeln die Datei damit trotzdem als Quirks Mode. In der header.php wird dieser alte Doctype nun ersetzt durch diesen:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Außerdem bekommt das html-Tag noch die nötigen Attribute:

<html xmlns="http://www.w3.org/1999/xhtml" lang="de">

XHTML Strict deshalb, weil ich mir das bei anderen Projekten angewöhnt habe und es keinen Grund gibt, die Sache nicht gleich richtig anzugehen.

Durch die Umstellung auf XHTML entstehen allerdings eine Menge Validierungsfehler, da in den alten Dateien oft HTML-Tags großgeschrieben waren oder schließende Tags fehlen etc. Diese gilt es nach und nach zu beheben. Anfangen kann man mit der Startseite und diese mittels des Validators valide bekommen. Das betrifft z.B. alle meta-, img- und br-Tags.

RegExp dafür z.B.:

Replace: <img ([^>]+)">
With: <img \1" />

Update Jan 2013: Dieser Text ist schon älter. Heute kann man natürlich auch gleich HTML 5 nehmen.

Header überarbeiten und Barrierefreiheit verbessern

Der Header der Seiten besteht im Moment aus einer Tabelle. Links und rechts ist ein Bild eingebettet, in der Mitte steht ein weiteres Bild, welches den Titel der Seite enthält. Dies wird ersetzt durch zwei divs, welche jeweils das linke und rechte Bild als Hintergrundbild enthalten (da es sich nur um Design-Elemente handelt). Das mittlere Bild bleibt zentriert in den divs stehen. Zusätzlich wird der Seitentitel für die Druckansicht und für Screenreader als h1-Tag eingebunden, welches am Bildschirm nicht angezeigt wird.

Dazu füge ich im Stylesheet diese beiden Klassen ein:

.printonly, .invisible {
  display: none;
}

Damit können Elemente in die Seite eingebunden werden, die optisch nie oder nur in der Druckansicht dargestellt werden. Ganz oben in den Inhalt kommt folgender Block:

    <p class="invisible robots-noindex">
      <a href="#jumpToNavigation">Zur Haupt-Navigation springen</a>
      <a href="#jumpToPageContent">Zum Inhalt springen</a>
    </p>

Dies soll Screen-Readern, die das normale Stylesheet ignorieren sollten, ermöglichen, direkt zum Inhalt und zur Navigation zu springen. Insbesondere für die Navigation ist dies wichtig, da sie sich nun *nach* dem Seiteninhalt befindet. Angezeigt wird dieser Block weder am Bildschirm noch in der Druckansicht.

Die Ziele dieser Verweise müssen natürlich ebenfalls eingefügt werden. Über der Navigation zum Beispiel:

<a name="jumpToNavigation" class="invisible"></a>
<h2 class="invisible robots-noindex">Hauptnavigation</h2>

Maskierte Umlaute demaskieren

Die Webseite wurde ursprünglich wie gesagt noch mit ISO-8859-1 erstellt und mein damaliger Editor, Phase 5, hat mir alle Umlaute praktischerweise beim Speichern in Entities umgewandelt. Da die Seite nun mit UTF-8 läuft, können die maskierten Umlaute der besseren Lesbarkeit im Quelltext halber wieder zurückgewandelt werden. Also: &Auml; zu Ä, &auml; zu ä etc. Groß- und Kleinschreibung dabei beachten! UltraEdit kriegt das in meiner Version leider nicht hin (es zerhaut dabei die UTF-8-Codierung), deshalb mache ich das nach und nach manuell. Fürs erste schaden die maskierten Umlaute ja auch nicht.

Update Jan 2013: Dass das einfach nicht geht ist ja wohl nicht akzeptable. Ich bin auch sicher, dass Notepadd++ das hinkriegt. Diesen Editor kannte ich damals leider noch nicht.

Navigation überarbeiten

Die Navigation meiner Seite beruhte auf einer Tabelle, welche die Einzelteile eines größeren Bildes enthält (ein Bild pro Link). Hover-Effekte sind mittels JavaScript umgesetzt. Alles in allem also eine aufwändige und sehr schlecht zu wartende Lösung. Idealerweise würde ich heute eine Navigation immer als Text umsetzen und Hover-Effekte mit CSS realisieren.

Die alte Navigation muss mehr oder weniger komplett neu geschrieben werden. Die JavaScripts für die Hover-Effekte können entfallen. Alle Links werden in einer ul-Liste eingebunden, welche per Stylesheet ohne Bulletpoints dargestellt wird. Der Hintergrund (ein Schwert) wird als ein ganzes Bild eingebunden. Darüber lege ich den Kasten für die Menüpunkte als Hintergrund der li-Elemente. Die Abschlusskappen oben und unten (abgerundete Ecken) kommen an die ul-Liste und ein weiteres Hilfs-div. Die Hover-Effekte können dann an den Links realisiert werden.

Alle Links absolut machen

Mit der basePath-Variable kann ich nun alle Links absolut machen. Bisher waren Links immer relativ zur aktuellen Seite gesetzt, so dass man immer wissen musste, in welchem Ordner man sich gerade befindet. Mittlerweile tendiere ich dazu, Links absolut zu setzen.

Folgende RegExp-Suche sollte alle internen Links erbringen, die nicht schon absolut sind:

href="([^#</"][^:"]*)"

Weniger strikt:

href="(\.\./[^:"]*)"

Die Links werden per Auto-Ersetzen nach und nach absolut gemacht. Dabei wird die $basePath-Variable verwendet, damit die Links sowohl lokal als auch auf dem Server funktionieren (lokal liegt die Seite in einem Unterordner unter localhost). Die neuen Links sehen dann z.B. so aus:

<a href="<?php echo $basePath; ?>/de/chronik/immortals/files/amanda.php">Amanda</a>

Fazit

Ich hoffe, dieser etwas längere Text hilft vielleicht bei ähnlichen Projekten weiter. Ich bin jedenfalls froh, dass ich meine alte Webseite damit ins 21. Jahrhundert geholt habe. Ein richtiges CMS als Basis wäre natürlich schöner, aber da ich weiterhin nahezu null Zeit für die Webseite habe, ist der gegenwärtige Zustand schon ziemlich gut. Immerhin erlaubt die Umstellung auf PHP es, z.B. externe Kommentarscripte einzubinden.

Schreibe einen Kommentar

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

Bitte beachte die Kommentarregeln: 1) Kein Spam, und bitte höflich bleiben. 2) Ins Namensfeld gehört ein Name. Gerne ein Pseudonym, aber bitte keine Keywords. 3) Keine kommerziellen Links, außer es hat Bezug zum Beitrag. mehr Details...

So, noch mal kurz drüber schauen und dann nichts wie ab damit. Vielen Dank fürs Kommentieren! :-)