Tener un tabla de contenidos ayuda a la navegación de usuario y además es bueno para SEO, en este artículo veremos cómo crear una tabla de contenidos en WordPress sin usar plugins y que se genere de manera automática.
Para esto usaremos el código del repositorio de GitHub Genera tabla de Contenidos, que está preparado para trabajar con WordPress.
1- Estructura de nuestro contenido
Primero definimos la estructura, los títulos de nuestro contenido tendrán la etiqueta HTML h2, los subtítulos con h3, y si queremos otro nivel más con h4, por ejemplo:
<h2>titulo contenido</h2>
<p>Algún texto</p>
<h3>subtítulo contenido</h3>
<p>Algún texto</p>
2- Agregando el código javascript
Dependiendo del nivel de detalle que tenemos en nuestro contenido, h2, h3, h4, y lo que queremos mostrar en nuestra tabla, podemos usar un script para dos niveles o para tres niveles, en este caso asumiremos que tenemos un contenido a dos niveles por lo que usaremos el siguiente script:
(function($){
//Comprobación para que se ejecute sólo al ver el detalle de una entrada
if ( $('body.single').length ){
//Plantillas para la tabla
var tmplwrap ="<div id='tabla-contenido'>\n<p class='titulo'>Tabla de Contenido</p>\n{contenido}</div>";
var tmpllink = "<p {clase}><i class='fa fa-caret-right'></i> <a href={link}>{texto}</a></p>\n";
var cadena = "";
//Preparamos el segundo nivel para que tenga una clase
$('article h2').siblings('h3').addClass('n2');
//Bucle, recorremos elementos para construir la tabla
$('article h2, article h3').each(function(index, element){
clase = $(this).hasClass('n2')?'class="n2"':'';
texto = $(this).text();
enlace_id = texto.replace(/\d-\s|\?|¿/g,'');
enlace_id = enlace_id.replace(/\s+/g, '_');
$(this).attr('id',enlace_id);
//Agregamos en una variable cadena
cadena += tmpllink.replace('{link}',"'#" + enlace_id + "'");
cadena = cadena.replace('{texto}',texto);
cadena = cadena.replace('{clase}',clase);
});
//Ejemplo de link adicional, descomentar
//$('div.rel_posts h3').attr('id','relacionados');
//cadena +="<p><i class='fa fa-link'></i> <a href='#relacionados'>- Artículos relacionados</a></p>\n";
cadena = tmplwrap.replace('{contenido}',cadena);
//Finalmente insertamos la cadena antes del primer elemento
$(cadena).insertBefore( $('.entry-content h2').first() );
}
})(jQuery);
Tener en cuenta:
- En este mismo repositorio también se encuentra el script para tres niveles.
- Para insertar este código puedes revisar el artículo Insertar Javascript de manera correcta en WordPress
- Este código usa iconos de FontAwesome, puedes revisar Insertar una fuente de Iconos en WordPress
3- Agregando código CSS
Luego que obtenemos la tabla, y comprobamos su funcionalidad, podemos entonces agregar el código CSS para dar un aspecto visual más atractivo, usaremos el siguiente código:
#tabla-contenido{
background-color: #EDEDED;
max-width:600px;
padding:10px 20px 20px;
margin: 10px auto 30px;
border-radius: 5px;
}
#tabla-contenido p{
margin:0;
}
#tabla-contenido p.n2{
margin-left: 20px;
}
#tabla-contenido p.n3{
margin-left: 40px;
}
#tabla-contenido .titulo{
background-color: #D8D8D8;
padding: 2px;
margin-bottom: 10px;
border-radius: 5px;
width: 100%;
text-align: center;
font-size: 16px;
font-weight: bold;
}
4- Resultado Final
Finalmente luego de realizar estos pasos obtendremos algo similar a la siguiente imagen:

