36 - Creating an HTML Sitemap in ExpressionEngine

In this chapter I’ll cover creating an HTML sitemap (for human consumption, vs. an XML version for search engine consumption) on the project Church site.

 
Download the EE Code for 36 - Creating an HTML Sitemap in ExpressionEngine

So over the years I’ve seen a number of comments in the ExpressionEngine Forums regarding HTML sitemaps and wondering why EE doesn’t have something built in.

The answer is there is nothing built-in because in order to do so you’d have to make a number of assumptions about how the site had been implemented and if categories or relationships had been used, etc.  Since EE doesn’t make any of those assumptions about the structure of your site, there’s no easy way to write a plug-in that would produce a sitemap.

Luckily, it’s not that hard to roll one yourself.

The overall approach that I’ve used is to just create a unordered list as a basic framework, then at each node on the list use whatever EE tag will return me the links I need in the format I need.  Usually it’ll be either the weblog entries tag or the category archive tag.  Mixed in with those tags will be some simpler links - for when the target section is just a one-pager.

The Result
So here’s what I’m building—just a simple vertical list type sitemap with links as deep into the content as it makes sense.  The order of items matches the main navigation.  In spots where there might be a ton of content (blog posts, audio messages etc) I’m just pulling the most recent few. 

The Code
See the companion files for the full download - but are the guts of the sitemap template:

<h2>Sitemap</h2>
            <
div id ="sitemap">
                <
ul>
                    <
li><a href="{homepage}">Home</a></li>
                    <
li><a href="{path='weblog'}">Weblog</a>
                        <
ul>
                            
{exp:weblog:entries weblog="weblog" disable="categories|custom_fields|trackbacks|member_data|pagination" limit="5" dynamic="off"}
                                
<li><a href="{url_title_path='weblog/comments'}">{title}</a></li>
                            
{/exp:weblog:entries}
                        
</ul>
                    </
li>
                    <
li><a href="{path='ministries'}">Ministries</a>    
                        
{exp:weblog:category_archive weblog="ministries" style="nested" id="not_used"}
                            {categories}
                                
<a href="{path='ministries/index'}">{category_name}</a>
                            
{/categories}
                            {entry_titles}
                                
<a href="{path='ministries/details'}">{title}</a><br />
                            
{/entry_titles}
                        {
/exp:weblog:category_archive}
                    
</li>
                    <
li><a href="{path='worship'}">Worship</a>
                        
{exp:weblog:category_archive weblog="worship" style="nested" id="not_used_either"}
                            {categories}
                                {category_name}
                            {
/categories}
                            {entry_titles}
                                
<a href="{path='worship'}">{title}</a><br />
                            
{/entry_titles}
                        {
/exp:weblog:category_archive}
                    
</li>
                    <
li><a href="{path='beliefs'}">Beliefs</a></li>
                    <
li><a href="{path='events'}">Events</a>
                        <
ul>
                            
{exp:weblog:entries weblog="events" show_future_entries="yes" disable="categories|custom_fields|trackbacks|member_data|pagination" limit="5" dynamic="off"}
                                
<li><a href="{url_title_path='events/details'}">{title} on {entry_date format="%F %d, %Y"}</a></li>
                            
{/exp:weblog:entries}
                        
</ul>
                    </
li>
                    <
li><a href="{path='photos'}">Photos</a>
                        <
ul>
                            
{exp:gallery:categories gallery="Photos"}
                                {category_row}
                                    {row}
                                        
<li><a href="{category_path='photos/category'}">{category}</a></li>
                                    
{/row}
                                {
/category_row}
                            {
/exp:gallery:categories}
                        
</ul>
                    </
li>
                    <
li><a href="{path='staff-directory'}">Staff Directory</a>
                        <
ul>
                            
{exp:weblog:entries weblog="staff-directory" disable="categories|custom_fields|trackbacks|member_data|pagination" dynamic="off"}
                                
<li><a href="{url_title_path='staff-directory/profile'}">{title}</a></li>
                            
{/exp:weblog:entries}
                        
</ul>
                    </
li>
                    <
li><a href="{path='audio-messages'}">Audio Messages</a>
                        <
