Archive Calendar Widget for Graffiti CMS
The JmbCalendar is a full-featured monthly archive calendar widget for Graffiti CMS. Being a widget it can only appear in one of the two sidebars.
The calendar widget supports the following features:
1. Copy the JmbCalendar.dll
into the /bin
folder on your website.
2. To make sure that Graffiti recognizes it, go to your website's home page, hit refresh in your browser, then go to the widget control panel in Graffiti CMS. In the left hand drop down list, you should see JmbCalendar as one of the widgets.
3. Add the JmbCalendar widget to one of your sidebars using the control panel.
4. If necessary, edit the calendar's properties. By default, the title is "Archives", the previous month link format is "« {0}" and the next month link format is "{0} »". Clearing a text box will restore the default for that property when you update.
5. Create an uncategorized post called "archive" (without the quotes). There's no need to enter any content for that post, it won't get displayed. All this does is create a placeholder post in the root folder of the Graffiti site.
6. Create a view file in your current theme called archive.view
. Define the HTML markup and Chalk calls to display a collection of posts. (See below for full details.)
7. Create some CSS to theme the calendar (see below).
8. Check the look of the calendar, and tweak the view, the CSS, or both if necessary.
The calendar uses just one id: jmbCalendar
. It is set on the <table>
element. Nevertheless you can reference all other elements in the calendar from this.
Here are the selectors to use:
#jmbCalendar
: the table itself. #jmbCalendar caption
: the caption of the table, that is, the month name being displayed. #jmbCalendar caption a
: the link in the caption. #jmbCalendar thead th
: the cells in the table header, that is, the day letters. #jmbCalendar tfoot td
: the cells in the table footer, that is, the previous and next month links. #jmbCalendar tfoot td a
: the links in the footer #jmbCalendar tbody td
: the cells in the main body of the table, that is, the days in the month. #jmbCalendar tbody td a
: the links for those days that have posts. As an example, here's the CSS I use for my blog:
#jmbCalendar {border-spacing:0px;border-collapse:collapse;margin:0 auto;} #jmbCalendar caption {margin:5px auto 5px auto;} #jmbCalendar thead th {border:1px solid #5F5F5F;margin:0;} #jmbCalendar tfoot td {border:1px solid #5F5F5F;margin-top:5px;text-align:center;} #jmbCalendar tbody td {padding:2px 4px;text-align:right;} #jmbCalendar tbody td a {display:block;} #jmbCalendar tbody td a:hover {background-color:#5F4C4C;}
The archive.view
file will be rendered in two situations: either to display the archived posts for a particular month (the reader clicked on a month link in the calendar), or for a particular date (the reader clicked on one of the days in the calendar). Consequently there will be some kind of Chalk if statement in there.
Here's an example view file.
<div id="blog"> #if($request.day) <h1>Archives for $JmbCalendarHelper.GetDateDisplayName($request.year, $request.month, $request.day)</h1> #foreach($post in $JmbCalendarHelper.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 - $JmbCalendarHelper.GetMonthDisplayName($request.year, $request.month)</h1> #foreach($post in $JmbCalendarHelper.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 $JmbCalendarHelper.Pager("pager", "« older posts", "newer posts »") </div><!--end of blog -->
Ignore the HTML markup in there: this will depend on the theme you are using. Instead focus on the Chalk code. The first if statement checks to see whether a "day" parameter was passed in the URL query string (the URL will look like "<yoursitename>/archive/?year=2009&month=1&day=4"
and this statement looks for the day part).
If that's present, the view uses some Chalk extensions (the extension is called JmbCalendarHelper
and was installed along with the widget). GetDateDisplayName
returns a pretty string of the date (pass in the request's year, month and day as shown) and GetPostsForDay
returns a collection of posts for that same date. The posts are then iterated through. Note that the number of posts in the returned collection is limited to 10. You will need to use the pager to see the others.
A similar bit of code works for displaying the posts for a month. Here the day part of the request is empty, so we only use the month and year parts. The Chalk methods to use are GetMonthDisplayName
and GetPostsForMonth
, and work in a similar way to their date counterparts.
Finally there's the call to the pager method. This works in the same way as the $macros.pager
command. The parameters are the CSS class name for the <div>
element to hold the pager links, and the two link texts for older and newer posts.
If you use the calendar for a while, you'll notice that the most popular page on
your site as displayed by the GraffitiCMS control panel becomes the archive page. Since this information isn't really that interesting, the JmbCalendarHelper Chalk extension has an extra method to clear the statistics for the archive page. Just put the command $JmbCalendarHelper.ResetArchivePageStatistics()
at the top of your archive
view file, and it will clear the stats every time the archive page is displayed.
Although the month and day names are retrieved from the operating system hosting Graffiti, ancillary text such as tips is still hardcoded in English.
The day that starts the week is retrieved from the operating system hosting Graffiti. If you want the calendar to start on a different day of the week, you will have to make an operating system configuration change.
Date formats are hard-coded, although some are read from the operating system hosting Graffiti. However, nowhere is the ambiguous 99/99/9999 date format used.
If you are interested in how I designed and implemented this widget please see these posts on my blog.
This document, the code, and the compiled binaries for JmbCalendar are all © Copyright 2008-2009, Julian M Bucknall.
The license for this product is the MIT license:
Copyright (c) 2009 Julian M Bucknall
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
If that lot scares you off, I'll certainly help out with changes if your request is reasonable. I can be reached via my blog http://blog.boyet.com, or by email at julianb@boyet.com.