WordPress Tutorial – Table of Contents in a Page

This tutorial will explain how to add a table of contents to a generic WordPress page. Our table of contents will be a list of posts in chronological order. This tutorial is a follow up to a comment on the post for my WordPress Table of Contents Widget by Ashley who indicated that she would be interested in the capability of having a table of contents in a page rather then the sidebar.

WordPress has the wonderful capability of allowing specific pages to have custom templates. In the initial version of Muse’s Success, we exploited this capability along with custom fields to generate the listing directory and listing detail pages.

Firstly, I would like you to make a copy of your default pages template. This file is usually named page.php, and located in /wp-content/themes/[name of your theme]/ directory of WordPress installation. Name this copy, table_of_contents.php, and open it in your favourite text editor.

Add the following to line 1 of your table_of_contents.php. It needs to be the first thing in your file.

1
2
<?php /* Template Name: Table of Contents
*/ ?>

Find:

1
<?php the_content('<p class="serif">Read the rest of this page &raquo;</p>'); ?>

This line may be slightly different, your basically looking for an instance of <?php the_content(‘…’). ?> Don’t worry about what the single parameter, if any.

Immediately after add:

This is the basic code to output post titles in chronological order. You can make slight variations of this, and it in general depends on how you’ve been naming your posts. In my experience, most authors are placing the chapter number and title in their WordPress post titles, so this example is geared towards these authors, but I will show some alternatives at the end of this tutorial.

1
2
3
4
5
6
7
8
9
<?php
global $post;
$post_save = $post;
$category_id = get_post_meta($post->ID, 'toc_category_id', true);
$toc = get_posts('numberposts=-1&category='.$category_id.'&order=ASC&orderby=date');
foreach($toc as $post) :
?>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><br />
<?php endforeach; $post = $post_save; ?>

Create the Page

Now, we have to create a WordPress page. You can do this by selecting Pages -> Add New in your WordPress Dashboard Menu. It’s up to you what you name your page, and what you write in the content area, but I would recommend the title is that of your book, and your content area contains a short introduction to your story (like what you would have on the blurb of a print book).

Select the Custom Template

Before you publish your page, we have a few special things we need to do to make the table of contents appear. You’ll need to select the Table of Contents template in the Attributes section (lower right) of the Add Page page as depicted.

Page Attributes Screenshot

Set the Custom Field

Next, we have to add a custom field. Custom fields can be added below the page content area. Name your custom field “toc_category_id” and set the value to the ID number of the category containing your posts. You can find the ID out by going to the Edit Categories (Dashboard menu -> Posts -> Categories) page, and clicking Edit under the category containing the posts that comprise your story. On the Edit Category page, take a look at your address bar, and you’ll see the text &cat_ID=. The number after the equals sign is your category ID.

Custom Fields Screenshot

Click Add Custom Field, and then Publish, and you’re done. If all went well, when you view the page you just created, you should see your new table of contents.

Using an ordered list instead

Earlier, I mentioned that there are other variations of the code that are suited to different post naming schemes. The one I showed earlier was a basic one title after another list using linebreaks.

If you are one who names their posts solely the name of your chapter with no number, you might like to use an ordered list to automatically add the chapter number for you.

1
2
3
4
5
6
7
8
9
10
11
<ol>
<?php
global $post;
$post_save = $post;
$category_id = get_post_meta($post->ID, 'toc_category_id', true);
$toc = get_posts('numberposts=-1&category='.$category_id.'&order=ASC&orderby=date');
foreach($toc as $post) :
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; $post = $post_save; ?>
</ol>

Those knowing CSS (and respecting semantics) but naming their chapters with number and name might also want to use the above code, but use CSS to hide the numbers in visual browsers.