Inclure une table des matières dans WordPress

Inclure une table des matières dans un long article ou une longue page WordPress peut être utile pour faciliter la navigation et, paraît-il, c'est bon pour le référencement.

Même si personnellement, le référencement, n'est pas du tout ma priorité principale. Je ne cherche pas forcément à être super connu, à la différence d'un site web pro, qui est le gâgne pain de son auteur.

Donc pour insérer un formulaire dans une page ou un article, je me suis inspiré du code de cet excellent tuto : Un sommaire pour vos articles, sans plugin que j'ai modifié pour mes besoins (un grand merci à l'auteur de ce blog).

Il suffit simplement d'ajouter le shortcode [sommaire] dans la page ou l'article concerné et, surtout, de structurer correctement la page.

On peut rajouter des numéros aux liens de la table des matières et(ou) aussi devant les tags h2, h3, h4 et h6. (h1, on ne s'en occupe pas, on part du principe qu'il n'y en a qu'un par page)

Le scrolling est effectué à l'aide du script jQuery Smooth Scroll.

1 Titre h2

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.1 Titre h3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.2 Titre h3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.2.1 Titre h4

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.2.2 Titre h4

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.3 Titre h3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.3.1 Titre h4

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.3.1.1 Titre h5

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.3.1.1.1 Titre h6

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

1.4 Titre h3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

2 Titre h2

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

2.1 Titre h3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

2.1.1 titre h4

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

2.1.1.1 titre h5

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

2.1.1.1.1 titre h6

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

2.1.1.1.2 titre h6

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

2.2 Titre h3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

3 Les fichiers de ce script

3.1 functions-sommaire.php

<?php
/**
 * functions-sommaire.php
 *
 * Génération d'une table des matières (à partir des titres Hx contenu dans la page)
 * h1 est ignoré (théoriquement il doit y en avoir qu'un par page)
 *
 * shortcode [sommaire] à insérer dans la page.
 *
 * Je me suis inspiré de ce tuto : https://wabeo.fr/sommaire-article-wordpress/
 */

define('NTH_NIVEAU_MAX', 6);
define('NTH_TDM_SEPARE_NUMBER', '.');
define('NTH_TDM_AFTER_NUMBER', ' ');
define('NTH_TDM_FORMAT_INDEX', '-%s');
define('NTH_TDM_PATTERN', "/<h([2-".NTH_NIVEAU_MAX."])(.*?)>(.*?)<\/h([2-".NTH_NIVEAU_MAX."])>/i");

function nth_clean_text_link($t) {
	return str_replace(['«', '»'], ['', ''], $t);
}

function nth_clean_anchor($c) {
	return str_replace('_', '-', sanitize_title($c));
}

$nth_ccc = 0;
function nth_replace_tag($matches) {
	global $tbl_index_anchor, $nth_ccc, $num_tag;
	$numerotation = ($num_tag) ? '<span class="numerotation-tag-h'.$matches[1].'">'.$tbl_index_anchor[$nth_ccc]['number'].'</span>' : '';
	$new_tag = '<h'.$matches[1].$matches[2].' id="'.$tbl_index_anchor[$nth_ccc]['anchor'].$tbl_index_anchor[$nth_ccc]['index'].'">'.$numerotation.$matches[3].'</h'.$matches[4].'>';
	$nth_ccc++;
	// test('<span style="white-space: pre-wrap;">'.htmlspecialchars($new_tag).'</span>', 't=$tdm&l='.basename(__FILE__).':'.__LINE__.' ');
	return $new_tag;
}

function add_anchor_content($content) {
	global $post;
	$content = preg_replace_callback(NTH_TDM_PATTERN, 'nth_replace_tag', $content);
	return $content;
}

add_shortcode('sommaire','nth_generate_table_contents');
/**
 * shortcode : sommaire
 * paramètres :
 * class    : (défaut '') class appliquées sur tag <nav> ex. class="toto titi"
 * style    : (défaut '') styles appliqués sur tag <nav> ex. style="width: 50%;"
 * num_link : (défaut 1) la numérotation (si définie) sera comprise dans le lien
 * num_tdm  : (défaut 1) numérotation table des matières
 * num_tag  : (défaut 0) numérotation devant les titres hx
 */
