Whelp, let's take a crack at this...

The following is a first run at the documentation for the template tag documentation. The first of, I fear, a million and six pieces of documentation about Blogware.

Blogware styles and templates sit on top of a template management system called "Bots". Bots (short for Brad's Own Templating System) evolved from Jots (Joe's Own Templating System). Bots is loosely based on the the very helpful HTML::Template perl module, but there are differences.

  • IF/ELSIF/UNLESS/ELSUNLESS can check for the existence of a template.

  • ELSIF tag supported.

  • EQ/REGEXP tag supported in IF, ELSIF, UNLESS, and ELSUNLESS blocks.
  • 'global' array of variables which are available in all contexts is supported.
  • INCLUDE tags can take a variable name as well as a filename. See docs for usage.
  • {{ }} used for tag markers instead of < >.
  • No TMPL_ prefix needed for tags.
  • Short syntax supported for simple variables: {{variable_name}} is the same as {{var name="variable_name"}}
  • Miscellaneous other cool features in HTML::Template still need to be implemented in Bots.


Caveat: This is a very simplistic first crack that solely describes the tags and where they can be used. This document doesn't attempt to describe the templating system or styles or how to use either.

...and of course, this is all very likely wrong by the time that you read it. :) I will be doing some more work on this later today and throughout the week to make it more self-explanatory. This first crack is simply a head-start for the eager beavers that like wrestling with half-documented features :)

'article' => {
'label' => 'Article template',
'filename' => 'article.html',
'tags' => {
'trackback_rdf' => "A string of rdf text which enables blog interfaces to use auto-discovery techniques against these blog articles",
'title' => "The article title",
'author' => "The article author",
'publish_time' => "The publish time for this article",
'num_comments' => "The number of comments",
'num_trackbacks' => "The number of trackbacks",
'body' => "The article body",

'category' => {
'label' => 'Category template',
'filename' => 'category.html',
'tags' => {
'breadcrumb' => {
'description' => "A loop containing the category breadcrumb trail",
'tags' => {
'selected' => "A boolean indicating whether the user is currently viewing this category",
'name' => "The category name",
'url' => "The url to view this category",

'days' => {
'description' => "A loop containing the days of articles for display",
'tags' => {
'date' => "The date string for this day",
'articles' => {
'description' => "A loop containing the articles for this day",
'tags' => {
'title' => "The article title",
'author' => "The article author",
'excerpt' => "The article excerpt",
'body' => "The article body",
'publish_time' => "The publish time",
'view_url' => "The url to view this article",
'num_comments' => "The number of comments",
'num_trackbacks' => "The number of trackbacks",

'calendar' => {
'label' => 'Calendar template',
'filename' => 'calendar.html',
'tags' => {
'calendar.month' => "The month name",
'calendar.year' => "The year",
'calendar.weeks' => {
'description' => "A loop containing the weeks for this month",
'tags' => {
'days' => {
'description' => "A loop containing the days of this week",
'tags' => {
'can_link' => "A boolean indicating whether the day should be linked",
'selected' => "A boolean indicating whether the day is being viewed",
'url' => "The url to view this day",
'day' => "The day of the month",

'calendar.months' => {
'description' => "A loop containing several nearby months with articles",
'tags' => {
'selected' => "A boolean indicating whether the month is being viewed",
'url' => "The url to view this month",
'month_name' => "The month name",
'year' => "The year",

'calendar.years' => {
'description' => "A loop containing the years with articles",
'tags' => {
'url' => "The url to view this year",
'year' => "The year",

'comments' => {
'label' => 'Comments template',
'filename' => 'comments.html',
'tags' => {
'comments' => {
'description' => "A loop containing article comments",
'tags' => {
'thread_starts' => "A loop whose size is equal to the number of indent levels that should be created for this comment",
'thread_ends' => "A loop whose size is equal to the number of indent levels that should be closed after this comment",
'title' => "The comment title",
'author' => "The comment author (optional)",
'publish_time' => "The publish time for the comment",
'body' => "The comment's body",
'can_post' => "A boolean variable which indicates whether the current user can post a reply to this comment",
'post_reply_url' => "The url which brings up the post-comment form",

'trackbacks' => {
'label' => 'Trackbacks template',
'filename' => 'trackbacks.html',
'tags' => {
'article.url' => "The url to view the article for these trackbacks",
'article.title' => "The article title",
'article.trackback_url' => "The trackback url for this article",
'trackbacks' => {
'description' => "A loop containing the trackbacks",
'tags' => {
'title' => "The trackback title",
'blog_name' => "The blog name for this trackback",
'create_time' => "The time when the trackback was received",
'excerpt' => "The trackback excerpt",

'style' => {
'label' => 'Style sheet template',
'filename' => 'style.css',

'base' => {
'label' => 'Base template',
'filename' => 'base.html',
'tags' => {
'blog.url' => "The primary url for this blog",
'blog.name' => "The blog name",
'blog.new_article_url' => "The url used to post a new article to the current category",
'blog.edit_article_url' => "The url to edit the currently viewed article",
'user.username' => "The username of the currently logged in user",
'authenticated' => "Boolean indicating whether the user is logged in",
'blog.rss_url' => "The url to access the rss feed for this blog",
'category.rss_url' => "The url to access the rss feed for this category",
'category.collection_url' => "The url to add this category to the user's virtual blog",
'test_tmpl_mode' => "Boolean indicating whether the user is viewing the blog with staging templates",
'live_tmpl_mode_url' => "The url to view the blog with live templates",
'message' => "A string containing occasional information from the cgi",