Up Down Left Right Tarkus-OnLine.de / WebDesign / Tipps / SSI
WebDesign 4.4   TIPPS - Serversteuerung mit SSI
(Neue Rubrik 2003-10-17)
 
Ich setze an dieser Stelle die Grundlagen für das Arbeiten mit SSI als bekannt voraus und werde daher lediglich beschreiben, wie und warum ich meine eigenen SSI-Anweisungen genau so angelegt habe, wie sie zur Zeit sind. Basis-Wissen über SSI findet man zum Beispiel bei Server Side Include Externe Seite in neuem Fenster.
 
Wichtiger Hinweis für voreilige Umsteiger!
SSI funktioniert nur, wenn der Server seitens des Betreibers entsprechend eingerichtet wurde. Aber auch Server, die es unterstützen, setzen nicht immer alle SSI-Funktionen um! Bevor man seine Seiten mit umfangreichen SSI-Funktionen ergänzt, sollte man sich daher vergewissern, dass diese auf dem vorgesehenen Server auch wirklich funktionieren. Lokal auf der eigenen Festplatte kann man dies in der Regel nicht testen. Zum Testen ist also ein UpLoad zwingend erforderlich.
Flower Graphic By Tarkus
 
Up Down Top   4.4.1   SSI als Standard einstellen
 
SSI-Code wird vom Server nur dann umgesetzt, wenn er eine Seite anhand ihrer Endung (z.B. .shtml) als SSI-Seite erkennt. Um nicht jedesmal, wenn eine weitere Seite mit SSI-Code ergänzt wird, diese Seite umbenennen zu müssen, macht es Sinn, grundsätzlich alle Seiten als SSI-Seiten zu definieren.
 
Normalerweise müssten hierzu die Endungen sämtlicher Seiten von .shtml bzw. .html in .shtml umbenannt werden. Zwangsläufig müssten dann natürlich auch sämtliche Verweise zu diesen Seiten geändert werden.

 
 
Man kann sich das Umbenennen von Dateien und Verweisen ersparen, indem man dem Server einmalig mitteilt, dass auch Seiten mit den Endungen .shtml bzw. .html SSI-Seiten sind. Hierzu bedarf es lediglich eines neuen Eintrags in die Datei .htaccess, zum Beispiel so:
 
AddType text/x-server-parsed-html .html .shtml
 
 
Der Nachteil von SSI, dass der Code erst vom Server umgerechnet (geparsed) werden muss, führt zwar zu einer leichten Verzögerung, auch wenn auf einer Seite letztlich gar kein SSI-Code vorhanden ist, doch in der Regel ist diese Verzögeung so gering, dass sie für den Besucher der Seite kaum spürbar sein dürfte.
 
Flower Graphic By Tarkus
 
Up Down Top   4.4.2   Zeitpunkt des letzten Uploads anzeigen
 
Man kann den Zeitpunkt des letzten UpLoads einer Datei mit folgendem Javascript anzeigen lassen:
 
<script type="text/javascript">
document.write("UpLoad: " + document.lastModified);
</script>
 
 
Dies funktioniert allerdings nicht bei Seiten, die als SSI-Seiten definiert sind (siehe weiter oben). Der Grund ist, dass SSI-Seiten bei jedem Aufruf vom Server automatisch neu aufgebaut werden. Für das Javascript sieht es dann so aus, als sei die Seite soeben erst hochgeladen worden. In solchen Fällen muss das o.g. Javascript durch SSI-Code ersetzt werden. Zum Beispiel so:
 
<!--#config timefmt="UpLoad: %Y-%m-%d, %H:%M:%S" -->
<!--#echo var="LAST_MODIFIED" -->
 
 
Der Einsatz von SSI wird übrigens damit belohnt, dass die Formatierung der Zeitangabe flexibler ist. Das weiter oben genannte Javascript gibt die Zeit nämlich im Standard-Format aus, was nur mit einem aufwändigen Zusatz-Skript änderbar ist. SSI dagegen erlaubt durch einfache Definition des Zeit-Formats (config timefmt=...) bereits recht viele Möglichkeiten.
 
