Cómo añadir un índice de contenidos (TOC) en WordPress sin plugins
¿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.