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:

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

and like this for an actual date:

http://blog.boyet.com/blog/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)




Posts on similar topics...

Share it: Digg It!  StumbleUpon  Reddit  Del.icio.us  NewsVine  Furl  BlinkList  Ma.gnolia  Technorati

2 Responses

  • Sat 17 Jan 2009
  • 7:26 PM
  •  avatar #1

Dew Drop – January 17, 2009 | Alvin Ashcraft's Morning Dew said...

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

  • Sun 18 Jan 2009
  • 2:00 PM
  •  avatar #2

Writing an Archive Calendar, Part 4 said...

Thank you for submitting this cool story - Trackback from DotNetShoutout

Leave a Response

About Me

I'm Julian M Bucknall, the M because it's my middle initial and because I and the other Julian Bucknall (the movie guy) would like to differentiate ourselves.

I'm a programmer by trade, an actor by ambition, and an algorithms guy by osmosis. I write articles for PCPlus in my spare time, not that there's much of that.

Julian M Bucknall Apart from that, an ex-pat Brit, atheist, microbrew enthusiast, Pet Shop Boys fanboy, slide rule and HP calculator collector, amateur photographer, Altoids muncher.

DevExpress

I'm Chief Technology Officer at Developer Express, a software company that writes some great controls and tools for .NET and Delphi. I'm responsible for the technology oversight and vision of the company.

The OUT Campaign

The OUT Campaign

Validation

Valid XHTML 1.0 Transitional     Valid CSS!

Bottom swirl

Archives

February 2010 (2)
SMTWTFS
« Jan  
123456
78910111213
14151617181920
21222324252627
28

Like this Archive Calendar widget? Download it here.

Search

Google ads

My Tweets

  • It seems replacing all our windows will take a mere couple of days. Next Monday/Tuesday will be interesting: it'll drive me crazy.
  • Every now and then, you have a day where nothing goes right. That was today. Bah.
  • White paper written. Now to write the exemplar application
Bottom swirl