Table of Contents Plus

A powerful yet user friendly plugin that automatically creates a context specific index or table of contents (TOC) for long pages (and custom post types). More than just a table of contents plugin, this plugin can also output a sitemap listing pages and/or categories across your entire site.


Built from the ground up and with Wikipedia in mind, the table of contents by default appears before the first heading on a page. This allows the author to insert lead-in content that may summarise or introduce the rest of the page. It also uses a unique numbering scheme that doesn’t get lost through CSS differences across themes.

This plugin is a great companion for content rich sites such as content management system oriented configurations. That said, bloggers also have the same benefits when writing long structured articles. Discover how Google uses this index to provide ‘Jump To’ links to your content.

Includes an administration options panel where you can customise settings like display position, define the minimum number of headings before an index is displayed, other appearance, and more. For power users, expand the advanced options to further tweak its behaviour – eg: exclude undesired heading levels like h5 and h6 from being included; disable the output of the included CSS file; adjust the top offset and more. Using shortcodes, you can override default behaviour such as special exclusions on a specific page or even to hide the table of contents altogether.

Prefer to include the index in the sidebar? Go to Appearance > Widgets and drag the TOC+ to your desired sidebar and position.

Custom post types are supported, however, auto insertion works only when the_content() has been used by the custom post type. Each post type will appear in the options panel, so enable the ones you want.


Install / upgrade

Install the plugin by searching for Table of Contents Plus from the plugin add menu, or directly from the WordPress plugins repository.

There are no special upgrade instructions (woohoo!). Overwrite your existing folder with the latest or use the streamlined approach in the plugin menu. Your options will not be lost.


The simplest approach

For the impatient, all you have to do is enable the plugin.

The plugin will apply default settings and produce the table of contents before the first heading on pages (not posts, nor custom post types) with four or more headings.

No shortcodes are needed.

Where’s my table of contents?

  1. In most cases, the post, page or custom post type has less than the minimum number of headings. By default, this is set to four so make sure you have at least four headings within your content. If you want to change this value, you can find it under ‘Main Options’ > ‘Show when’.
  2. Is auto insertion enabled for your content type? By default, only pages are enabled.
  3. Have you got [ no_toc ] somewhere within the content? This will disable the index for the current post, page or custom post type.
  4. If you are using the TOC+ widget, check if you have the “Show the table of contents only in the sidebar” enabled as this will limit its display to only the sidebar. You can check by going into Appearance > Widgets.
  5. You may have restricted generation to a URL path match. The setting can be found in the advanced section under Main Options.

How do I stop the table of contents from appearing on a single page?

Place the following [ no_toc ] anywhere on the page to suppress the table of contents. This is known as a shortcode and works for posts, pages and custom post types that make use of the_content()

I’ve set wrapping to left or right but the headings don’t wrap around the table of contents

This normally occurs when there is a CSS clear directive in or around the heading originating from the theme (Twenty Eleven and Twenty Twelve are two themes which do this). This directive tells the user agent to reset the previous wrapping specifications.

You can adjust your theme’s CSS or try moving the table of contents position to the top of the page. If you didn’t build your theme, I’d highly suggest you try the Custom CSS plugin if you wish to make CSS changes.

Try adding the following CSS to allow the wrapping to occur around the table of contents:
h1, h2, h3, h4, h5, h6 { clear: none; }

How do I include the name of the page in the table of contents title?

As the title of the page changes depending on the page you’re viewing, you can use the following special variable to automatically insert the title of the page into the table of contents heading:


You can use it as is or place text either side of the variable.

As an example: if your page is named Great Expectations and your table of contents title is set to Contents for %PAGE_NAME%, the final title would read Contents for Great Expectations

My site has 100 pages but I only want the table of contents to appear on 10 of them

You could put [ no_toc ] on the 90 pages but that wouldn’t be fun… so try the following:

  1. Go to Settings > TOC+ and disable the auto insertion option for pages (or the content type you’re working with).
  2. Add [ toc ] onto the 10 pages that need them. Note that the table of contents will appear where you placed the shortcode.

Alternatively, you could also experiment with the restrict path option if the pages you want to include the index on all fall within a certain section of your site (eg /doc/).

