Ajouter des ancres sur vos titres

See comments

Un bout de code PHP pour ajouter des ancres sur les titres HTML.

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 ?

Happy coding, Thomas Zilliox.

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 ?