isenberg
I'm new here

Einstiegsseiten mit kurzen URLs im Live-Webserver

Um auf einem Live-Webserver kurze URLs für verschiedene Einstiegsseiten bereitzustellen, kann im Apache httpd mod_rewrite mit der Funktion RewriteMap verwendet werden.

Der einfachste Fall, die Weiterleitung z.B. von http://www.domain.net/info nach http://www.domain.net/en/products/info.html wird über folgende Zeilen in der Konfigurationsdatei httpd.conf realisiert:

RewriteEngine On

RewriteMap kurzurls txt:/var/www/site/en/globalpages/rewritemap.txt

RewriteRule ^/(.*) ${kurzurls:/$1} [redirect=permanent,last]

Wobei in der Datei rewritemap.txt die Weiterleitungsregeln zeilenweise in der Form "/kurzadresse   /zielpfad/seite.html" eingetragen werden:

/info /en/products/info.html

/contact /en/contact.html

/kontakt /de/contact.html

Die Rewrite-Datei wird vom httpd automatisch bei Änderungen erneut eingelesen.

Um die Rewrite-Datei als Redakteur über FirstSpirit im Inhaltsbereich verwalten zu können, also Kurzadressen als Text eingeben zu können und die zugehörigen Seitenreferenzen direkt im Strukturbereich auswählen zu können, muss folgende Seitenvorlage erstellt werden:

Formular:

<CMS_MODULE>

    <CMS_INPUT_CONTENTAREALIST name="pt_rewrite" hFill="yes" rows="25">

    <LANGINFOS>

      <LANGINFO lang="*" label="Rewrite map"/>

    </LANGINFOS>

    <SOURCES>

      <TEMPLATE name="rewrite_entry"/>

    </SOURCES>

    <VARIABLES>

      <VARIABLE name="st_urlName"/>

    </VARIABLES>

  </CMS_INPUT_CONTENTAREALIST>

</CMS_MODULE>

HTML:

<CMS_HEADER>

</CMS_HEADER>

$CMS_TRIM(level:2)$

$CMS_IF(!pt_rewrite.isEmpty)$

          $CMS_FOR(item, pt_rewrite)$

                    $CMS_VALUE(item)$

          $CMS_END_FOR$

$CMS_END_IF$

$CMS_END_TRIM$

Und folgende Absatzvorlage mit Namen "rewrite_entry":

Formular:

<CMS_MODULE>

  <CMS_INPUT_TEXT name="st_urlName" hFill="yes" singleLine="no" useLanguages="no">

    <LANGINFOS>

      <LANGINFO lang="*" label="URL Name"/>

    </LANGINFOS>

  </CMS_INPUT_TEXT>

  <FS_REFERENCE name="st_target" hFill="yes" sections="yes">

    <FILTER>

       <ALLOW type="pageref"/>

        </FILTER>

    <LANGINFOS>

       <LANGINFO lang="*" label="Target" description="Please choose a page"/>

       <LANGINFO lang="DE" label="Ziel" description="Bitte wählen Sie eine Seite"/>

    </LANGINFOS>

    <PROJECTS>

        <LOCAL name=".">

           <SOURCES>

             <FOLDER name="root" store="sitestore"/>

           </SOURCES>

        </LOCAL>

    </PROJECTS>

  </FS_REFERENCE>

</CMS_MODULE>

HTML:

<CMS_HEADER>

</CMS_HEADER>

$CMS_VALUE(if(!st_urlName.isEmpty,"/" + st_urlName))$ $CMS_SET(url)$$CMS_REF(st_target,abs:2)$$CMS_END_SET$$CMS_VALUE(url.toString.subString(url.toString.indexOf("/", 1)))$

Eine Seite "rewritemap.txt" wird dann im Inhaltsbereich aus diesen beiden Vorlagen erstellt und dort die Liste der Weiterleitungsregeln bearbeitet und damit automatisch beim Deployment zum Webserver übertragen.

Um Groß/Kleinschreibung in der URL zu ignorieren, sind noch einige weitere Regeln hinzuzufügen. Außerdem ist ein Schutz vor Überlagern wichtiger, in FirstSpirit vorgegebener Pfade wie /media, notwendig. Folgende Konfiguration in httpd.conf bearbeitet alle Kurzadressen, die mindestens 3 Zeichen enthalten und nur aus Buchstaben und Zahlen bestehen über die Weiterleitungsliste:

RewriteEngine On

RewriteMap shorturls txt:/var/www/site/en/globalpages/rewritemap.txt

RewriteMap lcmap int:tolower

RewriteCond %{REQUEST_URI} !^/media/?

RewriteCond %{REQUEST_URI} ^/([a-zA-Z0-9]{3,})/?$

RewriteCond ${lcmap:/%1} ^/(.*)$

RewriteCond ${shorturls:/%1} ^/(.*)$

RewriteRule ^/(.*)$ /%1 [redirect=permanent,last]

Falls man sprachunabhängige Kurzadressen verwenden möchte, also die Zielseite in Abhängigkeit von der im Web-Browser eingestellten Prioritätsliste von Sprachen angezeigt werden soll, kann RewriteMap nicht verwendet werden, sondern z.B. folgende hier nur im Konzept beschriebene Lösung mittels PHP, die beispielsweise auf http://e-spirit.com eingesetzt wird:

