Thomas Zilliox
Expert CSS Freelance à Lyon

Ajouter des ancres sur vos titres

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.

Thomas ZILLIOX

That's my face!

Je suis un développeur CSS freelance sur Lyon.
En tant qu’expert CSS, on dit parfois que je suis « l’homme qui murmure à l'oreille des chevrons ».

Je suis également le co-créateur de Zupple Escape Game Lyon qui propose une salle d’escape game, des jeux de piste, des team building, de nombreuses énigmes en ligne, et même un podcast. Une aventure extraordinaire, grâce à laquelle il n’y a pas deux jours qui se ressemblent.