Creating Blog Archive Navigation by Month

A common design element for blogs is to provide a listing of past months and years, linked to a page that shows all the posts in that month.

We've provided a special WebvantaScript tag and a special page type to facilitate building this.

The "Year-Month Count Widget" Tag

The tag that does all the magic is w:year_month_count_widget. The basic usage is as follows:

<w:year_month_count_widget item_open='<li><a href="/blog-by-month/%Y/%m">%B (%count)</a>' />

This single line of code will display a nested unordered list of years and months, with each one showing the number of posts in parenthesis and linking to the page "blog-by-month", with the year and month added to the slug.

The Blog Archive Page

The blog archive page to which these links go is a special page type, which you set via the Page Type pop-up list on the page edit screen. Set this to "Blog Archive" on this page. This tells the page to extract the month and year from the URL and place those into variables.

The variables are then available within WebvantaScript statements as {{path-year}} and {{path-month}}. If you want to use them in HTML, use <w:var name='path-year' /> and <w:var name='path-month'>. (Note: these are numeric values; if you want names, use the standard date formatting parameter, as shown in the example below.)

To provide a heading on the blog archive page, you can use code like this:

<h1>Blog posts from <w:var name="path-month" format="%B" />, <w:var name="path-year" /></h1>

For the iterator, you need to access the variables to set the condition. Without the condition, the iterator looks like this:

<w:kb:item:each by='published_at desc' type='Posts'>

To which you must add this condition, so it finds posts within the specified month and year:

condition = "published_at >= {{path-year}}-{{path-month}}-1 &&
published_at < {{path-year}}-{{path-month}}-1+1.month"

Year-Month Count Widget Options

The year-month count widget is highly configurable, so you can provide any sort of presentation if you don't want the default nested unordered list. To customize it, add the following attributes:

Attribute NameDefault ValueUsage
outer_open<ul>Beginning of the outer structure
outer_closed</ul>End of the outer structure
group_open<li>%Y</ul>Beginning of each year
group_closed</ul></li>End of each year
item_open<li>%B (%count)Beginning of each month
item_closed</li>End of each month

As an example, the following code produces a select list, one entry for each year/month combination:

<div class="blog-selector">
<w:year_month_count_widget 
  outer_open="<select>" 
  outer_closed="</select>" 
  group_open="<optgroup label='%Y (%count)'>" 
  group_closed="</optgroup>" 
  item_open="<option value='/blog-by-month/%Y/%m'>%B (%count)"
  item_closed="</option>" 
/>
</div>

And then a little bit of jQuery causes the appropriate blog archive page to be loaded when the user makes a selection:

<script type="text/javascript">
  $(".blog-selector select").change(function(){
    var v=$(this).val(); 
  });
</script>