Thomas Zilliox
Intégrateur CSS Freelance à Lyon

Ajouter des ancres sur vos titres

Voir les commentaires

L'objectif

Sur ce blog par exemple, les titres contiennent des liens qui pointent sur eux-même. Cela me permet de pouvoir partager un lien qui dirige vers une section précise d'un article.

Même si vous n'en avez pas l'utilité, c'est une possibilité intéressante à donner à vos lecteurs.

Le code

Pour traiter l'HTML, j'utilise la classe DOMDocument native de PHP. Celle-ci fonctionne un peu comme le DOM en JavaScript. On retrouve les méthodes getElementsByTagName(), hasAttribute(), createElement(), etc. Mais elle a quelques particularités, par exemple il est impossible de récupérer simplement l'innerHTML.

Voici la fonction PHP finale :

function addAnchor($html, $addLink = true, $level = 2)
{
    $doc = new \DOMDocument();
    @$doc->loadHTML('<?xml encoding="UTF-8">' . $html);

    $hList = $doc->getElementsByTagName('h' . $level);

    // For every title node
    foreach ($hList as $h) {
        $title = $h->textContent;

        // Retrieve or generate an id
        if ($h->hasAttribute('id')) {
            $id = $h->getAttribute('id');
        } else {
            $id = slugify($title);
            $h->setAttribute('id', $id);
        }

        // Add a link
        if ($addLink) {
            $h->nodeValue = '';
            $link = $doc->createElement('a');
            $link->nodeValue = htmlentities($title);
            $link->setAttribute('href', '#' . $id);
            $h->appendChild($link);
        }
    }

    /* Only return body content */
    $stripHTML = ['/^\<\!DOCTYPE.*?<html><body>/si', '!</body></html>$!si'];
    return preg_replace($stripHTML, '', $doc->saveHTML());
}

function slugify($string)
{
    $string = trim($string);
    $string = str_replace(' ', '-', $string);
    $string = preg_replace('/[^A-Za-z0-9-]/', '', $string);
    return preg_replace('/-+/', '-', $string);
}

Bien-sûr la fonction slugify() utilisée ici est un peu simplifiée pour rendre l'exemple compréhensible.

Exemple

Voici un exemple simple d'utilisation :

$html = <<<EOF
<h2 id="objectif">L'objectif</h2>

<h2>Le code</h2>
EOF;

$html = addAnchor($html);

qui retourne :

<h2 id="objectif"><a href="#objectif">L'objectif</a></h2>

<h2 id="Le-code"><a href="#Le-code">Le code</a></h2>

Qu'est-ce que vous en pensez ?

Amusez-vous bien, Thomas.

comments powered by Disqus
That's my face!

Thomas ZILLIOX

L'homme qui murmurait à l'oreille des chevrons.

Je développe, j'intègre, je forme ou je conseille sur les CSS. Besoin d'améliorer la maintenabilité ou les performances de vos projets ?