« Back to blog

Blog: Blog Archive complete, simple too!

Graham Weldon

06 November, 2008

Not much code digging tonight, as the Archive element for the blog pages was way less complex than I had initially anticipated. What I wanted as a basic display of the months in which posts had been made, and to have them list in the side bar of the site. Nothing fancy there, but it meant grouping, ordering, and returning non-standard fields. All of which turned out to be a piece of Cake.. PHP, that is.

The first thing to note is that I am using some automagic within CakePHP, in that it automatically populates a 'created' field on a table, when the data is created. This is absolutely perfect for things like blog entries. Sure there are situations in which you might want to back-date a post, but I tend to just leave the dates natural, and the auto created field suits this just fine.

The second thing to note is that while we don't need to go to huge lengths to create a custom query for this model data to be returned, we do need to deal with it in a alightly different manner to normal, to get the data we want in an optimal manner.

Namely, the 'conditions' as part of the model find is used to only return published, non-deprecated posts. The 'fields' option is provided to indicate what fields we want to return. I chose to use 'DATE_FORMAT(Blog.created, '%Y-%m') AS date', and 'COUNT(Blog.id) AS count' as the two fields to return, as that is all we really need. The count is included there in case I want to put a visual indicator on the site to show how many posts for the month.

The 'group' option should also be supplied, to ensure we get distinct months, and total counts for each month. This is a relatively new option. The following was used: 'group' => 'date'. Pretty simple, right there. You can go ahead and order this by any of the fields that are returned 'count' and 'date' in this example.

The view is done the same as any model output in a loop, but the data is not associative in the array due to the custom fields returned. A print_r() will show you what I mean. Last, i've adjusted the routes to include a date based url with: Router::connect('/blog/archive/:year/:month/*', array('controller' => 'blogs', 'action' => 'archive'), array('year' => '[0-9]{4}', 'month' => '[0-9]{2}'));

Lastly, I do some trickery that I think could be optimised, for the display of dates as their textual names. This is done with the time helper, one of the more useful yet forgotten view helpers.

PS. Codeblocks are coming soon, so I will be able to post some more readable code. Stay tuned.