Standard-Format:
aniclock.gif UpLoad: 05/28/2022 00:37:36

Statt der eigentlich gewünschten UpLoad-Zeit wird hier durch das Parsen fälschlicherweise die aktuelle Uhrzeit angezeigt. (Die obige Darstellung entspricht genau dem, was man mit Javascript sehen würde, wurde aber, damit es an dieser Stelle auch bei evtl. deaktiviertem Javascript sichtbar ist, dennoch mit SSI gemacht.)
 
SSI-Beispiele:
aniclock.gif UpLoad: 11.08.2013, 22:39 Uhr
aniclock.gif UpLoad: 2013/08/11 22h 39m 12s
aniclock.gif UpLoad: 2013-08-11-22:39:12

Hier wird die korrekte UpLoad-Zeit angezeigt.
Flower Graphic By Tarkus
 
Up Down Top   4.4.3   Inhalte auf mehreren Seiten einbinden
 
Sich ständig wiederholende Inhalte, wie zum Beispiel beim Info-Balken (Footer) unten auf jeder meiner Seiten, schreibe ich in separate Dateien, die ich an der gewünschten Stelle mittels SSI aufrufe:
 
<!--#include virtual="/footer.shtml" -->

Ähnlich den zentralen CSS-Formaten erleichtert dies eventuelle Änderungen enorm, da man statt jeder einzelnen Seite nur noch die von dort aufgerufene Datei ändern muss.
 
 
Neben diesem Info-Balken auf den Inhalt-Seiten verwende ich die Technik vorwiegend auch in den Menü-Leisten, um dort Schalt-Flächen zu setzen, die stets verfügbar sein sollen.
 
Auch die Verweise unter "WebDesign/SurfTipps" werden auf diese Art dargestellt, da sie identisch auch in meine Seite "SurfTipps/Internet" eingebunden sind.

 
Flower Graphic By Tarkus
 
Up Down Top   4.4.4   Offline-Darstellung trotz SSI-Angaben
Substitute symbol (Tipp überarbeitet 2004-05-12)
 
Lässt man SSI-Seiten offline anzeigen, so werden die SSI-Angaben normalerweise nicht ausgeführt. Es gibt zwar Software, mit der man auch offline Server-Funktionen, wie SSI, ausführen lassen kann, doch ist dabei einerseits nicht sichergestellt, dass die Anweisungen wirklich identisch wie auf dem Server ausgeführt werden, und andererseits steht diese Software nicht überall zur Verfügung.
 
 
Eine Lösung, die für viele Zwecke völlig ausreicht, basiert auf folgender Überlegung (Der Text ist zwar etwas lang geworden, doch es ist weniger kompliziert, als es anfangs ausschaut.):
 
Offline werden SSI-Angaben zwar nicht ausgeführt, wohl aber alles, was dazwischen steht! Diesen Umstand kann man sich zunutze machen, indem man die Anzeige eines nur offline gewünschten SSI-Ersatzes mit einer SSI-"if-"Abfrage kombiniert, welche online garantiert nicht zur Ausführung führt (zum Beispiel, ob das aktuelle Datum in der Vergangenheit liegt oder ähnlich Absurdes).
 
Diesen Teil lässt man der eigentlich gewünschten SSI-Angabe folgen.
 
 
Beispiel:
 
Wenn ich den Inhalt einer anderen Datei einbinden will, dann tue ich dies nacheinander auf zwei Arten, nämlich online per SSI (weils einfach besser ist), und offline per I-Frame (damit auch dann noch etwas zu sehen ist):
 
Hier nun ein Beispiel-Skript, welches in die einbindende Datei integriert werden könnte:
 
<!--#include virtual="/einzubindende_seite.shtml" -->
 
<!--#config timefmt="%Y" -->
<!--#if expr="$DATE_LOCAL <= '1998'" -->
<iframe src="einzubindende_seite.shtml" style="width:100%; border-style:none; ">
An dieser Stelle sollte eigentlich ein I-Frame geladen werden.
<br> Leider stellt der hier verwendete Browser keine I-Frames dar.
<br> <a href="einzubindende_seite.shtml" target="_new">
Klicke hier zum Anzeigen des Inhaltes im neuen Fenster.
</a>