function nth_generate_table_contents($atts) {
	global $post;
	global $tbl_index_anchor, $num_tag;

	extract(shortcode_atts(array(
		'class' => '',
		'style' => '',
		'num_link' => 1,
		'num_tdm' => 1,
		'num_tag' => 0
		), $atts));

	add_filter('the_content', 'add_anchor_content', 12);
	preg_match_all(NTH_TDM_PATTERN, $post->post_content, $matches);
	// test($matches[3], 'h=200&t=$matches[3]&l='.basename(__FILE__).':'.__LINE__.' ');
	// test($matches[1], 'h=200&t=$matches[1]&l='.basename(__FILE__).':'.__LINE__.' ');

	$tbl_index_anchor = array();
	foreach (array_reverse($matches[3]) as $c1 => $ti) {
		$tbl_index_anchor[$c1]['titre'] = $ti;
		$tbl_index_anchor[$c1]['anchor'] = nth_clean_anchor($ti);
	}

	/**
	 * ajout d'un index aux ancres si plusieures identiques
	 */
	foreach($tbl_index_anchor as $row) {
		$new_array[] = $row['anchor'];
	}
	$tbl_temp = array_count_values($new_array);
	// test($tbl_temp, 'h=200&t=$tbl_temp&l='.basename(__FILE__).':'.__LINE__.' ');

	foreach ($tbl_index_anchor as $x => $ttt) {
		if ($tbl_temp[$ttt['anchor']] == 1) {
			$tbl_index_anchor[$x]['index'] = '';
		}
		else {
			// plus d'une occurence du titre dans la page
			$tbl_temp[$ttt['anchor']] = $tbl_temp[$ttt['anchor']] - 1;
			$tbl_index_anchor[$x]['index'] = sprintf(NTH_TDM_FORMAT_INDEX, $tbl_temp[$ttt['anchor']]);
		}
	}
	unset($tbl_temp);
	$tbl_index_anchor = array_reverse($tbl_index_anchor);

	/**
	 * Génération numéro index
	 * Afficher dans la table des matières (paramètre shortcode num_tdm à 1)
	 * Afficher devant les titres Hx de la page (paramètre shortcode num_tag à 1)
	 */
	if ($num_tdm || $num_tag) {
		$format = array();
		$chaine = array();
		$tbl_args = array();

		for ($i = 0; $i < NTH_NIVEAU_MAX - 1; $i++) {
			$chaine[$i] = '%s';
			$format[$i] = implode(NTH_TDM_SEPARE_NUMBER, $chaine).NTH_TDM_AFTER_NUMBER;
			// test($format[$i], 't=$format[$i]');
			$tbl_niveau[$i] = 0;
		}
		foreach ($matches[3] as $h => $titre) {
			$idx = $matches[1][$h] - 2;
			$tbl_niveau[$idx]++;
			for ($j = 0; $j < $idx + 1; $j++) {
				$tbl_args[$j] = $tbl_niveau[$j];
			}
			$tbl_index_anchor[$h]['number'] = vsprintf($format[$idx], $tbl_args);
			if ($matches[1][$h] != NTH_NIVEAU_MAX) {
				if (isset($mem) && $mem != $matches[1][$h]) $tbl_niveau[$idx + 1] = 0;
				$mem = $matches[1][$h];
			}
		}
	}

	/**
	 * Génération de la table des matières
	 *
	 * <nav id="nth-sommaire" role="navigation" ... >
	 *   <ul>
	 *     <li class="nth-niveau-X">
	 *       <a href="#mon-titre">Mon titre</a>
	 *       ......
	 *     </li>
	 *   </ul>
	 * </nav>
	 */
	$tdm = '';
	$tbl_class = [];
	$chn_style = '';

	if (!empty($class)) $tbl_class[] = $class;
	$tbl_class[] = 'nth-margin-bottom';

	if (!empty($style)) $chn_style .= $style;
	// $chn_style .= 'border: 1px solid red;';

	$attr_nav = [];
	$attr_nav[] = 'id="nth-sommaire"';
	$attr_nav[] = 'role="navigation"';
	if (!empty($tbl_class)) $attr_nav[] = 'class="'.implode(' ', $tbl_class).'"';
	if (!empty($chn_style)) $attr_nav[] = 'style="'.$chn_style.'"';
	$tdm .= '<nav';
	if (!empty($attr_nav)) $tdm .= ' '.implode(' ', $attr_nav);
	$tdm .= '>';
	// test('<span style="white-space: pre-wrap;">'.htmlspecialchars($tdm).'</span>', 't=$tdm&l='.basename(__FILE__).':'.__LINE__.' ');
	$tdm .= '<ul>';
	foreach ($matches[3] as $h => $titre) {
		$tdm .= '<li class="nth-niveau-'.$matches[1][$h].'">';
		$numerotation = ($num_tdm) ? '<span class="numerotation-tdm-'.$matches[1][$h].'">'.$tbl_index_anchor[$h]['number'].'</span>' : '';
		if (!$num_link) $tdm .= $numerotation;
		$tdm .= '<a href="#'.$tbl_index_anchor[$h]['anchor'].$tbl_index_anchor[$h]['index'].'">';
		if ($num_link) $tdm .= $numerotation;
		$tdm .= strip_tags(nth_clean_text_link($tbl_index_anchor[$h]['titre'])).'</a>';
		$tdm .= '</li>'."\n";
	} // end foreach ($matches[3] as $h => $titre)
	$tdm .= '</ul>';
	$tdm .= '</nav><!-- /nav#nth-sommaire -->';
	// test($tbl_index_anchor, 'h=200&t=$tbl_index_anchor&l='.basename(__FILE__).':'.__LINE__.' ');
	if (!is_singular())
		return '';
	else
		return $tdm;
}