Für jede Kurzadresse wird eine Datei mit Namensschema "kurzadresse.php.sprachkürzel" erstellt, also beispielsweise für die Kurzadresse "info" zur Weiterleitung auf die deutsche und englische Seite:

Datei info.php.de:

<?php

header("HTTP/1.1 301 Moved Permanently");

header("Status: 301 Moved Permanently");

header("Location:http://www.domain.net/de/products/info.html");

header("Connection:close");

exit;

?>

Datei info.php.en:

<?php

header("HTTP/1.1 301 Moved Permanently");

header("Status: 301 Moved Permanently");

header("Location:http://www.domain.net/en/products/info.html");

header("Connection:close");

exit;

?>

In httpd.conf wird dann nur der oben verwendete Block zur Umsetzung der Groß/Kleinschreibung verwendet und zusätzlich "MultiViews" aktiviert um die sprachabhängigen Dateiendungen automatisch auszuwerten. PHP wird hier verwendet, da im httpd die Multiviews nicht mit virtuellen URLs der RewriteMap kombiniert werden kann, sondern nur auf tatsächlich vorhanden Dateien funktioniert. Statt PHP könnte man auch JSP oder Servlets verwenden. MultiViews hat den Vorteil gegenüber selbstgeschriebenen RewriteRules, die HTTP-Spezifikation Content-Negotiation vollständig zu implementieren, also komplizierte Prioritätslisten von Sprachdefinitionen im Browser auszuwerten.

httpd.conf:

RewriteEngine On

RewriteMap lcmap int:tolower

RewriteCond %{REQUEST_URI} ^/[a-zA-Z0-9]{3,}/?$

RewriteCond %{REQUEST_URI} [A-Z]

RewriteRule ^/(.*) /${lcmap:$1} [nocase,redirect=permanent,last]

<Location />

  Options +MultiViews ...

  ...

</Location>

Die Seiten- und Absatzvorlagen werden werden wie zuvor verwendet. Zusätzlich muss nun ein im Deployment-Auftrag z.B. über ssh aufgerufendes Skript auf dem Webserver die PHP-Dateien anhand der Rewrite-Datei für jede Sprache erstellen.

Labels (2)
Tags (1)
Comments

Vielen Dank, das mod_rewrite-Beispiel ist klasse.

Wir verwenden in unseren Projekten noch ein anderes Konstrukt mit PHP, welches sich ebenfalls bewährt hat. Das Prinzip ist ähnlich, der Effekt ein etwas anderer:

  • Redakteur pflegt in FS eine Liste der Kurz-URLs in ähnlicher Form wie oben
  • Wir generieren daraus eine Map (in diesem Fall eine PHP-Datei mit einem fertigen Array, welches einfach inkludiert werden kann)
  • Verwendet wird dies aber nicht per mod_rewrite, sondern in der 404-"not found"-Seite. Diese ist ein PHP-Script, welches die Map inkludiert, in der URL nach Strings sucht, welche in der Map vorkommen, und dann einen Redirect in die Website macht
  • In der Regel verwenden wir "307 Temporary Redirect", weil wir ja wollen, dass die (publizierte) Kurz-URL weiterhin die gültige ist. Auf die Weise können die Redakteure das Linkziel ummappen, und der Redirect wird sofort aktiv

Beispiel: Aufruf von www.domain.de/seminare. /seminare existiert als Seite nicht, also landet der Aufruf beim PHP-404-Script. Dieses parst die URL "www.domain.de/seminare", findet in der Map "seminare", und springt auf die entsprechende Seite im Web. In der Map ist am Ende auch gleich noch ein Redirect auf die Startseite des Webs enthalten, so dass generell keine 404-Fehler mehr vorkommen.

Einziger Nachteil ist, dass bei jeder Kurz-URL ein "404"-Fehler im Apache-Log auftaucht.

Dieser Mechanismus ist so universell und bei uns mittlerweile so stark in FS verzahnt, dass wir ihn für alle möglichen Dinge verwenden (alles vom Redakteur pflegbar)

  • Einsprung auf unterschiedliche Seiten in Abhängigkeit von der Domain
  • Dito in unterschiedliche Sprachen
  • Mapping von alten auf neue URLs nach einem Relaunch / einer Restrukturierung
  • Fallback, wenn eine Seite in der Struktur verschoben wurde. FS erzeugt eine Map mit FS-IDs bzw. UIDs, und das 404-Script findet die Seite an ihrem neuen Ort in der Struktur

Nebenbei: Wir pflegen die Map als DOM, geben nur die Links im DOM per Linkvorlage aus, und ignorieren den Rest des DOMs (Linktext = Kurz-Url). Auf die Weise kann der Redakteur Kommentare als normalen Text in den DOM schreiben, das erleichtert die Übersicht. Außerdem wurde der Mechanismus zu 3.1-Zeiten geboren, und da waren Linklisten und CALs mit mehr als 20 Einträgen nicht mehr vernünftig bedienbar.