25. August 2009
Seit der Version 2.8 bringt Wordpress das neues Template-Tag body_class mit, womit sich verschiedenste Abhängigkeiten und Statusinformationen des CMS als CSS-Klassen an das <body> Element heften lassen, um mittels CSS im Layout darauf reagieren zu können.
<body <?php body_class(); ?>>
Leider ist die Implementation dieser interessanten und nützlichen Funktion in Wordpress eher unglücklich gelöst. Die Jungs von WPEngineer haben bereits im Februar vorbildlich darüber informiert, welche Klassennamen das Tag ins Markup rendert. Darunter befinden sich zahlreiche allgemein gebräuchliche Klassenbezeichnungen wie:
- archive
- author
- blog
- category
- date
- home
- page
- search
- tag
Das Problem bei der Verwendung derart gebräuchlichen Bezeichnungen sind fast zwangsläufig Kollisionen bei der Implementation bestehender CSS-Layouts in Wordpress. Gerade heute habe ich eine Mail zu diesem Thema bekommen:
Man kann sich ja mittlerweile im BODY-Tag CSS-Klassen einfügen lassen je nachdem welcher Typ von Seite aktuelle von WordPress ausgegeben wird. Dabei gibt es auch die Klasse “page” für die Seiten in WordPress. Resultat ist, dass sich das dann mit der Klasse “page” aus YAML überschneidet.
Ich kann im Moment froh sein, dass es nur eine CSS-Klasse von YAML trifft. Schon innerhalb dieses Bloglayouts hier – würde dieses Blog mit Wordpress laufen – würden weitere Klassenbezeichnungen kollidieren, denn ich verwende in meinem Bloglayout auch Klassenbezeichnungen wie “date” oder “category”. Nur sind diese Klassen in meinem Layout nicht dafür gedacht, an das body-Element geheftet zu werden. Nun könnte ich mein CSS-Framework YAML in einer nächsten Version natürlich anpassen, um der Kollision aus dem Wege zu gehen, aber ich halte dies für den falschen Weg, denn die Welt dreht sich nicht um Wordpress und YAML ist nicht allein von diesem Problem betroffen. Wordpress als Blogtool oder CMS sollte eigenständig kein Markup generieren (soweit die graue Theorie) und es sollte ebenso die Implementation bestehender Layouts nicht durch die Kollision von Klassennamen unnötig erschweren.
Ein relativ einfacher und unkomplizierter Lösungsweg heisst: Namespacing. Wordpress könnte allen dynamisch ins Markup generierten CSS-Klassen das Kürzel “wp-” voranstellen (oder dieses sogar im Backend konfigurierbar machen). Bei anderen Content Management Systemen (Bsp: TYPO3) kommt dieses Verfahren bei den meisten Extensions zum Einsatz. Auf diese Weise ließen sich die angedeuteten Probleme leicht vermeiden, während die durchaus sinnvolle Funktionalität weiterhin uneingeschränkt verfügbar bleibt. Leider bin ich selbst zu wenig bewandert in PHP und auch nur ein Gelegenheitsnutzer von Wordpress, dennoch hoffe ich, dass diese Idee auf irgendeinem Kanal an das Entwicklerteam herangetragen wird.
Dienstag, 25.08.09 (16:24 Uhr)
Du kannst die Funktion body_class() auch in der Datei funktions.php (liegt bei dir im Template-Verzeichnis) überschreiben. So könntest du diese dann YAML mitgeben.
Dienstag, 25.08.09 (16:28 Uhr)
@David,
das ist für mich keine echte Lösung, da ich keine Wordpress-Baustelle aufmachen und zukünftig Patches für jede einzelne WP-Version pflegen will. Bei anderen CMS ist Namespacing selbstverständlich.
Dienstag, 25.08.09 (16:41 Uhr)
Dann solltest du vielleicht über YAML-Namespaces nachdenken, wenn es WordPress schon nicht macht.
Dienstag, 25.08.09 (16:48 Uhr)
Das ist zwar eine Überlegung gewesen - siehe Beitrag - aber das bekämpft auch nur die Symptome, aber nicht die Ursache.
Zudem würde ich eine über Jahre gewachsene Kompatibilität von YAML zerstören - nur weil ein CMS bei einem optionalen Template-Tag ein bisschen aus der Reihe tanzt. Nein, das ist es mir momentan nicht wert.
Für Wordpress-User gibt es mehrere Wege, das “Problem” zu umgehen. Die einfachste wäre, auf den Template-Tag zu verzichten. Wenn das nicht geht, dann kann man innerhalb des YAML-Layouts mit dem Selektor “div.page” störungsfrei arbeiten oder man setzt man setzt die für “.page” definierten Eigenschaften für “body.page” wieder zurück.
Dennoch wäre es mittelfristig das Beste, wenn Wordpress hier nachbessern würde.
Dienstag, 25.08.09 (16:58 Uhr)
Betrifft in der Tat ja nicht nur YAML.
Mir sind auch gleich die Microformate eingefallen, derren Parser mit einigen der Klassennamen Probleme haben könnten…
Dienstag, 25.08.09 (18:10 Uhr)
Das ist das typische Wordpress-Problem, es scheint als dächten sie man ist ganz alleine auf der Welt und sie müssten sich um niemand kümmern. Alleine schon, dass es
class=”“mitrendert zeugt schon davon, ich will eventuell ja auch noch eine andere Klasse an meinen Body anhängen. In meinem Textpattern-blog benutze ich als Klasse die Sektion, so:<body class=”<txp:section />”>würde meine Sektion jetzt page heißen uns sich daher mit YAML (das ich nicht nutze, aber wir simulieren jetzt mal) ins Gehege kommen, ist es ein einfaches daraus<body class=“sect-<txp:section />”>zu machen und dann im CSS per sect-page darauf zuzugreifen.Dienstag, 25.08.09 (18:46 Uhr)
@Eric
So isses. Und Du lieferst gleich einen weiteren Lösungsansatz, Wordpress könnte sich auf das Rendern der Klassennamen beschränken, ohne das class-Attribut mit auszugeben.
Dienstag, 25.08.09 (19:57 Uhr)
@Eric: Auch wenn ich Dirk hier recht gebe, so holst du doch weit aus; es ist nicht nur in WordPress ein Problem; außerdem kann man die Funktion von WordPress einfach ersetzen, was aber YAML nicht hilft und zusätzlich kann man die Funktion um eigene Klassen erweitern. Alternativ kann man via Hook auch noch auf die Funktion einfluss nehmen. Also ganz so typisch WP ist es nicht, denn andere Systeme geben diese Möglichkeiten nicht.
Trotzdem ist das sicher via Standard Namespacing besser zu lösen. Aber die Idee von WP war hier zusätzlich noch Strings zu nutzen, die immer gleich sind und man so eventuell offen benutzerdef. Stylesheets vereinfachen kann.
Dienstag, 25.08.09 (20:20 Uhr)
Das neue Template-Tag ist absoluter Mumpitz! Wordpress sollte sich mal ein vernünftiges Template-System anschaffen. Wenn ich PHP-Methoden aufrufen muss, welche direkt ein HTML zurück- oder gar ausgeben, hat irgendwer was falsch verstanden. Damit bin ich bei WP schon einige Male auf die Nase gefallen.
Dienstag, 25.08.09 (20:29 Uhr)
Wer YAML mit Wordpress benutzt, wird doch sicher schlau genug sein, einfach get_body_class() zu nehmen.
Die Funktion mit der direkten Ausgabe ist für Leute gedacht, die sich sonst nicht weiter mit PHP beschäftigen wollen; niemand muß sie verwenden.
Dann kann man wegwerfen, was man nicht braucht, und umbenennen, was stört.
Alternativ setzt man auf den Hook body_class in der functions.php einen Filter.
Dienstag, 25.08.09 (23:06 Uhr)
body_class() sollte meines Achtens konfigurierbar sein. :) Aber ich nutze schon keine Wortpresse mehr, sondern bald ein eigenes System - mit YAML. :)
Dienstag, 25.08.09 (23:56 Uhr)
Ich finde es ja auch nicht toll, was WordPress bei body_class() und post_class() für einen Horror rausbläst. post_class() liefert auf einer Seite ebenfalls die Klasse page. Aber ich muß diese Funktionen nicht verwenden oder ich modifiziere sie.
Mittwoch, 26.08.09 (07:12 Uhr)
Interessant ist an dieser Stelle, dass Wordpress wohl unterschiedliche Wege nutzt um Klassen mit ihren Klassennamen auszugeben.
Ein Beispiel sind bei Wordpress die Widgets der Sidebar, wenn ich mir dort die automatisch gerenderten Klassennamen anschaue sehe dort ein namespacing-Verfahren.
Beispiel: “widget_tag_cloud, widget_text, widget_search, widget_pages”.
Warum denn dann nicht auch bei dem neuen Template-Tag?!
Mittwoch, 02.09.09 (12:56 Uhr)
Um kollisionen zu vermeiden und trotzdem den classennamen sinnvoll zu erhalten gibt es die einfache möglichkeit die classnames gross zu schreiben.
wenn also alle cms hersteller ihre standard classen gross machen würden gäbe es keine Kollision mit irgendwelchen css framworks oder einenen stylesheets.