</iframe>
<!--#endif -->

Der abgedunkelte Code wird nur von Browsern verarbeitet, die keine I-Frames darstellen können.
 
Auf dem Server würde die zweite Anweisung nur ausgeführt, wenn das aktuelle Datum in der Vergangenheit liegen würde, also in der Regel nie(!). Lokal dagegen werden zwar alle SSI-Angaben ignoriert, nicht aber die Anweisung für den I-Frame.
 
Neben der alternativen Einbindung von Inhalten per SSI und I-Frame sind natürlich auch andere Ersetzungen denkbar, wie zum Beispiel eine Datums-Einblendung alternativ mit SSI und Javascript.
 
 
Der Vollständigkeit halber sollte vielleicht noch erwähnt werden, dass per SSI der komplette Inhalt der eingebundenen Datei in die einbindende Seite integriert wird, wogegen beim I-Frame die eingebundene Datei als eigenständige Internet-Seite dargestellt wird.
 
Dies ist wichtig zu wissen, denn wenn die eingebundene Datei zum Beispiel eigene head-Angaben enthält, kann es beim SSI-include-Befehl zu Konflikten mit den head-Angaben der einbindenden Datei kommen.
 
Lässt man dagegen die head-Angaben einfach weg, so werden die Dateien aber innerhalb von I-Frames nicht wirklich korrekt dargestellt. Das stört zwar nicht sonderlich, sofern es lediglich als Hilfe für die offline-Bearbeitung verwendet wird, doch auch das lässt sich auf dem oben beschrieben Weg umgehen:
 
Man umschließt den head-Bereich der eingebundenen Datei ebenfalls mit einer Datums-Abfrage in der Vergangenheit. Somit wird dieser Teil ebenfalls nur offline ausgeführt. Eine eingebundene Datei könnte dann so aussehen:
 
<!--#config timefmt="%Y" -->
<!--#if expr="$DATE_LOCAL <= '1998'" -->
<HTML...>
<head>
(Hier stünden die head-Angaben)
</head>
<body>

<!--#endif -->

(Hier stünde der eigentliche Seiten-Inhalt)

<!--#config timefmt="%Y" -->
<!--#if expr="$DATE_LOCAL <= '1998'" -->
</body>
</HTML>

<!--#endif -->
 
Der letzte Teil ist erforderlich, um die HTML- und body-Bereiche korrekt abzuschließen.
 
Flower Graphic By Tarkus
 
Up Down Top   4.4.5   Informations-Übergabe ohne Cookies
Substitute symbol (Neuer Tipp 2004-06-20)
 
Cookies und Javascript bzw. Java sind an sich eine praktische Sache. Nur leider(?) kann der Besucher diese Funktionen deaktivieren. Will man an eine Folge-Seite lediglich kleine Informationen übergeben, die nicht permanent benötigt werden, so geht dies aber auch schon mit purem SSI.
 
 
Version 1: In manchen Fällen reicht es schon aus, wenn man weiß, von welcher Seite der Besucher kam. Man fragt also zum Beispiel einfach ab, ob der Besucher zuvor auf der Seite mit den AGBs war:
 
<!--#if expr="$HTTP_REFERER = 'http://www.eigene_domain.de/agb.shtml'" -->
Substitute symbol Hier finden Sie
Substitute symbol <a href="download.shtml> unser Angebot! </a>
<!--#else -->
Substitute symbol Bitte lesen und akzeptieren sie zunächst
Substitute symbol <a href="agb.shtml> unsere AGBs. </a>
<!--#endif -->
 
In obigem Beispiel bekommt der Besucher also, wenn er zuvor auf der Seite mit den AGBs war, den Verweis zu den Download-Seiten und andernfalls zu den AGBs angezeigt.
 
 
Version 2: Wenn es nicht ausreicht, nur zu wissen, von welcher Seite der Besucher kam, dann kann man einen Parameter (z.B. ja oder nein) getrennt durch ein Fragezeichen, einfach an einen Verweis anhängen und ihn auf diese Art (als Inhalt einer Variablen) an die Folge-Seite (z.B. zielseite.shtml) übergeben. Man kann so zum Beispiel gezielt abfragen, ob die AGBs akzeptiert wurden oder nicht:
 
