Sein Link(er) Gang

Written by | 01 May 2013 | Published in 2013 May
Ein abschreckendes Beispiel wie die verlinkte Vergangenheit Martin Raja und Arlen Walker eingeholt hat, und wie sie (die Links) in der Folge besinnunglos geschlagen wurden. Der Beitragstitel (Der im Original Dead Link Walking heisst) ist übrigens eine Anspielung auf den Film "Dead Men Walking" - welcher auf Deutsch etwas unglücklich "Sein letzter Gang" heisst. Naja, ich habs versucht zu übersetzen, aber der Gag passt halt nicht unbedingt. Sorry about that.
Sein Link(er) Gang image by @Helvecio

"He! Dieser Link geht nicht mehr!"

Nicht gerade das, was man hören möchte nach einem sonst reibungslos gelaufenen Upgrade. Auch unter den besten Umständen nicht. Und die Umstände in diesem Fall waren alles andere als ideal. Der link in der Adresszeile sah völlig verstümmelt aus, kaum als Link erkennbar.

Woher kam dieser Link bloss? Na, toll.. Es handelte sich um einen Link in einem völlig veralteten Format, er hatte ein "task=view" drin als Anweisung für Joomla! eine Seite anzuzeigen. Alt. Ganz alt, Uralt.

Aber das war noch nicht alles, es kam noch schlimmer. Dieser nette Link wurde immer noch in E-Mails mitgesendet, noch heute; und die Idee war natürlich, dass dieser Link gültig war für die Kunden, sicherlich ein volles Jahr lang. Was uns zwei Möglichkeiten liess: Die E-Mails anzupassen und irgendwie dafür sorgen, dass der alte Link irgendwie doch funktioniert - oder dann Anpassen der Mails und ein volles Jahr lang zuwarten mit der Migration von Joomla! 1.5. Letztere Möglichkeit schied natürlich sofort aus.

Was war also zu tun? Zunächst dachten wir, das sei ein einfacher Job für das mod_rewrite Modul von Apache, also starten wir dort. Die ersten paar Versuche scheiterten allerdings kläglich, und Onkel Google wusste auch keinen vernünftigen Rat - offenbar hatte sowas noch nie jemand geschafft.

Gutmeinende Freunde rieten uns, ein eigenes Router Plugin zu schreiben für diesen Fall, Aber nun hatte uns der Ehrgeiz gepackt; wir wollten den Apachen dazu bringen, das zu tun, was wir wollten. Abwechslungsweise klopften wir an dem Problem herum, jeder Versuch brachte uns der Lösung einen Schritt näher - aber die Lösung wollte sich einfach nicht finden lassen. Es war Martin, mein Co-Autor, der schliesslich das fehlende Mosaiksteinchen fand.

Wir hatten ursprünglich im Sinn, einen vollen Satz von Regulären Ausdrücken zu schreiben, um damit jedes Vorkommen von "view=article" durch "task=view" zu ersetzen, aber nach den ersten paar fehlgeschlagenen Experimenten liessen wir diese Idee fallen und vereinfachten die Aufgabe: es war gar nicht notwendig, den "task" Parameter zu entfernen, Joomla! würde ihn schliesslich einfach ignorieren. Alles, was wir tun mussten, war, den "view" Parameter hinzuzufügen. Das allerdings löste nun des Apachen's Lust auf Endlosschleifen aus. Obwohl uns das eine Menge Zeit für die Fehlersuche kostete, fanden wir genau dadurch schliesslich doch die Lösung für das Puzzle.

Die Lösung bestand aus drei Zeilen mod_rewrite. Für ähnliche Fälle ist dieser Code durchaus zur Verwendung empfohlen; er löste unser Problem (wir hatten ausschliesslich ein Problem mit dem Linken auf Artikel) und während unser Code für die Lösung von anderen Situationen nicht unbedingt geeignet ist, mag doch unsere Lösung als Leitfaden herhalten.

Um ganz zu verstehen, was wir getan haben, müssen wir uns kurz mit dem mod_rewrite des Apachen und mit Regulären Ausdrücken beschäftigen. Es gibt eine Anzahl gute Einführungen in diese beiden Thematiken, also genügte es, hier zwei Links zu erwähnen. Da wäre einmal Apache’s mod_rewrite Dokumentation und dann auch noch diese diese Einführung in Reguläre Ausdrücke. (Beides auf Englisch)

