Bernhard Häussner
Tags: Artikel mit dem Tag «Projekt: Mein Blog» durchstöbern

Schöne URLs dank mod_rewrite

01.03.2009, 13:17
blogjournal.php?page=2 => blog/journal/2                   (22->14;64%)
blogtags.php?tag=PHP&page=2 => blog/tags/PHP/2             (27->15;56%)
blogentry.php?link=1_Hello_World! => /blog/1_Hello_World!  (33->20;61%)

Eigentlch war das ja schon lange geplant, alle URLs etwas zu verschönern, und sämtliche überflüssige .php?bla=&foo= rauszunehmen. Doch ich hatte immer das Problem, dass die alten URL nicht mehr benutzbar waren. Das ganze habe ich erst versucht mit RewriteRules zu lösen, doch es hat sich herausgestellt, dass es mit PHP leichter zu lösen ist. Wie alles funktioniert will ich hier kurz beschrieben.

Wer den RSS-Feed liest, dem ist vielleicht aufgefallen, dass über Nacht ein paar viele neue Einträge dazu gekommen sind. Diese sind leider gar nicht neu, jedoch da ich das URL-Format ändern musste, werden sie als neu erkannt. Die Seite hat jetzt URL-mäßig einen schönen hierarchischen Aufbau:

/
/about
/blog
/blog/1_Hello_World!
/blog/[...alle Einträge]
/blog/archiv
/blog/feeds
/blog/journal
/blog/journal/1
/blog/journal/2
/blog/journal/[...alle Seiten]
/blog/newcomments
/blog/tags
/blog/tags/PHP
/blog/tags/PHP/1
/blog/tags/PHP/2
/blog/tags/PHP/[...alle Seiten]
/blog/tags/[...alle Tags]
/contact
/projects
/projects/1_Mein_Blog

Das alles wird erstmal von mod_rewrite erledigt. Die URLs oben werden in PHP-verträgliche URLs mit GET-Paramtern usw. umgewandelt. Damit dann aber nicht immer Seiten doppelt erscheinen, musste ich im PHP-Script überprüfen, durch welche URL das Script aufgerufen wurde. Stimmt diese nich mit der kanonischen URL überein, dann leitet das Script mittels eines 301-Redirects direkt an diese weiter. So ist jedes Dokument nur einmal vertreten, was sowol meinen Aufrufstatistiken zuvorkommt, Verwirrung bei Benutzern vorbeugt und Suchmaschinen zufrieden stellt.

Außerdem sind die URLs nicht mehr von der Technik hinter den Kulissen abhängig. Sollte ich also irgendwann die Technik von PHP auf ColdFusion, ASP, Java oder was es alles gibt umstellen, bleiben die URLs (höchstwahrscheinlich) gleich. Sie enthalten keine sinnlosen Dateiendungen usw. Der Prozess funktioniert so:

                           |
                           V
              Request mit beliebiger URL
                           |
                           V
Apaches mod_rewrite wandelt in „normale“ URL mit GET Parametern um
                           |
                           V
    PHP parst die URL und entschiedet, was angezeigt werden soll
                           |
                           V
 PHP vergleicht die kanonische URL zur Anzeige mit der des Requests
             /                          \
            /                            \
    URL ist gleich                   URL ist anders
           |                              |     
           V                              V
  Content wird angezeigt         301 an die richtige URL

Im PHP sieht das Vergleichen dann ungefähr so aus: (z.B. in blog.php)

function setCanURL($root,$url) { // Leiter weiter, falls nötig
	$request_url_withoutHTTP=$_SERVER['REQUEST_URI'];
	$canonical_url_withHTTP=$root.$url;
	$canonical_url_withoutHTTP=removeDomain($root.$url);
	$request_url_withoutHTTP_realspaces=rawurldecode($request_url_withoutHTTP);
	if ($request_url_withoutHTTP_realspaces!=$canonical_url_withoutHTTP) {
			redirect301($canonical_url_withHTTP);
	}
}
function redirect301 ($newurl) { // Macht 301 Weiterleitungen
	header("HTTP/1.1 301 Moved Permanently"); 
	header("Location: $newurl"); 
	header("Connection: close");
	die();
}
function removeDomain($url) { // gibt die URL ohne den Domaine-Teil zurück
	$url=preg_replace('/https?:\/\/([0-9a-zA-Z]+\.){1,}([0-9a-zA-Z]+)\//','/',$url);
	return $url;
}
setCanURL('http://localhost/testseite/','blog');