ul>
                            
{exp:weblog:entries weblog="audio-messages" limit="5" disable="categories|custom_fields|trackbacks|member_data|pagination" dynamic="off"}
                                
<li><a href="{url_title_path='audio-messages/comments'}">{entry_date format='%F %d, %Y'{title}</a></li>
                            
{/exp:weblog:entries}
                        
</ul>
                    </
li>
                    <
li><a href="{path='contact-us'}">Contact Us</a></li>
                </
ul>
            </
div

The Build
Overall this is pretty straightforward stuff - building on templates that you’ve already created by now in this series.  I choose to create a new template group named “sitemap” and put this code into the index template - mostly for URL reasons.  I could have put a new template in the default group, but in my case it’s called site and then I have a URL of /index.php/site/sitemap - which I didn’t like.

You’ll note some odd ID’s on the category:archive tags.  I wanted these returning links in a nested format - but by default (and if you don’t specify an ID) EE will return the list with an ID of “nav_cat_archive”.  This isn’t a problem, until you use a second category archive tag on the same page.  The duplicate ID will cause a validation error, so I just specified some unique values to get around that issue.  All formatting is done at the unordered list level anyway, so I didn’t need the specific ID’s in this case.

You might need to be careful with the Events—I’ve coded assuming there will always be upcoming events.  In the case that there aren’t, this code will return an empty unordered list tag pair that would cause the page to not validate.  If that’s a concern for you, try this approach instead:

<li><a href="{path='events'}">Events</a>
{exp:weblog:entries weblog="events" show_future_entries="yes" disable="categories|custom_fields|trackbacks|member_data|pagination" limit="5" dynamic="off"}
    {if count
=="1"}<ul>{/if}
        
<li><a href="{url_title_path='events/details'}">{title} on {entry_date format="%F %d, %Y"}</a></li>
    
{if count=="total_results}</ul>
{/exp:weblog:entries}
</li> 

I’ve created a link for the Contact Us page but as of this writing that page isn’t yet done.  That should be next.

Also - note that I’ve deep-linked into the Worship section even though that part of the site doesn’t have a details template.  What I’ve done here is take advantage of the dynamic property of the weblog entries tag, such that if I link to the index template with a url_title_path variable, I can get the index template to only show that one entry because it reads the URL and sees the URL title for the entry.  Note that I had to change the code on the Worship page to do this as I had the main weblog:entries tag specified with a “dynamic=“off”.  If this isn’t to your liking, you can just eliminate the weblog entries tag pair under the main Worship link, and link only to the top level/default view of the Worship section.

Performance
This template is a bit loaded with EE tags - so make sure to use the disable parameter on the weblog:entries tag as much as possible.  This template would also be a prime candidate for caching - but I won’t be covering that here.

That’s about it!  Make sure to download the companion files to get all the updates (including the stylesheet) and as always let me know if any questions.

 

 

Category Navigation

<< Previous Entry   

Next Entry >>

 

Previous Comments

Picture of giovanni

by giovanni

Date: Tuesday, February 10th, 2009
Comment: #1

Well Done ... i can really sue this.

many thanks !

Picture of Kevin

by Kevin

Date: Tuesday, February 10th, 2009
Comment: #2

YES! YES! YES!

Finally another series entry! Boy, have I been checking this blog’s RSS feed every day for the past few weeks ....

I’m sure looking forward to the book!

Kevin

Mike Boyink

by Mike Boyink (Author)

Date: Tuesday, February 10th, 2009
Comment: #3

You know..there is software that will check RSS feeds for you…;)

Picture of Kevin

by Kevin

Date: Tuesday, February 10th, 2009
Comment: #4

Mike is such a Funny Guy!

Yes, I have the feed on the top of Firefox Bookmark’s Toolbar.  Just made sure it was updating, that’s all.

I guess the author has the right to add some “lip” sometimes!  Thanks for the laugh.

Kevin

Add Your Comment

Commenting is not available in this channel entry.

Unless otherwise stated all content is © Michael Boyink of Train-ee.com & Boyink Interactive. Please don't steal - I've got kids to feed...

dy>