Hat man sich das unter den Gürtel geklemmt, schnappt man sich Schutzhelm und -brille und sieht sich damit den Rewrite-Code näher an:

RewriteCond %{QUERY_STRING} ^(.*)task=view(.*)$

Die RewriteCond Anweisung legt die Bedingung fest, unter der  die folgenden Zeilen ausgeführt werden. Jede dieser Regeln muss bei der Evaluation ein "True" zurückgeben, bevor die nächste RewriteRule ausgeführt wird. Obige Zeile gibt "True" zurück, falls in der URL ergendwo "task=view" vorkommt. (Das ^ steht für den Beginn der Zeichenfolge und das $ für das Ende. Das “.” steht für ein beliebiges Zeichen und das “*” wiederholt dasselbe für eine beliebige Anzahl Zeichen, sodass mit diesem Ausdruck die gesamte Zeichenfolge untersucht wird.)

RewriteCond %{QUERY_STRING} !(view=article)

Diese Zeile erwies sich als Schlüssel für das Puzzle. Der Apache liebt Schlaufen! Wenn er eine Änderung gemacht hat, wiederholt er sich. Das wurde uns plötzlich klar, als wir versuchten bloss einen neuen Ausdruck zur Zeichenfolge hinzuzufügen. Ohne diese Zeile, würde Apache in eine Endlosschlaufe den Server blockieren. (Oder er würde, wenn er nicht selbst von seiner Neigung zum Schlaufen wüsste. Stattdessen sagt der Apache "Nö, das mag ich nicht, da geh ich nimmer hin" und verweigert fortan die Ausführung von Rewrites, die ein Schlaufe zur Folge haben könnten.) Diese spezielle Eigenschaft hat uns in unseren frühen Versuchen  mehrmals gebissen, bis Martin schliesslich entdeckt hat, was hier passiert. Diese Zeile ist ein Schutz vor diesem Verhalten; ist der "view=article" Parameter irgendwo in der Zeichenfolge vorhanden (das “!” steht für  nicht), lautet das Ergebnis für diese Anweisung "False" und wir verlassen den Satz von Regeln an diesem Punkt - und damit die Schlaufe.

RewriteRule ^.*$ /$0?%1view=article%2 [R=301,L]

Jetzt gehts ans Eingemachte. Der erste Teil der Zeile ("^.*$") selektiert die gesamte URI, so, wie sie daherkommt. Der zweite Teil schreibt den neuen, umgeschrieben Request. Der $0 Teil nimmt die im ersten Teil der Regel selektierte Zeichenfolge und stellt ihn nach einem "/", womit wir ein "/index.php" für die URI bekommen.
Die Ausdrücke %1 and %2 nennt man Rückverweise, sie verweisen auf die beiden Teile der im ersten RewriteCond zerpflückten URI (.*), welche das "task=view" umgaben -- sie rahmen im neugeschriebenen Request nun "view=article" ein.

Die beiden Argumente am Ende der Zeile in eckigen Klammern (“R=301” und “L”) stehen für: Mach einen 301 Redirect, und das ist die letzte Anweisung für diese Regel.

Das alles formt aus dem veralteten Request eine Anweisung zu Anzeigen eines Artikels, welche von einem zeitgemässen Joomla! verstanden wird - genau das, was wir erreichen wollten.

Während diese Rewrite-Regel für unseren speziellen Fall funktioniert, kann damit natürlich nicht jede denkbare Möglichkeit von Joomla! 1.0-Requests abgefangen werden. Aber auch wenn das für andere - ebenso spezielle Fälle auch nicht genügend sein mag, kann dieser Artikel dennoch als Leitfaden dienen, wie solchen Problemen per Rewrite-Regel begegnet werden kann.

Dieser Artikel stammt ursprünglich aus der Feder von Arlen Walker und Martin Raja und erschien im Joomla! Community Magazine May 2013

Read 7308 times Tagged under German
Chris Hoefliger

Chris Hoefliger

Chris got involved in Joomla a few years ago (when 1.5.14 was the flavour of the day). But he stayed with Joomla! ever since, is eager and wants to learn the ropes...
«I have a small company and do web pages. I speak both German and English. I'd like to see a bit more content here in my native language and - oops got caught. Yep, I'm trying to do a bit translation work for the team»