3.2 sommaire.css

/**
 * Styles sommaire
*/
nav#nth-sommaire {
	line-height: 1.714285714rem;
	border: 1px solid #EDEDED;
	background-color: #F9F9F9;
	padding: 10px;
	display: table;
	font-size: 95%;
}

nav#nth-sommaire.align-left {
	float: left;
	margin-right: 20px;
}

nav#nth-sommaire ul {
	list-style: none;
	margin-bottom: 0;
}

/* spécial doc phpMyForm long sommaire */
nav#nth-sommaire.tdm-phpmyform {
	display: block;
	height: 300px;
	overflow: auto;
}

nav#nth-sommaire ul li[class*="nth-niveau-"] a {text-decoration: none;}

nav#nth-sommaire ul li[class*="nth-niveau-"] a span[class*="numerotation-tdm-"] {}
span.numerotation-tdm-2 {}
span.numerotation-tdm-3 {}
span.numerotation-tdm-4 {}
span.numerotation-tdm-5 {}
span.numerotation-tdm-6 {}

span[class*="numerotation-tag-h"] {}
span.numerotation-tag-h2 {}
span.numerotation-tag-h3 {}
span.numerotation-tag-h4 {}
span.numerotation-tag-h5 {}
span.numerotation-tag-h6 {}

nav#nth-sommaire ul li[class*="nth-niveau-"] {}
nav#nth-sommaire ul li.nth-niveau-2 {margin-left: 0px;}
nav#nth-sommaire ul li.nth-niveau-3 {margin-left: 30px;}
nav#nth-sommaire ul li.nth-niveau-4 {margin-left: 50px;}
nav#nth-sommaire ul li.nth-niveau-5 {margin-left: 70px;}
nav#nth-sommaire ul li.nth-niveau-6 {margin-left: 90px;}

Mis à jour le : 25/10/2018 18:41

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Sélection smileys

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.