Writing an Archive Calendar, part 4

Not much more to discuss for phase 1 of the Archive Calendar since we've covered the code. This post is a kind of wrap up (although it does contain a couple of warnings at the end) and we'll talk about what you have to do in order for the calendar to actually work and display the archived posts.

First up: to display the calendar on the home page just enter this into your layout.view file (or the home.layout.view), essentially in one of the sidebars.

$JmbChalk.ShowCalendar()

and the calendar will display for the current month.

For my site, I use a special widget <div> class, and so the code ends up like this, where I display the calendar followed by the rest of the sidebar:

    <div class="widget">
        <h2>Archives</h2>
        #if($request.year)
            $JmbChalk.ShowCalendar($request.year, $request.month)
        #else
            $JmbChalk.ShowCalendar()
        #end
    </div>
    $macros.RightSideBar("%{beforeWidget='<div class=\"widget\">', afterWidget='</div>', beforeTitle='<h2>', afterTitle='</h2>'}")

That way the calendar looks just like a widget, even though it isn't. Ignore the $request stuff for now, I'm coming to it.

In order to display the pages the links in the calendar point to, you need to create an uncategorized post called "archive". There's no need to put anything in this post, you just have to get Graffiti to create the archive folder off the root (that's where uncategorized posts go) and put the standard default.aspx file in it. The reason we won't be putting anything in this post is that we are not going to let the standard post.view display it. Instead, we're going to create an archive.view, and because of the way that Graffiti works, it will use this view to display the uncategorized post called "archive".

If you remember, the links in the calendar create URLs that look like this for the month:

https://boyet.com/archive/?year=2009&month=1

and like this for an actual date:

https://boyet.com/archive/?year=2009&month=1&day=8

Notice the query parts of the URLs (that is, the bits after the question mark). Graffiti decodes these and makes them available to the view using the $request Chalk class. So we have access to $request.year, $request.month, and $request.day. If the query parameter is not present, the corresponding property of the $request class will be null and we can test for it using code like #if($request.year) for example. (This should be read as "if the year parameter on the request is present...") Looking above you can now see that if the URL contains a query parameter for the year, we generate the calendar for that year and month. (Really I should be testing for the month too, but it doesn't matter since the code takes care of the validation.)

Given all that, here's the archive.view file:

    <div id="blog">

        #if($request.day)
            <h1>Archives for $JmbChalk.GetDateDisplayName($request.year, $request.month, $request.day)</h1>
            #foreach($post in $JmbChalk.GetPostsForDay($request.year, $request.month, $request.day) )
                <div class="post" id="$post.id">
                    $macros.LoadThemeView("postheader.view")
                    <div class="text">
                        $post.Excerpt("<p>", "</p>" ,"Read more...", 300)
                        $macros.LoadThemeView("postfooter.view")
                    </div>

                </div><!--end of post -->

            #nodata
                <div class="post">
                    Sorry, there are no posts matching your request.
                </div>

            #end
        #else
            <h1>Archives - $JmbChalk.GetMonthDisplayName($request.year, $request.month)</h1>
            #foreach($post in $JmbChalk.GetPostsForMonth($request.year, $request.month) )
                <div class="post" id="$post.id">
                    $macros.LoadThemeView("postheader.view")
                    <div class="text">
                        $post.Excerpt("<p>", "</p>" ,"Read more...", 300)
                        $macros.LoadThemeView("postfooter.view")
                    </div>

                </div><!--end of post -->

            #nodata
                <div class="post">
                    Sorry, there are no posts matching your request.
                </div>

            #end
        #end

        $macros.Pager("pager", "&laquo; older posts", "newer posts &raquo;")

    </div><!--end of blog -->

    $macros.LoadThemeView("sidebarleft.view")
    $macros.LoadThemeView("sidebarright.view")

As you can see, the main condition is to test to see if there's a day parameter. If so, we assume it's a display for an actual date, if not, we assume that it's for a single month. We patch up the relevant bits in the page by using the helper functions I'd created in part 3.

And that is that: the current state of play. Except...

There's a subtle bug in my routines to get the list of posts. For me on my blog here, it doesn't matter in the slightest, but for other users of GraffitiCMS it may. GraffitiCMS gives you the option to create roles (and therefore users) who may not have permissions to see the posts in certain categories (by default, a role has global permissions, but you can restrict them). As written, my code does not take this security aspect into account: the user gets to see everything, no filtering at all. I'll revisit that in the near future.

Secondly, although I merrily put in the call to the $macros.pager method, it doesn't work. The view just displays all the posts. No paging, it's for wimps. As it happens, I'd mistaken how the pager operates and so I have some code changes to make for that to work properly and page the list of posts properly. Since the pager also uses the query syntax for the URL, it'll be an interesting investigation. (I may just ignore the built-in pager and do my own.)

(Part 1 is here, part 2 here, part 3 here, part 4 here, part 4a here, part 4b here.)

Album cover for Riptide Now playing:
Palmer, Robert - Riptide
(from Riptide)



Loading similar posts...   Loading links to posts on similar topics...

2 Responses

#1 Dew Drop – January 17, 2009 | Alvin Ashcraft's Morning Dew said...
17-Jan-09 7:26 PM

Pingback from Dew Drop – January 17, 2009 | Alvin Ashcraft's Morning Dew

#2 Writing an Archive Calendar, Part 4 said...
18-Jan-09 2:00 PM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Leave a response

Note: some MarkDown is allowed, but HTML is not. Expand to show what's available.

  •  Emphasize with italics: surround word with underscores _emphasis_
  •  Emphasize strongly: surround word with double-asterisks **strong**
  •  Link: surround text with square brackets, url with parentheses [text](url)
  •  Inline code: surround text with backticks `IEnumerable`
  •  Unordered list: start each line with an asterisk, space * an item
  •  Ordered list: start each line with a digit, period, space 1. an item
  •  Insert code block: start each line with four spaces
  •  Insert blockquote: start each line with right-angle-bracket, space > Now is the time...
Preview of response