I want to ignore certain headings

Use the ‘exclude headings’ option if you would like to ignore certain headings. Separate multiple headings with a pipe |. Use an asterisk * as a wildcard to match other text. Note that this is not case sensitive. Some examples include:

  • Fruit* ignore headings starting with Fruit
  • *Fruit Diet* ignore headings with Fruit Diet somewhere in the heading
  • Apple Tree|Oranges|Yellow Bananas ignore headings that are exactly Apple Tree, Oranges or Yellow Bananas

Can I have the table of contents in the sidebar?

Use the TOC+ widget and drag it into your desired position. If you want the table of contents to only be displayed in the sidebar, then make sure you tick that option in the widget.

Unlike Wikipedia, I want all my anchors to be lowercase and use hyphens rather than underscores

There are two options that allow you to adjust the casing and use of hyphens. If you still require more, you can massage it a little more by attaching into the toc_url_anchor_target filter. See the developers section for an example.

I would like to incorporate a sitemap

  1. Create a page for your sitemap (if you have an existing one, use that instead).
  2. Add [ sitemap ] into your page and save.

The above is the simplest example of integrating a sitemap listing all pages and categories. You can customise the sitemap options under Settings > TOC+ or check out some of the more advanced uses with the sitemap related shortcodes below.

You could also incorporate a sitemap using a text widget and pasting any of the sitemap shortcodes.

The sitemap uses a strange font dissimilar to the rest of the site

No extra styles are created for the sitemap, instead it inherits any styles you used when adding the shortcode. If you copy and pasted, you probably also copied the ‘code’ tags surrounding it so remove them if this is the case.

In most cases, try to have the shortcode on its own line with nothing before or after the square brackets.


The plugin was designed to be as seamless and painfree as possible and did not require you to insert a shortcode for operation. However, using the shortcode allows you to fully control the position of the table of contents within your page. The following shortcodes are available with this plugin.

When parameters are left out for the shortcodes below, they will fallback to the settings you defined under Settings > TOC+.

[ toc ]Lets you generate the table of contents at the preferred position. Also useful for sites that only require a TOC on a small handful of pages.
  • label: text, title of the table of contents
  • no_label: true/false, shows or hides the title
  • wrapping: text, either “left” or “right”
  • heading_levels: numbers, this lets you select the heading levels you want included in the table of contents. Separate multiple levels with a comma. Example: include headings 3, 4 and 5 but exclude the others with heading_levels="3,4,5"
  • exclude: text, enter headings to be excluded. Separate multiple headings with a pipe |. Use an asterisk * as a wildcard to match other text. You could also use regular expressions for more advanced matching.
  • class: text, enter CSS classes to be added to the container. Separate multiple classes with a space.
[ no_toc ]Allows you to disable the table of contents for the current post, page, or custom post type. 
[ sitemap ]Produces a listing of all pages and categories for your site. You can use this on any post, page or even in a text widget. 
[ sitemap_pages ]Lets you print out a listing of only pages.
  • heading: number between 1 and 6, defines which html heading to use
  • label: text, title of the list
  • no_label: true/false, shows or hides the list heading
  • exclude: IDs of the pages or categories you wish to exclude
  • exclude_tree: ID of the page or category you wish to exclude including its all descendants
[ sitemap_categories ]Similar to [ sitemap_pages ] but for categories. 
[ sitemap_posts ]This lets you print out an index of all published posts on your site. By default, posts are listed in alphabetical order grouped by their first letters. There are CSS classes for each section, letter and list allowing you to customise the appearance.
  • order: text, either ASC or DESC
  • orderby: text, popular options include “title”, “date”, “ID”, and “rand”. See WP_Query for a list.
  • separate: true/false (defaults to true), does not separate the lists by first letter when set to false.

For developers

How do I customise my anchors?

If you’re still not happy with the anchors, you can modify them to suit your needs through a custom function hooked into the toc_url_anchor_target filter. As an example, place the below code snippet into your functions.php file to convert all anchors to uppercase.

function my_custom_anchor( $anchor )
	return strtoupper( $anchor );