Akzeptieren Sie unsere AGBs?
<a href="zielseite.shtml?ja"> Ja! </a>
<a href="zielseite.shtml?nein"> Nein! </a>
 
Auf der Ziel-Seite fragt man nun mittels SSI den Inhalt dieser Variablen ab und macht davon die weitere Verarbeitung abhängig. In folgendem Beispiel wird je nach Antwort lediglich ein anderer Text ausgegeben und ein anderes Verweis-Ziel gesetzt. Es sind natürlich auch deutlich komplexere Anwendungen denkbar (siehe weiter unten).
 
<!--#if expr="$QUERY_STRING_UNESCAPED = 'ja'" -->
Substitute symbol Hier finden Sie
Substitute symbol <a href="download.shtml> unser Angebot! </a>
<!--#elif expr="$QUERY_STRING_UNESCAPED = 'nein'" -->
Substitute symbol Kein Download ohne Akzeptanz unserer
Substitute symbol <a href="agb.shtml> AGBs! </a>
<!--#else -->
Substitute symbol Bitte lesen und akzeptieren sie zunächst
Substitute symbol <a href="agb.shtml> unsere AGBs. </a>
<!--#endif -->
 
In obigem Beispiel bekommt der Besucher also, je nachdem, ob er auf der vorhergehenden Seite die AGBs akzeptiert hat, entweder den Verweis zu den Download-Seiten oder zurück zu den AGBs angezeigt. Letzteres auch Jeder, der die Seite direkt aufgerufen hat (z.B. über eine Suchmaschine), dann aber mit einem etwas freundlicheren Text. ;o)
 
 
Variante a): Man kann auch beide obigen Versionen kombinieren, indem man zum Beispiel abfragt, ob der Besucher sowohl von der AGB-Seite kommt, als auch diese akzeptiert hat. Damit könnte man zum Beispiel den Zugriff verhindern, für den Fall, dass Jemand die Seite direkt aufruft, und zwar inklusive der Option hinter dem Fragezeichen.
 
 
Variante b): Beide Versionen funktionieren auch, wenn die aktuelle Seite einen Verweis auf sich selbst enthält. Je nach Abfrage-Ergebnis stellt die Seite sich dann unterschiedlich dar.
 
 
Beispiel: Eine Kombination 'mit Allem' habe ich übrigens für meine Download-Seiten geschrieben. (Da meine Skripte ständig in Arbeit sind, entsprechen die aktuellen Download-Seiten eventuell zwar ganz oder teilweise nicht mehr den folgenden Beschreibungen, doch sie hatten auf jeden Fall so funktioniert.)
 
Wenn mein Download-Menü von einer anderen meiner Seiten aufgerufen wird, dann enthält es zunächst statt der eigentlichen Menü-Leiste einen Hinweis auf den Disclaimer mit der Option diesen zu akzeptieren oder abzulehnen. Die Download-Seite im Haupt-Fenster enthält zu diesem Zeitpunkt noch an Stelle der Download-Schalter einen Hinweis auf den Disclaimer.
 
Durch Akzeptieren des Disclaimers wird die Menü-Seite erneut geladen und zeigt dann statt der Abfrage der Akzeptanz die eigentliche Menü-Leiste an. Auch die Download-Seite im Haupt-Fenster wird neu geladen und enthält dann die gewünschten Download-Schalter.
 
Bei Ablehnung des Disclaimers wird die Download-Seite weiterhin ohne Download-Schalter angeboten.
 
Okay, das ist sicherlich ein recht komplexer Weg, der kaum Fehler verzeiht. Doch dieser Internet-Bereich ist ja nicht zuletzt mein Experimentier-Feld, um Neues auszuprobieren. Und was selbst komplex funktioniert, das dürfte im Kleinen erst recht gehen. ;o)
 
Flower Graphic By Tarkus
 
