Html4ify: valid HTML 4.01 Strict met Ruby on Rails
De uitdaging
Na een verhitte flamewar over de voor- en nadelen van XHTML tegenover HTML op onze interne mailinglist een paar weken geleden, durfde ik natuurlijk geen XHTML 1.1 meer te gebruiken en koos daarom maar voor HTML 4.01 Strict[1].
Ik ben redelijk neurotisch in het produceren van valide HTML-code; het stoorde me dan ook dat de HTML-code uit mijn huidige applicatie niet valide was toen ik het HTML 4.01 Strict doctype gebruikte. Zoals je wellicht weet zijn “self-closing tags” één van de zaken die XHTML onderscheid van HTML. De volgende code is bijvoorbeeld XHTML niet valide:
<link href="style.css" media="screen" rel="Stylesheet" type="text/css">In XHTML zou deze tag “self-closing” moeten zijn, wat er zo uitziet:
<link href="style.css" media="screen" rel="Stylesheet" type="text/css" />En, je voelt hem al hangen, Ruby on Rails genereert standaard XHTML-valid code, waardoor mijn validaties bleven falen.
Het idee
De standaard tag-methode in Rails accepteert een boolean argument “:open” dat regelt hoe tags gesloten worden. “true” voor HTML 4 valid tags, “false” voor XHTML valid tags. Deze tag-methode wordt door stylesheet_link_tag gebruikt om de uiteindelijke link-tag op te stellen, maar helaas kan aan deze method alleen een Hash van options worden meegegeven. Het volgende werkt dus niet:
<%= stylesheet_link_tag “style.css”, true %>
Naast het feit dat het niet werkt is het ook niet echt DRY om dit argument overal toe te voegen, dat moest dus anders kunnen!
Enter Html4ify
Na wat overleg met Remco van ‘t Veer besloten we hier een kleine plugin voor te maken, die simpelweg de Rails-methode die verantwoordelijk is voor het genereren van HTML-tags vervangt. Een kind kan de was doen.
Elke HTML-tag die nu door Rails wordt gegenereerd (meta, link, img, …) heeft nu geen slash meer op het einde. Ik blij, de W3C Validator blij. Win-win!
Omdat we als developers van het type “liever lui dan moe” ook niet telkens de DTD in onze views willen hoeven typen, heb ik daar maar meteen een method voor geschreven.
De volgende code:
<%= doctype %>
Levert een DTD op voor HTML 4.01 Strict. Optioneel kan een type worden meegegeven, zodat het ook mogelijk is om HTML 4.01 Transitional en HTML 4.01 Frameset DTD’s te genereren:
<%= doctype :loose %> # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" # "http://www.w3.org/TR/html4/loose.dtd"> <%= doctype :frameset %> # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" # "http://www.w3.org/TR/html4/frameset.dtd">
Installatie van deze plugin is “sweet ‘n simple”.
Op een *nix platform, in de root van je applicatie:
./script/plugin install http://rails.finalist.com/plugins/html4ify
En onder Windows, in de root van je applicatie:
ruby script\plugin install http://rails.finalist.com/plugins/html4ify
En dat is het!
[1] Wellicht verandert dit in de toekomst nog, als het XHTML-kamp alle HTML-evangelisten heeft uitgeroeid
———————————————————————————–
Meer weten over Ruby-specialist Finalist IT Group?



Even wat achterliggende info, niet als negatief commentaar, maar als aanvullende kennis.
Ten eerste termgebruik. Er is een belanrijk verschil tussen tags en elementen. Een element is het geheel van starttag, sluittag, content en attributen. Vooral in html zijn tag en element heel verschillende dingen, die je wellicht in de war kunnen brengen als je op DOM niveau (javascript) ermee omgaat. Sommige elementen hebben bijvoorbeeld geen sluittag, zoals meta, img en link. Dat zal de meesten wel bekend zijn. Er zijn ook elementen die helemaal geen tags hoeven te hebben. Zo zijn (in html) de tbody tags niet verplicht, maar het element is er altijd. Ook zijn de tags van het html en body element niet verplicht. Ook die elementen zijn er altijd, ook al hoeven de tags niet in je source te staan.
Een tweede is validatie, de html 4.01 validator is zeker niet heilig. In SGML, waar html 4.01 op is gebaseerd, is het mogelijk om elementen op een manier af te sluiten wat syntactisch erg lijkt om de xml empty element tag constructie. iets als foo en . Probleem is alleen dat geen enkele grote browser dit geimplementeerd heeft. Het zou xhtml syntax overigens ook niet backwardss compatible maken, want dan zou die ene laatste “>” als data worden getoond (na een plaatje bijvoorbeeld). Deze constructie staat bekend als SGML Null End Tag (NET).
Grtz
Rikkert - oktober 29, 2007 17:12
Ik ben benieuwd naar de discussie op de interne mailinglijst. Kun je een samenvatting geven?
jeroen - oktober 29, 2007 22:39
@ Rikkert: bedankt voor de info! Helaas kan ik het artikel niet meer editen om de termen aan te passen…
@ Jeroen: jazeker! De discussie begon toen één van de medewerkers de lijst een mailtje stuurde met een “reminder” om geen XHTML te gebruiken in productie-projecten. Hij gaf aan dat code pas écht XHTML is als het wordt geserveerd als “application/xhtml+xml”, maar Internet Explorer kan hiet niet mee omgaan. Vaak wordt daarom gekozen om een XHTML-document te serveren als “text/html”, maar daarbij wordt de code simpelweg geïnterpreteerd als HTML-code.
Resultaat: je hebt eigenlijk helemaal geen case-sensivity, geen namespaces en geen omgeving die “XML-aware” is. Je code is overgeleverd aan de gratie van de error-handling van je browser, die van de XHTML “tagsoup” wat moois moet maken.
De reacties hierop waren gemengd. De één vond dat de gebruiker “dan maar een echte browser moest gebruiken” (Firefox of Opera bijvoorbeeld), terwijl de ander zei dat “we geen producten voor onszelf maken”. Na wat heen-en-weer mailen was men het er wel over eens dat de klant beslist, maar dat het onze taak als developers is om de juiste keus te maken als de klant niet over genoeg technische kennis of inzicht beschkt om te beslissen.
Uiteindelijk is er geen sluitende conclusie getrokken, maar wellicht komt dat nog eens (met een biertje erbij ofzo ;-)). Ik denk in ieder geval dat het (met het ook op usablilty, accessability en compatibility) een wezenlijk onderdeel van ons werk als webontwikkelaars is om goed na te denken over wat je naar de gebruiker stuurt en ik vond het dan ook een interessante discussie op de lijst.
Marcel de Graaf - oktober 30, 2007 12:13
Leuk artikel Marcel!
Hebben jullie de validatie van jullie Rails views ook geautomatiseerd en zo ja hoe?
Cheers
Klaas Jan Wierenga - januari 2, 2008 16:09
Klaas Jan,
Bedoel je de validatie bij (bijvoorbeeld) de W3C Validation Service?
Marcel - januari 2, 2008 16:44
Wat ik bedoelde is of jullie de validatie inderdaad automatisch draaien als een soort continuous integration test. Zie bijv:
http://www.marklunds.com/articles/one/313
http://www.railslodge.com/plugins/431-assert-valid-markup
Klaas Jan Wierenga - januari 3, 2008 10:41