W3C Validation for Drupal 7 HTML5 + RDFa

 

Overview

We've all seen the client requirement: "Must follow HTML5/CSS3 standards," often followed by some requirement for validation. If you try to run your Drupal 7 site through the normal validator at validator.w3.org you'll see a lot of problems. Many of the problems seem insolvable without major patches to Drupal core. So what do you do?

Turns out it's not as hard as you might think. This article will go through all the steps you need to help your Drupal 7 site validate.

Mike Potter, Software Architect
#Development | Posted

Overview

We've all seen the client requirement: "Must follow HTML5/CSS3 standards," often followed by some requirement for validation. If you try to run your Drupal 7 site through the normal validator at validator.w3.org you'll see a lot of problems. Many of the problems seem insolvable without major patches to Drupal core. So what do you do?

Turns out it's not as hard as you might think. This article will go through all the steps you need to help your Drupal 7 site validate.

Using the correct validator

The first step is to use the correct validation tool. The normal validator.w3.org only has experimental support for HTML5, and it does not support the RDFa metatags added by the D7 RDF module. You can try all of the different document type options, but you probably still won't find one that works. The solution is the "New" validator located at validator.w3.org/nu. Click on the Options button and select the Preset called "HTML5 + SVG 1.1 + MathML 2.0 + RDFa 1.1 + Microdata". Do not select the "RDFa Lite" version, be sure to select the full version. Run this on your site to get started.

Setting the correct DOCTYPE

Next make sure your web site is sending the correct DOCTYPE to the browser. You want to use a DOCTYPE of:

<span class="sy0"><!</span>DOCTYPE HTML<span class="sy0">></span>

for HTML5. Do not use the "HTML+RDFa 1.1" used by the Omega theme, for example.

In addition to setting the DOCTYPE, you also need to make some other changes to the HTML headers to generate the correct syntax for the RDFa 1.1 namespaces. The following code is used in the theme template.php file and can be adapted to other sites (NOTE: this code is based upon sub-theme of Omega. For other themes your mileage may vary)

  1. /**
  2.  * Implements hook_preprocess_html().
  3.  */
  4. function themename_preprocess_html(&$vars) {
  5. $prefixes = array();
  6. $namespaces = explode("n", trim($vars['rdf_namespaces']));
  7. foreach ($namespaces as $name) {
  8. list($key,$url) = explode('=', $name, 2);
  9. list($xml,$space) = explode(':',$key, 2);
  10. $url = trim($url, '"');
  11. if (!empty($space) && !empty($url)) {
  12. $prefixes[] = $space . ': ' . $url;
  13. }
  14. }
  15. $prefix = implode(" ", $prefixes);
  16. $vars['doctype'] = '<!DOCTYPE HTML>' . "n";
  17. $vars['rdf']->version = '';
  18. $vars['rdf']->namespaces = ' xmlns="http://www.w3.org/1999/xhtml" prefix="' . $prefix . '"';
  19. $vars['rdf']->profile = '';
  20. }

The main work of this code is to convert the old xmlns:name="http://url" syntax into the new prefix="name: url ..." syntax. It also removes the deprecated "version" and "profile" attributes.

Fixing markup from Drupal 7

The RDF module provides basic support for semantic web markup in Drupal 7. I often use the contributed RDF Extensions module to extend and provide a nice UI for configuring my meta tags. However, the generated markup often doesn't pass the script RDFa 1.1 requirements of the validation tool. In particular, it often generates blank attributes, such as datatype="". Rather than patching core, we can fix this as our theme preprocessing:

  1. /**
  2.  * Implements hook_preprocess_node()
  3.  */
  4. function themename_preprocess_node(&$vars) {
  5. unset($vars['title_attributes_array']['datatype']);
  6. }

Another problem is with Entities. Drupal can sometimes generate duplicate "classes" attributes and empty "typeof" attributes. Once again, a preprocess in template.php is a good solution:

  1. /**
  2.  * Implements hook_preprocess_entity()
  3.  */
  4. function themename_preprocess_entity(&$vars) {
  5. if (!empty($vars['classes_array']) && !empty($vars['attributes_array']['class'])) {
  6. unset($vars['attributes_array']['class']);
  7. }
  8. if (empty($vars['attributes_array']['typeof'])) {
  9. unset($vars['attributes_array']['typeof']);
  10. }
  11. }

Conclusion

You might run into other markup issues depending upon what other Drupal modules you are using. In most cases you can solve those issues via similar pre-processing tricks. Once you are done you should end up with a Drupal 7 site that passes the new validation tool with flying colors. If your client complains that you are not using the normal validator.w3.org tool, just let them know that it's an old tool and that only the new tool can properly check for HTML5 and RDF compliance. Hopefully Drupal 8 will generate even cleaner markup, but until then, feel free to embrace HTML5 and RDFa today!

Mike Potter

Software Architect