Man muss natürlich immer irgendwie wissen, wie die kanonische URL aussehen soll. Dann ruft man einfach die Funktion auf. Es ist egal, wie die alte URL aussah! Am besten noch da einbauen, wo die URLs geparst werden bevor die Seite gerendert wird.

Super-Geeky Firefox Quicksearch feature

Die neuen URLs machen auch etwas sehr Zeitsparendes möglich. Empfiehlt sich bei allen Seiten zu machen, die man häufig benutzt (und man kurze URL-Pfade besucht):

In Firefox erstellt man im Bookmark-Manager ein neues Bookmark mit Folgenden Eigenschaften:

  • Adresse: http://bernhardhaeussner.de/%S (Großes S)
  • Schlüsselwort: bh

Allgemein funktioniert das so, dass man z.B. für Suchfunktionen „[Schlüsselwort] [Begriff]“ in die Adresszeile eingeben kann, und so eine Schnelle Suchfunktion hat. Da Firefox aber nichts anderes macht, als %S mit dem Begriff zu ersetzten, kann man das auch für jede andere URL verwenden. So kann ich jetzt durch Eingabe von bh blog direkt zu meinem Blog kommen. Sehr praktisch... Übrigens, benutzt man den Kleinbuchstaben %s wird / zu %2F und ähnliches, wodurch man nicht alle URLs eingeben kann, was jedoch in GET-Parametern wichtig ist („urlencode“).

Super-Geeky Konqueror Quicksearch feature + KRunner

Im Konqueror gibt es auch eine Suche über die Adressleiste, die sich Webkürzel nennt. Man kann diese Webkürzel in Konqueror einrichten im Einrichtungsdialog unter Webkürzel. Dort gibt man dann als Adresse http://bernhardhaeussner.de/\{@} ein und als Kürzel z.B. bh, bxt.

Selbst wenn man Konqueror nicht benutzt, lassen sich diese Kürzel in KRunner benutzten: Ein Tastendruck auf ALT+F2 und die Eingabe von bh:blog führt dann also direkt zu meinem Blog. Ziemlich praktisch und lässt sich auch beliebig erweitern.

Zum Glück ist meine Seite auch noch nicht überall verlinkt, weshalb ich auch sonst nicht viel ändern muss.

Kommentare: keine

Schneller abbr- und acronym-Tags im Editor

01.02.2009, 21:42

Die beiden Abkürzungs-Tags abbr und acronym werden kaum verwendet, vielleicht weil man nicht ständig Definitionen schreiben will, denn wozu gibt es Abkürzungen? Glücklicherweise kann ich die Definitionen auch fast automatisch schreiben, dank einer netten (und neuen) Funktion im CMS, die ich hier vorstellen werde.

Da eine Abk. meist mehrere Bedeutungen hat und man auch nicht immer wissen kann, was sich hinter den wenigen Buchstaben verbirgt, wäre man manchmal froh um eine Erklärung. Weil aber meistens sowieso klar ist, worum es sich handelt, darf die Erklärung auch nicht im Weg stehen. Eine Lösung dafür bieten die abbr- und acronym-Tags welche im title-Attribut eine Definition enthalten können, die dann vom Browser als Tooltip angezeigt wird.

Um jetzt diese Definitionen einfach einzufügen markiert man die Abkürzung im Editor und klickt auf den Abkürzungsbutton. Mit Javascript und AJAX wird eine Liste der Abkürzungen mit den markierten Buchstaben geladen, die die verschiedenen Definitionen enthält. Aus dieser wählt man dann die passende Definition und die Tags werden in den Text eingefügt. Sollte die passende Definition nicht gefunden werden, kann man einfach einen leeren abbr- oder acronym-Block einfügen.