Up Down Top   4.4.6   Frameset nachladen - Teil 1
Substitute symbol (Neuer Tipp 2005-06-11)
Achtung! Der Vergleich der Umgebungsvariablen funktioniert noch nicht zuverlässig mit jedem Browser! Wenn Jemand eine Idee hat, was an dem Skript falsch ist, immer nur her damit.
 
Wenn eine Interent-Seite, die zu einem Frameset gehört, einzeln aufgerufen wird (zum Beispiel durch eine Suchmaschine oder durch sonstige Verlinkung), dann hat man das Problem, dass sie ohne das zugehörige Frameset erscheint, in dem sich Navigation, Titelleiste und andere mehr oder weniger wichtige Elemente befinden. Die einzige konsequente Lösung: Das Frameset muss nachgeladen werden.
 
Hier kann Javascript zwar gute Dienste leisten, doch funktioniert das halt nur, wenn im Browser Javascript nicht deaktiviert ist.
Es geht aber auch mit SSI, was den Vorteil hat, dass es nicht auf den Browser angewiesen ist.
 
 
Zunächst wird festgestellt, ob die Datei sich im Frameset befindet. Falls dies der Fall ist, müsste der Referrer (also die sie Seite von der aufgerufen wurde) den Domain-Namen enthalten (der im Server-Namen enthalten ist), auf der die Seite abgespeichert ist. Dies kann man wie folgt abfragen:
 
<!--#if expr="$HTTP_REFERER = /$SERVER_NAME/" -->
<!--#endif -->
 
Ist dies der Fall, ist keine weitere Aktion erforderlich, andernfalls muss das Frameset aufgerufen werden (in diesem Fall die Datei index.shtml). Dies geschieht hier mittels Weiterleitung per Metarefresh, wobei die Zeitverzögerung hier null Sekunden beträgt:
 
<!--#if expr="$HTTP_REFERER = /$SERVER_NAME/" -->
(keine Aktion)
<!--#else -->
<meta http-equiv="refresh" content="0; URL=index.shtml">
<!--#endif -->
 
Dieses Skript reicht aus, um das Frameset nachzuladen!
Das Frameset enthält allerdings nur die darin vorgegeben Seiten und in der Regel noch nicht die Seite, in der das obige Skript eingebunden ist. Wie man auch das noch bewerkstelligt, beschreibe ich in einem weiteren Abschnitt.
 
 
Statt in den Header jeder einzelnen HTML-Seite, schreibe ich es allerdings in eine eigene Datei, die ich per SSI-Include-Anweisung im Header jeder HTML-Seite aufrufe.
 
Das hat mehrere Vorteile:
1. Das Skript muss nur ein einziges Mal geschrieben werden, wodurch es änderungsfreundlich ist und zudem Speicherplatz spart.
2. Da SSI lokal ohnehin nicht ausgeführt wird, vermeidet man damit Fehlfunktionen des Browsers.
3. Die Einzelseiten können lokal auch ohne Frameset betrachtet werden und lassen sich dadurch mitunter komfortabler bearbeiten.
 
Flower Graphic By Tarkus
 
Up Down Top   4.4.6   Frameset nachladen - Teil 2
Substitute symbol (Neuer Tipp 2005-06-11)
Achtung! Der Vergleich der Umgebungsvariablen funktioniert noch nicht zuverlässig mit jedem Browser! Wenn Jemand eine Idee hat, was an dem Skript falsch ist, immer nur her damit.
 
Die bereits beschriebene Methode, per SSI ein Frameset nachzuladen, birgt noch den Nachteil, dass das nachgeladene Frameset in der Regel noch nicht die ursprünglich aufgerufene Seite enthält. Hier bedarf es einer Ergänzung des bereits bekannten Skriptes, als auch eine Erweiterung der Frameset-Datei.
 
 
Basis ist das bereits bekannte Skript:
 
<!--#if expr="$HTTP_REFERER = /$SERVER_NAME/" -->
<!--#else -->
<meta http-equiv="refresh" content="0; URL=index.shtml">
<!--#endif -->
 
Ergänzend wird mittels der Meta-Refresh-Anweisung noch der Name der aufrufenden Datei mit übergeben:
 