add_filter( 'toc_url_anchor_target', 'my_custom_anchor' );

toc_get_index( $content = ”, $prefix_url = ” )

Returns a HTML formatted string of the table of contents without the surrounding UL or OL tags to allow the theme editor to supply their own ID and/or classes to the outer list.

Both parameters are optional:

  • $content is the entire content with headings. If blank, will default to the current content found in $post (eg within “the loop”).
  • $prefix_url is the URL to prefix the anchor with. If a string was provided, it will be used as is. If set to “true” then will try to obtain the permalink from the $post object.

These examples assume you are within “the loop”:

  1. Obtain the index for the current page
    echo '<ul id="my_toc">' . toc_get_index() . '</ul>';
  2. Create a listing of all children and their headings
    $children = new WP_Query(array(
    	'post_parent' => get_the_ID(),
    	'posts_per_page' => -1	// get all children
    while ( $children->have_posts() ) {
    		'<h3>' . get_the_title() . '</h3>' .
    		'<ul>' . toc_get_index( get_the_content(), get_permalink( $children->post->ID ) ) . '</ul>'

Versioning scheme

I have adopted the same Ubuntu versioning scheme so the first release is 1107.

Other releases in the same month will be dot releases, eg the second release in July 2011 is 1107.1.

I love it, how can I show my appreciation?

If you have been impressed with this plugin and would like to somehow show some appreciation, rather than send a donation my way, please donate to your charity of choice. Feel free to leave a short note here if you’d like.

I will never ask for any form of reward or compensation. Helping others achieve their goals is satisfying enough 🙂

Questions or suggestions?

If you have questions or suggestions, please place them below.

1,136 thoughts on “Table of Contents Plus

    • Mike T says:

      I use Firefox as my main browser and that screenshot was taken using it. If it indeed is happening only in Firefox for you, then perhaps a Firefox extension is doing something?

  1. No, it’s still there. 1-6 are the headlines and then it’s starting again. I have seen this on other pages on my Blog as well but just a few of them. Any idea?

    1 Unsere Lieblingsstrände und -buchten auf Mallorca
    2 Cala Tuent
    3 Cala Deià
    4 Puerto Sóller
    5 Platja des Coll Baix
    6 Platja es Trenc

    7 Unsere Lieblingsstrände und -buchten auf Mallorca
    8 Cala Tuent
    9 Cala Deià
    10 Puerto Sóller
    11 Platja des Coll Baix
    12 Platja es Trenc

    • Mike T says:

      I checked the link you provided but it looked OK to me. Did you find out what was causing the problem?

  2. Ellen says:

    Hi, as far as I can tell this has been asked before, but either the replies were lacking or not explanatory enough for me (sorry!). Is it possible to get posts to be ordered by category rather than alphabetically? I’m afraid I’m a bit lost on this one. Thank you!

  3. Steve says:

    Hi Mike
    It’s an excellent plugin
    One question. Is it possible to put a bit of space between the anchor points and the Heading. This is so the Headings don’t come up quite so close to the top of the page after you’ve clicked the link in the Table of Contents.

    • Mike T says:

      Have you tried enabling smooth scroll? It will automatically cator for the admin bar which is probably appearing above your heading as you click the link.

  4. soga says:

    I really like your plugin, but i have question

    how to implement your table of contents in blogger page? Because it seems to be very suitable in bloggers that I just created.

    Can you help me?

    • Mike T says:

      What’s a blogger page? (I’m thinking it’s either a listing of posts by a single author, or you meant Google’s Blogger).

      • Mike T says:

        Yeah that would be cool but Blogger is something that Google manages and provides. If there isn’t already something that automatically creates anchors to your headings for you, then you’ll have to suggest it as a feature. Happy to do it for Google if they want but they’ve got more than plenty of smart engineers to do so 🙂

    • Michael Tran says:

      Try to enable the smooth scroll option, and then adjust the offset if needed in the Settings > TOC+, advanced settings.

  5. Hi there,

    how can I disable the TOC on the sidebar in archives? I tried a lot of stuff, but nothing works. It always shows the TOC of the newest post in the archive…

    Thank you,

  6. Hi Mike,

    A very usful plugin, I must say. And it is available for free too!

    But I have a query bro. I use a plugin called Google XML sitemap on my blog already. So, will the sitemap function of this plugin cause any conflict with that plugin? Waiting for your reply.

    Arun Kallarackal

    • Mike T says:

      Yeah it should be fine. I can’t see any reason why they would conflict.

      XML sitemaps should just be a list of your posts/pages and not contain the contents anyway.

  7. Hi Mike. Thank you for creating such a greate plugin!
    I’d like to contribute for development of TOC+ if I could.
    Do you concider hosting the codes on any repository hosting websites like GitHub, BitBucket?

    • Mike T says:

      Currently I run my own private SVN repo to manage this stuff and no public repo outside of WordPress.

  8. This was so easy to install and set up however, being very new at this, I have a question. I clicked pages and posts, thinking it would bring up a list of my individual posts but it only was an index for what I had written on my “about me” page. What did I do wrong? Thanks for you help.

  9. Markus says:


    I’m using the avada theme with Fusion Builder. It TOC dosen’t work for some reason, is there any way to make it work? I have TOC activated on pages, posts and tried the shortcode. Its not working.Please help

    • Mike T says:

      I would suggest you ask the Avada theme guys to see if they are doing anything strange when applying or outputting the_content() as this plugin uses the_content WordPress filter to do its thing. Sometimes theme and plugin authors bypass using the_content() or strip out enqueued functionality altogether which obviously isn’t great for maximising compatibility.

  10. Dear Mike,
    I checked all the suggestions you make in case, one does not see the table, but I could not find a mistake: no no_toc shortcode, no path restrictions, enough headings etc., tried the toc-shortcode, no widget used…. And no error message. Just not appearing… Perhaps I missed a big activaton button? 😉
    Thanks for any idea, would really like to have it working.
    PS If of any help, it is

    • Mike T says:

      Were you trying to put an index on your homepage? If so, enable “include homepage” option from the advanced settings.

      I copied the content you had on your homepage directly into a post on my server and it worked.

  11. Mads says:


    Some of my TOCs are really long, 30+ items.

    Is it somehow possible to have more than one column in a TOC? (and thereby improve the layout of my pages)


  12. Hi,
    I like the flexability of your plugin and would like to use it on my site but the problem is the lack of support for pages paginated with the ‘nextpage’ tag. At present I have to use the “Extended Table of Contents (with nextpage support)” plugin but it lacks the ability to chose where to position the table. Any chance of adding this feature?

    • Mike T says:

      There are no current plans to add nextpage support. Attempting so may introduce too many variables, eg:

      1. how does the index appear (list or drop down)? Does it appear the same on every page? Others would want different treatments on first with the rest of the pages.
      2. if on a sub page, do you highlight the first heading of that page in the index?
      3. does the index appear as a list at the top of the sub page, but then as a drop down at the bottom? Or vice versa?
      4. what happens if your server setup does not support pretty URLs?
      5. do you add links for headings on the prev and next pages? Where, next to the list and/or the drop down?
      6. how will they be styled? Colour, background, list types, sizes, fonts, etc.
      7. if you used the [toc] shortcode to define the position of where you want the index, where will it appear on every other page?

      And at the same time it would feel like you’re fighting against WordPress rather than work with it.

  13. Michael, Thanks for this plugin. My wife is deeply interested in using it, but I am concerned that it hasn’t been updated, or at least validated to work, for 4.1.x. Do you have plans to do so? I’m pleased that you are still active in comments, though 🙂 Thanks for your time and efforts. It’s clear that a lot of people love ToC+. -TC

    • Mike T says:

      It definitely works on production 4.x (mostly 4.1.1) installations running government and private sites. There aren’t many things I can add to improve it, but I’ve been thinking about striping out the help tab to make translations easier. Which really is just a bump in tested version number – not much of a change. But give it a go – it hasn’t been forgotten, it’s pretty much used on each site I’ve overseen.

  14. Hi everybody,
    please I have an issue with sidebar widget… I cannot view it on the page… In addition I would like to know if is it possible to insert TOC lines in the template. Do you have a php string to insert in child theme?

    Many thanks

  15. Thanks for the plugin. I am using WP 4.1 . If I navigate to a particular location a new page is created.

    1. Problem

    the location displayed on the page is not the location I selected in the TOC. I have to scroll up all the way .

    2. Problem

    I cannot return to the TOC easily. Neither the navigation arrow b rings me back nor the TOC is shown on the generated page.

    Please comment

    • Michael Tran says:

      Got a link? I’m using 4.1 everywhere and it’s OK for me.

      Not sure what you mean by a new page is created. The plugin does not create any pages.

      Check your console and address any javascript errors. These would prevent scroll to and collapse/hide actions.

      • thx for the quick reply. Concerning “new page” more explanation. If I select a heading in the TOC a new URL is generated and the displayed page starts at the location I was navigating to. The TOC is not longer visible.

      • Mike T says:

        You’ve described how a HTML anchor works… They let you create jump points to sections within your current page. This plugin automatically creates anchors at each heading within your content. More at

        After you select a heading, you will be transported to the anchor within the content. The TOC usually stays where it was outputted, usually before the first heading. It does not follow you as you scroll down the page. Although, some people have made it that way using custom javascript and CSS. If that is your intention, you need someone with javascript/CSS knowledge and they should be able to do it for you with this plugin.

  16. Hello, your plugin is really great so thank you very much. At the moment the Table will jump right under the heading, so you cant see it anymore – I would like it to jump right above the heading, so that you can read it. Is it possible? Thank you in advance.

    • Mike T says:

      Do you have an admin bar or another persistant top bar? Try enabling smooth scroll which will automatically accomodate with the admin bar’s height. If you need more offset, it’s in the advanced area of the settings.


    Add A Class That Will Exclude Headings. Example: this will be excluded
    Here is schema you should add to the output also for indexing.



  18. You Should Add A Class That Will Exclude Headings. Example: this will be excluded
    Here is schema you should add to the output also for indexing.


  19. Would really like to see something like:


    Which would just show a list of links that are children of the current page.

  20. Karen Bennett says:

    Hi Mike, this is a great plugin. I have a small (I think) change request.

    Some characters in headings get converted to numbers in the TOC+ links. Two examples:
    en-dash (as in “Critique – Assignment”) gets converted to 8211
    apostrophe (as in “This week’s”) gets converted to 8217

    See for a live page where these two things happen.

    Would it be possible to do something to convert or suppress them, the way WordPress handles them when creating a slug from a post title?


  21. Mike I put this in the WP forum too but wherever you reply I’ll add a note to show you did so on the other. I’m investigating 15 plugins to handle long texts and I really really like yours. Lovely range of design options and lots of manual control – and bog simple shortcode! Great plugin.

    Question – I don’t understand about anchors. I know how they work in html but how does TOC+ use them? Why only 6?

    Additional comment. The really mega power lack in the pagination/ TOC plugins is search.
    Search shows this one single whopping search result – plus other results, maybe more than one long one. All I then know is my search term is somewhere in there – in 5 – 30 pages of a long article? Ctrl+ F X 5 – 30 times maybe on each of the pages of a number of long articles … plus trying several different site searches … oh pity.
    The plugin dev who could add an indicator to a search result, eg. adding the title of the virtual page which contains the term would be a major pioneer in this zone.

    • Mike T says:

      Hi Shan

      TOC+ automatically extracts HTML headings defined in your content window and any extra as provided by WordPress (e.g. other plugins may add extra bits of content). TOC+ then automatically inserts anchors next to each of the headings within the content and saving the author time and effort (it also updates automatically as headings change). TOC+ finally inserts an index of the headings at the position you specified (before the first heading by default).

      As defined in the HTML specification, you can only have a maximum depth of 6 with each having a different semantic meaning (H1 being most important, H6 least).

      Re last comment, as a plugin author, we have to work with what WordPress provides and it sounds like the search discoverability could be improved with better content paging awareness. This is a core feature of WordPress and sounds like a suitable bug/enhancement ticket to be raised with the core team.

      I’ve previously battled with what WordPress gives you. In my case, when a content is paged, then WordPress only provides the content for the current page so TOC+ only creates an index of headings for the current page and not the entire article. Many comments have requested support for obtaining all headings over all pages but it would be more difficult and may work against what WordPress provides natively.

      Hope that helps.

  22. Joe D says:

    Quick question for you. I use add_filter in functions.php to add some content to the_content (priority = 10). The TOC plugin does not appear to be parsing it – headers that appear in it do not appear in the TOC. I’m using the Genesis framework. Any suggestions?? Thanks!

    • Joe D says:

      BTW it’s because we’re using the sidebar widget, which does not appear to apply the the_content filters before it parses everything. So, the hack I found was simply to use apply_filters in toc.php, which seems sub-optimal. Definitely open to better/cleaner suggestions.

  23. Hey, love the plugin! Exactly what I needed! Is there a way to exclude entire categories from the sitemap? Say I’d want all posts to show up in my sitemap, except the ones in the “cake” category?

  24. Hello Mike,

    I made a ABC-contents and I used the sitemap-pages shortcode. In my german language the umlaut marks are not correct.

    Is it changeable? Is so, how?
    In the plugin-editor are some files (table-of-contents-plus/toc.php, …/admin.js, …/admin.css, …/readme.txt, …/screen.css and …/front.js).

    Thanks for your help.

    Regards, Kersten

  25. I have a feature request: could you please add a hide toc initially option to the [toc] shortcode? Because some of my TOC’s are very long and might scare people away from the page if I show them initially

  26. Hi thanks for the great plugin…

    There’s a small bug, I’m using the [toc] shortcode and when “Hide the table of contents initially” is unchecked it actually hides the TOC, and when I check it, it shows the TOC, should be the other way around.

  27. Hi !

    I’m trying to use your plugin but I can’t…I thought it came from my wordress theme but here is what the author say :

    “I’m trying to add a shortcode like in the sharing.php with this plugin installed : but it won’t work…
    The toc shortcode works well inside the post edit…”

    The Author :
    “How does it not work? Is there an error? Do you have a live URL with an example?”

    Me :
    “There is no error…just, when I try to add into the sharing.php file, nothing happen but it works well into the the blog content
    here my URL :
    and on the attach file the code.
    I’ve put the toc shortcode at the end in order to let you see what I want in my left side bar ”

    The author :
    “I see that code outputting a comment in the code…

    But there’s no other content. You may need to check with the developer of that plugin to make sure you’re using the correct method for the do_shortcode() function.”

    Is there a way to make it works ?

    Thank you !

  28. Thanks for this plugin! I’m using it on the new educational site, Learn HTML With Song (

    I was wondering if there was a way to exclude not text, but specific categories from the TOC? That way we could have a category for any posts that are not tutorials (e.g. new music videos, free classes) and have the plugin exclude them. Otherwise, we’d have to manually remove each non-tutorial post, since their headers will be unique to the content of the post.

  29. Pingback: Round up of the best free SEO Tools for 2015 | Blooming SEO Blog

  30. mark says:


    Is there any way to start a single post with the TOC ‘hidden’?

    I know you can start the TOC shown or hidden with the site wide setting, but the problem I have is I want it showing on every post to begin with except for one.

    I’ve just finished an ‘epic guide’ that’s over 10k words and the TOC is just too large to be shown by default requiring a lot of scrolling to get past. So I’d prefer it to be started hidden on this one post only.

    Is this possible at all?

  31. scotty501 says:

    I love this – I have been trying to get something working for a while now and this almost does it out of the box. I would like to be able to have the results displayed as a drop down menu. As I add more content the box is going to become very long. Any ideas how I could do that?

  32. I absolutely love this plugin. However, when I change the color of the table of contents in the settings, it doesn’t change the color of the table of contents.

    I have it in my sidebar, is that why the color doesn’t change?

  33. You developed a great plugin! I am trying to promote the use of WP to publish art historical research, so [toc] is really very helpful. By the way, I donated a campaign of one of the humanitarian organisations in the Netherlands. 🙂

  34. Hello i use [sitemap_posts separate="false" orderby="date"] and before each post there is square what i need to put in the code to get numbered list before post title instead of square bullets ?

Comments are closed.