Ein PHP-Skript generiert im Hintergrund die Abkürzungsdatenbank. Es sammelt in den vorhandenen Blogposts die verwendeten Abkürzungen mit ihren Definitionen heraus. Damit bei einer großen Abkürzungsdatenbank nicht so viel übertragen werden muss, filtert das PHP-Skript die Abkürzungen auch gleich noch. Da der Filter optional ist und ich ein CSS-Stylesheet für die Abkürzungsliste gebastelt habe, kann man sich die XML-Datei mit den Abkürzungen auch im Browser anschauen.

Auf diese weise ist das Hinzufügen von Abkürzungen kein Problem und es erscheinen auch immer nur die Abkürzungen, die man auch wirklich verwendet.

(andere neue Features des Blogs)

  • Print-Stylesheet
  • Suchfeld-Tipp
  • jQuery 1.3 und dessen
  • Live Events bei Feed-Tag-Wahl
  • Noscript-Warnung bei Feed-Tag-Wahl
  • und ein paar interne Sachen

War wohl ein produktives Wochenende. Ich bin auch bei ein paar anderen Projekten erheblich weiter gekommen.

Kommentare: keine

Umstellung auf PHP Data Objects mit Prepared Statements

10.01.2009, 09:52
PDO and Prepared Statements

PDO and Prepared Statements

Da ich die letzte Zeit offline war (und bald eine rund 15x schnellere Internet-Verbindung habe) konnte ich am Computer recht wenig machen. Deshalb habe ich ein bisschen an dieser Webseite gebastelt und die Datenbank-Verbindung auf PHP Data Objects (PDO) umgestellt. Diese unterstützen Prepared Statements, wo eine SQL-Abfrage schon geparsed werden kann, bevor konkrete Werte eingesetzt wurden, was sowohl der Sicherheit (keine SQL-Injections möglich) als auch dem Reccourcen-Verbrauch (Unveränderliches wird geparsed und gespeichert) zugute kommt.

Ich konnte mit der Umstellung auch gleich meine interne Datenverbindung zu den Views von einem Gemisch aus MySQL-Resultsets und Arrays auf nur Arrays umstellen, sodass die Views jetzt nicht mehr Umgeschrieben werden müssen, falls der PHP-Controller auch die Daten ändern will, wie zum Beispiel bei der Suche, wo die Reihenfolge der Ergebnisse von PHP berechnet wird. Da die MySQL-Abfragen dennoch optimiert sind, werden diese Arrays auch nicht zu groß.

Die Umsetzung der PDOs war nicht ganz einfach, zumal die (unvollständige) Datenbankabstraktion mehr oder weniger abwärtskompatibel sein sollte aber zusätzlich einiges an Automatik beinhalten sollte. So cacht sie jetzt nur SELECT-Abfragen, und gibt je nach Abfrage-Art (SELECT, INSERT, UPDATE) das Resultset, die Insert-ID oder die Anzahl der upgedateten Datensätze zurück. Sie verwaltet selbst die Prepared Statements, sodass nichts doppelt präpariert wird, überlässt mir damit also die Fütterung mit beliebigem SQL und kümmert sich um den Rest.

Da die PDOs auch eine relativ einfache Umsetzung von Transactions mitliefern, überlege ich mir, ob ich auch noch diese automatisch laufen lasse, jedoch habe ich noch kaum Erfahrung mit Transactions, weshalb ich damit erst nicht etwas beschäftigen muss (Rollbacks, SELECTs etc.).

Kommentare: keine

Blog RC2

17.12.2008, 15:29
Konfigurierbare Feeds

Konfigurierbare Feeds

Kurz vor Weihnachten ist nun der nahezu finale Blog da. Es wurden noch einige Fehler ausgemerzt und Spamschutz implementiert. Außerdem etwas Interaktivität mittels Javascript und jQuery.

