Je réalise actuellement un thème Drupal 6 en HTML5 et vient le moment de déclarer comme il se doit le charset du document. Sachant que Drupal 6 déclare une la balise meta destinée à un doctype XHTML, mon premier réflexe est d’appliquer une simple substitution depuis mon implémentation du hook theme_preprocess_page() :

1
2
3
4
5
6
7
8
9
10
11
<?php
/**
 * @file template.php
 */
function MYTHEME_preprocess_page(&$vars) {
  $vars['head'] = str_ireplace(
    '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
    '<meta charset="utf-8">',
    $vars['head']
  );
}

Mais le résultat n’est pas vraiment celui escompté.

Une meta Content-Type en trop pour mon thème HTML5

Voyez vous-même :

1
2
3
4
<!DOCTYPE html>
<html lang="fr">
  <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Ok, il y a bien une couille dans le pâté comme dirait l’autre. Mon charset XHTML est toujours là.

Note :
Certains modules comme Nodewords doublent la déclaration du charset. Ainsi la précédente substitution fonctionnera, mais un charset XHTML demeurera.

Une mesure de sécurité peu flexible

Il s’avère que pour prémunir toute attaque par charset, il a été décidé d’injecter en dur et de manière peu élégante la déclaration de charset depuis le core, dès la fin de la première balise ouvrante <head> rencontrée.
Tout cela se passe après le traitement du dernier hook disponible, avec l’appel à la méthode drupal_final_markup().

À première vu je l’ai dans l’os. Et ce ne sont pas les thèmes estampillés « Drupal 6 + HTML5 » qui me seront d’une grande aide puisqu’aucun ne génère un markup HTML5 valide. Vous pourrez vérifier, tous arborent la belle déclaration de charset XHTML, en plus de la déclaration HTML5 bien évidemment.

La solution

Voici l’astuce, que dis-je, le palliatif quick & dirty que j’ai utilisé pour obtenir un en-tête HTML5 valide : puisque la fonction drupal_final_markup() insère la déclaration de charset à la suite de la première balise <head> rencontrée, et bien je lui en donne une fausse a modifier :

1
2
3
4
5
<!DOCTYPE html>
<!--<head>-->
<html lang="fr">
  <head>
    <meta charset="utf-8">

Pour obtenir ma déclaration de charset HTML5 et rendre inactive la meta Content-Type de Drupal 6.

1
2
3
4
5
6
<!DOCTYPE html>
<!--<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />-->
<html lang="fr">
  <head>
    <meta charset="utf-8">

La substitution vu en début d’article est désormais inutile, je déclare mon charset directement dans mes templates.

Attention :
N’insérez jamais de commentaire avant la déclaration du doctype sous peine de faire basculer IE en quirks mode.

publicité (chargement)

4 réponses pour Drupal 6 : résoudre le problème du double charset dans un thème HTML5

  1. lionelB dit :

    Malin!

  2. Adrien dit :

    J’ai été confronté au problème du double meta charset il y a quelques jours. Je n’ai pas la problématique du HTML5 comme ici, mais il apparaît que le core de D6 a un bug qui génère cette double meta. Dans mon cas (en version 6.24), j’ai donc du appliquer le patch présent dans cette discussion -> http://drupal.org/node/451304#comment-6483206

  3. piouPiouM dit :

    J’avais croisé cette issue (ouverte en 2009 *sic*) mais je n’ai pas retenu ce patch pour plusieurs raisons :

    1. il concerne exclusivement XHTML hors je suis dans un environnement multi-thèmes (XHTML / HTML5).
    2. il applique 3 expressions régulières dont 2 sur l’intégralité du source en sortie lorsqu’une seule était lancée et s’arrêtait dès la première substitution effectué.
    3. j’évite de patcher le core lorsque cela est possible.

    Dans ton cas de double meta charset Adrien, le problème apparaît soit parce qu’un module l’ajoute, soit parce que tu en as défini un autre dans ton thème. Pour la première option, la solution la plus simple est d’implémenter le hook theme_preprocess_page() et de remplacer la meta insérée par un module :

    1
    2
    3
    4
    5
    6
    7
    8
    
    <?php
    function MYTHEME_preprocess_page(&$vars) {
      $vars['head'] = str_ireplace(
        "\n" . '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
        '',
        $vars['head']
      );
    }

    Pour la seconde possibilité, supprimer la déclaration de la meta Content-Type du thème sera plus efficace.

  4. Maarx dit :

    C’est quand je rigole devant des trucs comme ça que je me dis que je suis un vrai geek. x)

    En tout cas un bon patch digne d’un ingé Microsoft. :p

Ajouter un commentaire


Syndication

Réseaux sociaux