$headings = [];
$headings_counter = 0;

/**
 * Extracts and builds TOC.
 *
 * @param string $content Post content.
 *
 * @return string
 */
function dorzki_build_tocbuild_toc( $content ) {

	$content = preg_replace_callback( '/<(h2)>(.*?)<\/h2>/i', 'dorzki_extract_headings', $content );

	$toc = dorzki_generate_toc();

	$content = $toc . $content;

	return $content;

}

add_filter( 'the_content', 'dorzki_build_toc' );


/**
 * Adds title id number and saves the heading.
 *
 * @param array $match Regex match array.
 *
 * @return string
 */
function extract_headings( $match ) {

	$tag = sprintf( '<%1$s id="title_%2$s">%3$s</%1$s>', $match[1], $headings_counter, $match[2] );

	$headings_counter++;
	$headings[] = $match[2];

	return $tag;

}


/**
 * Generates a table of contents from the headings.
 *
 * @return string|boolean
 */
function dorzki_generate_toc() {

	if ( empty( $headings ) ) {
		return false;
	}

	$html = '';

	$html .= '<div class="post_toc">';
	$html .= '  <strong>' . esc_html__( 'Table of Contents', 'dorzki' ) . '</strong>';
	$html .= '  <ol>';

	foreach ( $headings as $id => $text ) {

		$html .= "<li><a href='#title_{$id}'>{$text}</a></li>";

	}

	$html .= '  </ol>';
	$html .= '</div>';

	return $html;

}

Credit: dorzki.co.il

How to use it?

Usually adding functionality to a WordPress site is by creating a plugin.
However you can simply copy the code and paste it in your child theme’s functions.php file at the end of the file, just before ?>.

For JavaScript code you will need to add them to your theme’s main JavaScript file.

Having issues with the code?

If the code doesn’t work or you get an error please let us know in the comments section.
We will do our best to fix it as-soon-as-possible and update the code on this page.

Comments

  1. Sam

    Wow, it will look like Wikipedia.
    Truly useful…

    Reply
  2. Till

    Hey – great one, is there an option to disable it for specific pages….exclude pages option?
    cheers

    Reply
    1. Dor Zuberi

      Hello Till,
      You can download this code as a plugin, and then if you will add the shortcode [disable_toc] to the page or post content it will not generate table of contents.

Leave a Reply