Das Link-Widget auf der Startseite deaktivieren

In den letzten Tagen hatte ich viel mit WordPress 3.0 getestet und bin dabei oft tiefer in die Sourcen gestiegen, als mir letztlich lieb gewesen wäre. Ich arbeite gern mit WP und sehe da auch weiterhin viel Potenzial für meine Kunden. Aber manche Erkenntnisse hätte ich lieber nicht gewonnen. Ich bin nunmehr fest davon überzeugt, dass das Aktivieren von einigen Features dem Anwender überlassen werden sollte. Um nur ein Beispiel zu nennen: WordPress verfügt über einen Filter, der dafür sorgt, dass man WordPress „richtig“ (mit einem großen P) schreibt.

Aber Filter und Actions sind nicht die einzigen Dinge, die standardmäßig aktiviert werden, um dann vom Benutzer wieder deaktiviert zu werden. Bei den Widgets gibt es auch einige Kandidaten, deren Existenzberechtigung weiterhin eher zweifelhaft bleibt. Auch hier kann man nacharbeiten, um gezielt Standard-Widgets zu deaktivieren. Ich habe mir noch nicht so genau angesehen, zu welchem Zeitpunkt genau deren Aktivierung erfolgt. Allerdings frage ich mich ernsthaft, warum es nicht standardmäßig Optionen gibt, die dieses Verhalten steuern.

Die WordPress-Options werden doch zu einem großen Teil sowieso global verfügbar gemacht. Warum also werden keine Abfragen gebaut, die sicherstellen, dass keine unerwünschten Filter, Actions und Widgets aktiviert werden? Die einzusparende Rechenzeit ist bei einigen Websites sicher nicht unerheblich. Dazu kommt noch, dass man einige dieser Widgets – so Klasse das Konzept der WordPress-Widgets auch ist – „out-of-the-box“ nicht wirklich flexibel verwenden kann.

Auf der Suche nach der Lösung meines Problem mit WPML und den Widgets bin ich beispielsweise auf das  LinkTranslationWidget gestoßen. Aber meine spontane Idee, zwei Sidebars einzurichten, finde ich immer noch ziemlich in Ordnung und an sich war ja nur noch eine Lösung dafür zu finden, wie man das Link-Widget auf der Startseite entfernt, während es auf den anderen Seiten seine Aufgabe ganz normal erfüllen soll. Einen weiteren Anhaltspunkt für eine mögliche Lösung ergab sich beim Lesen von Disable wordpress sidebars without editing template.

Allerdings wollte ich ja nur ein Widget ausschließen. Interessant war die gebotene Möglichkeit aber allemal, sodass ich mir erst einmal angesehen habe, welche Daten mir der Filter zur Verfügung stellt. Letztlich handelt es sich nur ein mehrdimensionales Array, dass recht überschaubare Informationen zu den Sidebars und den eingesetzten Widgets enthält. Abgelegt ist hier jeweils eine Art ID, die aus dem registrierten Namen, einem Minuszeichen und einer Zahl besteht, wahrscheinlich um mehrere Instanzen eines Widgets zuzulassen.

Das bringt mich dann auf folgende Lösung, die auch wieder einfach in der functions.php oder einem Custom Plugin eingebaut werden kann:

<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 404 (Not Found)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
 </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>404.</b> <ins>That’s an error.</ins>
  <p>The requested URL <code>/svn/trunk/examples/my_disable_widget.php</code> was not found on this server.  <ins>That’s all we know.</ins>

In der Callback-Funktion für array_filter hatte ich ursprünglich preg_match verwendet. Allerdings ist strpos meist die bessere Wahl, wenn es um Geschwindigkeit geht, wovon man sich auch bei diesem Vergleich überzeugen kann.

Have fun!

Neu aufgelegt: Links von Webseiten parsen

Vor fast 3 Jahren habe ich den Artikel Backlinks gecheckt verfasst, der erstaunlicherweise immer noch reichlich Traffic abbekommt. Dabei sind die Informationen, um es mal vorsichtig auszudrücken, schon ziemlich veraltet und lösen einige Problemstellungen auch nicht wirklich. Ich hatte es auch schon bei der Beschreibung zu myLCO angedeutet. Das Parsen von Links mittels Regular Expressions ist keine sehr gute Idee. HTML ist kontextfrei und reguläre Ausdrücke schlagen da in aller Regelmäßigkeit fehl.

Etwas erfolgversprechender sind da schon die diversen DOM-Funktionalitäten, die es seit der Einführung von PHP5 gibt. Allerdings ist der Einsatz in der realen Welt auch nicht ganz ohne Fallstricke und abgesehen davon, gibt es bereits eine Lösung, die sich bei mir bisher bewährt hat und mit der man das Problem mit einigen wenigen Zeilen Code bändigen: den PHP Simple HTML DOM Parser.

Links in HTML-Dokumenten zu parsen wird damit zum Kinderspiel. In Verbindung mit den entsprechenden WordPress-Mechanismen, die das Holen von entfernten Webseiten stark vereinfachen, fühlt sich jeder, dem vielleicht auch die jQuery-Syntax geläufig ist, gleich dreifach wohl. Mein kleines Beispiel zeigt den Einsatz in einem File, das sich in einem Unterverzeichnis der WordPress-Installation befindet. Es sollen alle nofollow-Links meiner Startseite angezeigt werden:

<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 404 (Not Found)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
 </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>404.</b> <ins>That’s an error.</ins>
  <p>The requested URL <code>/svn/trunk/examples/backlinks-reloaded.php</code> was not found on this server.  <ins>That’s all we know.</ins>

Have fun!