In this short article, I’ll show you how I made my sitemap (not to be confused with sitemap.xml) of my website.
For Tweaking4All I just wanted a list of all pages, and all categories with the posts listed underneath it. The reason why I wrote my own code is pretty simple: Everything I could find out there on the Internet only showed first level posts and categories, or made a flat list out of it, or skipped duplicates. This list however maintains the actual hierarchy, and if a post occurs in multiple categories then this will reflect this as such.
With a simple tiny bit of code and your own customized CSS, things can be pretty easy.
WordPress code for a HTML sitemap
Creating a list of all Pages
Let’s first create a list of all Pages, it’s probably the easiest thing to do.
In the code below you will see that I assigned the CSS class “your_pages_list_class” – you can obviously rename this to anything you’d like. The point being that this class will give you the option to modify the look of this list (UL), it’s list items (LI), and items in the list, for example links or icons.
Note that if you’d like to exclude certain pages, then you can add their ID’s to line 6.
This list will only show top-level pages, alphabetically sorted. You can expand the depth (line 8) if you have pages with sub-pages.
This code goes into the “page.php” file (for example) – or where ever you’d like to see this list.
// Add Page ID's you'd like to exclude in the exclude below
'exclude' => '',
'title_li' => '',
'depth' => 1
Creating a list of Categories and Posts
For the generation of this list, I’ll be using recursion (here: a function that calls itself), so I need to put it in a function. This is not only needed for recursion but it makes it also nice and clean to put in your template.
This function generates an unordered list (ul) with the items in a category being an unordered list (ul) inside the list item (li). A simple example of what the structure will look like:
<li>Sub Category 1.1
<li>Post 1 in 1.1</li>
<li>Post 2 in 1.1</li>
<li>Post 3 in 1.1</li>
<li>Post 1 in 1</li>
<li>Post 2 in 1</li>
... etc ...
For this we use the following “call” in our template file (I used mine in page.php – but you can use it where ever you’d like);
The “$exclude” variable can be empty (”) or contain a list of category ID’s you do not wish to see in this list.
The Function to generate the Category and Posts list
Below you will find the code I used to generate the list of Categories and Posts – place this code in your “functions.php” file.
As you can see, I added the CSS class “your_category_list_class” and “your_posts_in_category_list” to give you the possibility to make it look and feel the way you prefer. Feel free to modify as needed.
As you can see in line 17 – This function calls itself again to see if there are sub-categories.
The process is simple:
- Get all categories in the active category ($startnode).
- For each category, display title and link, and get all categories in this category (line 17) and process these the same way as the active category.
- For each category get all posts (line 19) and display a list with all titles and links.
The recursion takes place in step 2 where it repeats the steps 1, 2, and 3 for the sub-category. When done with the function call in the recursion (step 2), it will return and continue with step 3.
$categories_in_this_category = get_categories('parent='.$startnode.'&hierachical=1&hide_empty=0&exclude='.$exclude);
echo '<ul class="your_category_list_class">';
foreach ($categories_in_this_category as $this_category)
$link = esc_url( get_category_link($this_category->cat_ID) );
// Output category link
echo '<li><h4><a href="'.$link.'">'.$this_category->cat_name.'</a></h4>';
// Get sub categories
// Get posts in this category
$post_in_this_category = get_posts('category='.$this_category->cat_ID.'&posts_per_page=-1&order=ASC');
// Output posts
echo '<ul class="your_posts_in_category_list">';
foreach($post_in_this_category as $a_post)
$post_title = $a_post->post_title;
echo '<li><a href="'.get_permalink($a_post->ID).'">'.$a_post->post_title.'</li>';