¿Cansado de instalar plugins pesados solo para tener un simple índice en tus entradas? ¿Te molesta que cada plugin traiga opciones SEO, scripts innecesarios o banners publicitarios?
Aquí te enseño cómo crear un Table of Contents (TOC) simple y eficaz sin plugins, usando solo un poco de PHP.
Qué vamos a conseguir
Un índice como este que se genera automáticamente a partir de los títulos títulos (<h2>, <h3>, etc.) del contenido de tu post:
<div class="simple-toc">
<strong>Índice:</strong>
<ul>
<li><a href="#primera-seccion">Primera sección</a></li>
<li><a href="#otra-seccion">Otra sección</a></li>
</ul>
</div>
Todo esto sin instalar ni un solo plugin.
Paso a paso
1. Abre el archivo functions.php de tu child theme
Importante: nunca edites directamente el functions.php del tema principal. Usa un tema hijo o un plugin de snippets como “Code Snippets”.
2. Añade este código al final:
<?php
function insert_toc_from_headings($content) {
if (is_singular() && in_the_loop() && is_main_query()) {
preg_match_all('/<h([2-4])[^>]*>(.*?)<\/h\1>/is', $content, $matches, PREG_SET_ORDER);
if (!$matches) return $content;
$toc = '<div class="simple-toc"><strong class="simple-toc-title">Índice de contenidos</strong><ul class="simple-toc-list">';
foreach ($matches as $match) {
$level = (int) $match[1];
$text = strip_tags($match[2]);
$slug = sanitize_title($text);
// Añadir id al heading
$new_heading = preg_replace(
'/<h([2-4])([^>]*)>/i',
"<h$1$2 id=\"$slug\">",
$match[0],
1
);
$content = str_replace($match[0], $new_heading, $content);
// Clase de indentado según nivel
$indent_class = "toc-level-$level";
$toc .= "<li class=\"$indent_class\"><a href=\"#$slug\">$text</a></li>";
}
$toc .= '</ul></div>';
return $toc . $content;
}
return $content;
}
add_filter('the_content', 'insert_toc_from_headings');
?>
Este código analiza tu contenido y genera un índice si encuentra títulos <h2>, <h3> o <h4>.
Estilos opcionales (CSS)
Si quieres que se vea bien, puedes añadir este CSS en tu style.css o desde el personalizador:
.simple-toc {
background: #f9f9f9;
border-left: 4px solid #ccc;
padding: 1em;
margin-bottom: 2em;
font-family: sans-serif;
font-size: 0.95em;
}
.simple-toc-title {
display: block;
font-weight: bold;
margin-bottom: 0.5em;
font-size: 1.4em;
color: initial;
}
.simple-toc-list {
list-style: none!important;
padding-left: 0;
margin: 0;
}
.simple-toc-list li {
margin: 0.4em 0;
list-style: none!important;
}
.simple-toc-list li.toc-level-2 { margin-left: 1em!important; font-weight: 500; }
.simple-toc-list li.toc-level-3 { margin-left: 1.5em!important; font-weight: 400; }
.simple-toc-list li.toc-level-4 { margin-left: 2em!important; font-weight: 300; }
Consideraciones
- Solo se aplica a entradas o páginas individuales (is_singular()).
- No se recomienda en listados de entradas (home, categorías, etc.).
- Evita IDs duplicados y no requiere JavaScript.