Mit jQuery konnte ich jetzt einige Dinge etwas verschönern. Kommentare werden ohne Neuladen gepostet und die Suche zeigt erste Ergebnisse schon beim tippen. Ein Feature, das ohne Javascript leider nicht geht, sind auf bestimmte Tags eingestellte Feeds. Mit aktivierten Javascript kann man Tags in eine Box klicken, und erhält dann einen Feed, in dem nur Artikel gelistet werden, die die gewählten Tags enthalten. Ohne Javascript sieht man nur die Tagcloud und kann daraus einen Feed zu einem Tag wählen. Das Hinzufügen der Kommentare und die Suche funktionieren ohne Javascirpt ganz klassisch.

Kommentare sind schnell moderiert

Kommentare sind schnell moderiert

Dann habe ich noch einen Spamschutz gebastelt, der hoffentlich funktioniert und keinen Ärger macht. Ich denke es wird sich zeigen, ob er Spambots von meiner Seite fernhält. Für den Fall dass Werbekommentare und rechtswidrige Kommentare gepostet werden, kann ich diese nun moderieren und dank jQuery auch ohne neu laden und damit recht schnell.

Um die Requests zu reduzieren habe ich auch ein Script, dass alle Javascrpt-Dateien zu einem jsmin-Komprimirten Script zusamenfügt. Außerdem werden die PHP-Klassen nun mit autoload geladen.

Noch andere Kleinigkeiten wurden geändert, doch weiter fehlende Features und Bugs werden sich eventuell im Betrieb zeigen.

Kommentare: 1 Einträge

Blog RC1

07.12.2008, 20:48

Ja es ist so weit. Der Blog ist nahezu fertig zum Release. Es ging jetzt wirklich recht zügig voran mit den Pojekten und der Suche.

Zuerst musste ich den Code des Blogs so weit verallgemeinern, dass es kein Problem bereitet, ein Blögähnliches Konstrukt für die Projekte zu basteln. Das hat erstaunlicherweise recht gut geklappt. Dann habe ich noch die About-Seite aus XML-Daten bauen lassen.

Etwas aufwändiger war die Suche. Hier kam mit die Generalisierung von Blog und Projekten zugute, da ich die Volltext-Suche nur einmal machen musste. Sie funktioniert nach einem durchdachten Punkte-System, sodass Treffer im Titel eines Eintrags die Einträge weiter nach oben wandern lassen, und auch Wortteile gefunden werden, jedoch nicht so viel zählen. Im Text wird natürlich auch nach de Suchbegriffen gesucht. Zusätzlich schaut sich die Suche in der Navigation um und in den Tags vom Blog. Es ist natürlich möglich nach mehreren Schlagwörtern zu suchen, wobei im Punktesystem für Blog & Projekte die Punkte einfach aufaddiert werden, und z.B. bei den Tags einfach alle Treffer angezeigt werden. Indem man eine Suchphrase in Anführungszeichen (") stellt, kann man auch nach Wortgruppen suchen. Man findet also eigentlich, so hoffe ich, alles.

Ein kleines Problem war, dass meine Views bisher nicht auch Array-Daten zugeschnitten waren, sondern auf Datanbank-Streams und XML-Daten. Die Suche brauchte aber leider die Flexibilität der PHP Arrays und daher musste ich mir dazu auch etwas einfallen lassen. Ich denke das müsste auch noch nützlich sein, wenn irgendwann mal Bäume gerendert werden sollen.

Was jetzt natürlich noch fehlt sind die Javascript-Teile. Die wären langsam wirklich praktisch. Leider muss ich mich dazu erst ein bisschen einlesen, z.B. in jQuery.

Was auch noch kam: Das Redesign. Manchmal muss man ein Konzept nochmal überdenken. Irgendwie war das ursprüngliche Design ja nur da, um ein bisschen zu testen, wie gut es sich mit den Templates designen lässt. Also redesignen lässt es sich Spitze. Doch dazu im Post Webdesign von x bis heute mehr.

Was auch noch fehlt sind so Dinge wie Spamschutz, die ich eigentlich nicht brauchen will, aber die da sein sollten, bevor die Seite online geht. Ansonsten freue ich mich schon auf den Release.

Kommentare: 1 Einträge
 
Χρόνογραφ
© 2008-2017 by Bernhard Häussner - Impressum - Login
Kurz-Link zur Homepage: http://1.co.de/