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.
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.
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 ?