<meta http-equiv="refresh" content="0; URL=index.shtml?<!--#echo var="DOCUMENT_NAME" -->">
<!--#else -->
<meta http-equiv="refresh" content="0; URL=index.shtml">
<!--#endif -->
 
Damit ist das Skript für die einzelnen Webseiten komplett.
 
 
Nun muss nur noch die Frameset-Datei ergänzt werden
 
Hierfür nehme ich das folgende (vereinfacht dargestellte) Frameset als Beispiel, welches aus einer Titelzeile oben, einem Menü links und dem eigentlichen Inhalt rechts besteht:
 
<frameset rows="100,*">
Substitute symbol <frame src="titel.shtml">
Substitute symbol <frameset cols="150,*">
Substitute symbol <frame src="menue.shtml">
Substitute symbol <frame src="startseite.shtml">
Substitute symbol </frameset>
</frameset>
 
Ergänzend wird nun noch der Inhalt des Übergabe-Parameters (QUERY_STRING) abgefragt. Ist dieser leer, wird die übliche Starseite aufgerufen. Falls nicht, wird statt dessen der Parameter-Inhalt in diesem Frame aufgerufen:
 
<frameset rows="100,*">
Substitute symbol <frame src="titel.shtml">
Substitute symbol <frameset cols="150,*">
Substitute symbol <frame src="menue.shtml">
Substitute symbol <!--#if expr="$QUERY_STRING = ' ' " -->
Substitute symbol <frame src="startseite.shtml">
Substitute symbol <!--#else -->
Substitute symbol <frame src="<!--#echo var="QUERY_STRING" -->">
Substitute symbol <!--#endif -->
Substitute symbol </frameset>
</frameset>
 
Jetzt ist auch das Frameset fertig!
 
Wird nun das Frameset (index.shtml) "normal" aufgerufen, so existiert in der Regel kein Parameter-Inhalt und im Frameset wird die gewohnte Startseite angezeigt.
 
Wird dagegen eine andere Seite des Internet-Bereiches direkt aufgerufen, so wird per Meta-Refresh zum Frameset (index.shtml) weitergeleitet und diesem als Parameter der Name der aufrufenden Datei übergeben. Das Frameset erkennt den Parameter-Inhalt und ruft im rechten Frame statt der Startseite nun die übergebende Seite auf.
 
 
Info für Perfektionisten...
 
Das oben beschriebene Skript hat einen kleinen Schönheitsfehler: Wenn das Frameset lokal, also in der Regel ohne SSI-Unterstützung, aufgerufen wird, dann "sieht" es beide Frame-Aufrufe, also sowohl den für die Startseite als auch den mit dem übergebenen Parameter. Mit letzterem kann das Skript aber lokal nichts anfangen!
 
Dies nur als Information. Einen gravierenden Nachteil sehe ich darin allerdings nicht, da die meisten Browser damit keine Probleme haben. Daher sehe ich auch keine zwingende Notwendigkeit, diesen Fehler abzufangen, was zwar durchaus machbar wäre, aber die Skripte meines Erachtens nur unnötig komplex machen würde.
 
Übrigens...
 
Sollte wider Erwarten das Frameset mal mit einem anderen Parameter, also keinem existierenden Dateinamen, aufgerufen werden (warum auch immer Jemand das tun sollte), so ist auch das kein Beinbruch. Es wird dann innerhalb des Framesets an Stelle der Startseite die übliche Fehlermeldung ausgegeben, dass die gewünschte Datei nicht existiert - und das ist ja auch völlig korrekt. Da die anderen Frames davon nicht betroffen sind, kann der Besucher problemlos per Menü eine existierende Seite anwählen.
 
Flower Graphic By Tarkus
 
site-reload-mini.gif Reload Private WebSite by Ulli U. alias Tarkus © 1998-2022
ICRA
tarkus-online.de/webdesign_tipps_ssi.shtml
37,261 bytes saved on 2013-08-11 at 22:39 (CEST)
Impressum, Kontakt, Rechtliches siehe siehe rechts © K I D e-Mail