301 - Dauerhaft Verschieben

Neben dem Umzug von Wordpress auf Octopress hat dieses Blog auch noch eine weitere einschneidende Veränderung erfahren: Alle Blogartikel haben ein vorangestelltes /blog/ in der URL bekommen. Einfach so die URL verändern ist eigentlich keine gute Idee:

  • Alle bisherigen Links funktionieren nicht mehr. Verlinkt jemand anderes auf einen Artikel, so verläuft dieser Link ins Leere.
  • Für den Pagerank bei Google ist das selbstverständlich auch nicht hilfreich.

Wenn man es aber richtig macht, dann ist all dies kein Problem mehr.

Für (unter anderem) solche Umstände gibt es die “HTTP-Statuscodes”, von denen 404 oder 500 wohl die bekanntesten sind. In diesem Fall hilft 301-Moved Permanently.

Für dieses Blog reichte folgende .htaccess.

.htaccess
ErrorDocument 404 /404.html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^feed atom.xml [l]
RewriteRule ^feed/atom atom.xml [l]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/blog/$1/ -d
RewriteRule ^(.*)$ blog/$1 [R=301,L]
</IfModule>

Das Wichtigste kurz erklärt:

  • Zeile 1 definiert die Datei, die angezeigt werden soll, wenn ein 404-Fehler aufgetreten ist (wenn also doch mal ein ungültiger Link existiert).
  • Zeilen 5 und 6 biegt die beiden alten urls der RSS-Feeds so um, dass sie auf den neuen Feed zeigen
  • Zeilen 7-10 sind wohl die interessantesten. Die RewriteCond geben die Bedingungen an, die erfüllt sein müssen, damit die RewriteRule ausgeführt wird. Dabei
    • Zeile 7 der Request darf nicht auf einen bereits existiertenden Ordner zeigen
    • Zeile 8 der Request darf nicht auf eine bereits existiertende Datei zeigen
    • Zeile 9 diese Condition enthält einen Parameter ($1) aus der darauffolgenden RewriteRule
      Diese Condition prüft, ob denn im ordner “blog” ein Ordner mit dem angeforderten Artikelname existiert (bei Octopress ist das normalerweise so)
    • Zeile 10 führt dann den eigentlichen rewrite durch und setzt den Statuscode 301

Diese Konfiguration funktioniert aber nur, wenn “%{DOCUMENT_ROOT}” tatsächlich auf das Document_Root des Blogs zeigt. Bei mir war dies nicht der Fall, da Apache vorher ein Virtual-to-Real-Mapping durchgeführt hat. In diesem Fall muss man dann “%{DOCUMENT_ROOT}” dann durch den korrekten Pfad ersetzen.

Die Verwendung von $1 in Zeile 9 ist nur deswegen möglich, weil bei der interne Verarbeitung der Direktiven erst das Suchmuster der RewriteRule überprüft wird und dann die RewriteCond.