¿Aún con dudas?, en el siguiente video se explica cada uno de los puntos tratados anteriormente
Muy buen articulo, gracias es lo que estoy buscando. HAy algunos articulos que no tienen mucho contenido y no tiene sentido tener una tabla de contenido. Hay alguna manera de indicarle que solo aparezca cuadno tenga determinada cantidad de contenido?. Por ejemplo que solo se vea la tabla de contenido cuadno tenga 4
Hola, tendrías que colocar una condicional antes de llamar al bucle .each, puedes usar lenght, revisa:
https://api.jquery.com/length/
Por ejemplo:
Como hago que el SCROLL no LLEGUE HASTA ARRIBA cuando se selecciona un subtitulo , que baje un poco
Hola, en este artículo se deja el comportamiento de desplazamiento al navegador, si quieres otro comportamiento tendrías que hacerlo por javascript, específicamente sumando algunos pixeles a la función scrollTop(), revisa : https://api.jquery.com/scrollTop/
Hola, gran aportación y única. Esto de no usar plugins no esta nada extendido.
Me gustaría que la caja se contrajera como hace la del plugin TOC+, vamos que solo cquedase el titulo de la tabla y un link a mostrar. Me podrías ayudar o aconsejar como?
Hola Jonatan, lo revisaré, sin embargo creo que antes de hacer esto hay que acomodar un poco la estructura HTML para que sea más fácil mostrar/ocultar.
Hola, genial articulo es posible si se agrega solo a los post de una categoria?
Hola, para lo que comentas se tendría que cargar el código javascript condicionalmente, una opción sería que coloques el código en un nuevo archivo y luego registrar el script, pero al momento de ponerlo en cola validarlo para que sólo se muestre en una categoría. Revisa el punto 4 del siguiente artículo: https://decodecms.com/insertar-javascript-en-wordpress-de-forma-correcta/
Funciona pero pero en chorme , no funciona para mozilla a que se debe eso?
En el video uso Firefox, de hecho en este artículo verás que la tabla de contenidos funciona en firefox igualmente. Debe haber algo mal en tu código o algún conflicto js con algún plugin o con tu theme.
Como meto codigo php en Edit Snippet. Gracias!!!!!!
Hola supongo que te refieres a usar un plugin de snippets sin tocar functions.php, revisa: https://decodecms.com/agregar-codigo-a-tu-sitio-sin-usar-functions-php/
Como añado javascript solo puedo añadir php
Hola, claro, los plugins de ese tipo sólo permiten snippets PHP, para javascript, revisa: https://decodecms.com/insertar-javascript-en-wordpress-de-forma-correcta/
Hola , podria ayudarme ¿como haria para que aparezca la tabla de contenido en el segundo parrafo?
gracias
Hola, en la función insertBefore() puedes establecer en donde irá, en mi caso lo inserto antes del primer h2 que se encuentra y que sería equivalente al segundo párrafo.
hola como haria para insertarlo en el segundo h2? o en el segundo parrafo?
Hola, podrías probar con nth-child, revisa: https://api.jquery.com/nth-child-selector/
Hola mira estoy probando de hacerlo funcionar, pero no me da error ni se muestra nada nuevo, mi html generado es
texto
primer subtitulo
si uso
//Preparamos el segundo nivel para que tenga una clase
$(‘.extract h2’).siblings(‘h3’).addClass(‘n2’);
//Bucle, recorremos elementos para construir la tabla
$(‘.extract h2, extract h3’).each(function(index, element)
te parece que tengo algún error? por que probé con . y sin punto por si no detectaba la clase y no funciona, y el js lo veo importado bien en el header
gracias
Hola, de manera general lo veo correcto, supongo que estas usando comilla simple, no se si al enviar como comentario lo enviaste con otra comilla, prueba comilla doble. También asegúrate de que la clase .extract exista en el detalle de tu artículo.
Hola, gracias por contestar y si estoy usando comilla simple, recien probe con comillas dobles para seleccionar la clase y en el html que me genera tengo la etiqueta donde esta el texto del post
hola, no se me aparece en version de lista enumarada, gracias por la ayuda
Hola, los números tendrían que ser parte de los títulos ya que la estructura HTML que uso no es de una lista enumerada.