Templating hits the Snitch
If you get the latest from SVN, you will now see basic templating with GoldenSnitch. There is a LOT going on here, so let me try to cover it bit by bit.
First - in the settings.xml file is a theme property:
The app looks in the template folder for a folder named red. You will also see a green folder. The name specified in the settings must match the directory name.
What is in the folders? Right now just two required files, template.html and entries.html. Both also have a style.css, but that is optional. You see - all themes will have rules for what is required, and the app will check at startup to ensure those files exist. Along with template files will be an XML file that defines the theme's metadata (title, author, version, etc). All of that is coming later. Outside of the required files, a theme can have any number of additional files. JS libraries - CSS - images - you name it.
So let's take a look at template.html first:
<head>
<title>$$TITLE</title>
<link href="$$TEMPLATEURL/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<center>
<table width="90%" bgcolor="white">
<tr valign="top"><td>$$BODY</td></tr>
</table>
</center>
</body>
</html>
As you can see - there is no code, but I'm using $$FOO to represent variables. Right off the bat you see $$TITLE, which will be replaced with the title. Ditto for $$BODY. TEMPLATEURL is a cool one. As a theme author, you don't know the exact URL of your crap, so it makes it hard to include your CSS/JS/images. Well by using $$TEMPLATEURL, you get a base URL that will always work.
The template.html file will be used for the main page layout for all parts of the blog. It is essentially header and footer.
Now to render entries we use entries.html. The contents of this file is repeated once for every entry, and has variables as well. Here is red's entries.html:
<h2>$$TITLE</h2>
<b>Posted: $$POSTEDTIME("h:mm tt") on $$POSTEDDATE("dddd, m/d/yy")</b><br />
<b>Author: $$AUTHOR</b><br />
$$BODY
</p>
$$NOTLASTROW("<hr>")
Note that some variables above have arguments. Both POSTEDTIME and POSTEDDATE let you pass formats. The last variable is an interesting one. What if - for each list of blog entries - you want an HR between each entry, but not at the end? That's what you use NOTLASTROW for. And it is smart too - it will work correctly if only one entry exists.
So let's compare this to green's entries.html:
<tr>
<th>$$TITLE</th>
<th>$$POSTEDDATE("m/d/yy") at $$POSTEDTIME("h:mm tt")</th>
<th>$$AUTHOR</th>
</tr>
<tr>
<td colspan="3">$$BODY</td>
</tr>
$$LASTROW("</table>")
This one uses a table, and demonstrates two additional variables, FIRSTROW and LASTROW. As you can guess, they are only run on the first and last row.
Thoughts? I'm a bit worried FIRST/LAST/NOTLASTROW are a bit complex - but I think you can look at them and still get a good idea of how the site is going to layout.
As an FYI, the code in template.cfc is a bit rough. Don't consider it final by any means.
Other random/stray thoughts in my head:
- I see at least one more template, entry.html, that will be used for single entry display. I'm really scared about the forms and how I will template-ize them. In fact, now that I think of it - Add Comment may need it's own form, and I'll need to think a bit about how to separate the form UI from the handling of adding comments.
- Due to the above - I may delay then other non-essential forms - like add trackbacks.
- How in the heck do I do search? On my blog, it is in the main template. I could simple allow for form action=$$SEARCHURL.
- Internationalization. Um. So.... thats a bit scary as well. In BlogCFC now - every bit of text is resource bundled. But does that even make sense if we have templates? I mean - someone could easily build a French skin and just hard code the layout. If BlogCFC were to stop having localized text versions, would people crap?
- Other pages I need to do off the top of my head - contact page, slideshows page, stats page. Although does anyone really skin their stats page? For that - I could just use the core template header/footer. That's my plan for Pages anyway.
Comments, please!

$$ROW("number here", "html here")
The problem with that is that ad code could be a bit clunky in there. I could allow for file includes
$$ROW("number here", "include:ad.cfm")
Why you are creating this using html templates instead of using the power of ColdFusion? Can they be .cfm files so we use built-in ColdFusion logic and/or our own custom tags? For instance, I have a CF custom wrap tag the outputs header/footer stuff that I use on my blogcfc instances. It doesnn't seem like I would be able to do that with this templating engine and would still have to hack the code to call my layout instead of yours.
Also, I was browsing the blog cfc svn repository in a web browser in riaforge, but that doesn't appear to have the updated files:
http://blogcfc.riaforge.org/index.cfm?event=page.s...
Mark
Mark - for SVN, see my earlier blog entry. There is a different SVN repo for BlogCFC6 Alpha.
Is your idea to allow cross-blog templates? Would a blogger user be able use a blogcfc theme pack? Or vice-versa? Am I missing something? Is there a huge blog template repository out there that works in several different blog software packages? (there certainly could be--I am no expert in this area) If the answer to these questions is "yes", then pursing it as you are makes sense. But if it's "no", then I don't see the purpose of having a generic template that makes the system harder to use for more complex templating.
This is where I would still argue that something more similar to the Joomla templating approach would be more powerful. Joomla templates include an index.php as the main template file that gets invoked and includes a mixture of php and html. The Joomla engine exposes a series of variables (e.g. configuration parameters) and template functions (e.g. mosShowHead();) to the template that it can use for the layout. Moving to this model would allow you to invoke your template as a cfm file, and it could be as simple as an HTML file with a few function calls (e.g. getBlogTitle() instead of $$TITLE and getBlogBody() instead of $$BODY) to a more complex system that could use existing ColdFusion custom tags, CFCs, etc.
In regards to the SVN question, I was able to add the BlogCFC 6 repository--sorry I missed that!
Mark
Am I hoping other blog engines can use the templates? No.
You should have a theme competition once this is done and make the best theme the default when you deploy it - oh, and give them a copy of CFWACK of course!
What happens internally when the template engine sees $$BODY? Is there an opening there for a call to a plugin that could transform the body in some way (change some markup language to HTML, translate English into pig latin, etc)?
My first thought with the templates was that it's not flexible enough for where I wanted to go, but then I've also been working some with Drupal and Wordpress, who violate your "no logic in the template" goal. Granted it's just view logic and most of the time it's justa loop and a function call, but it's logic nonetheless. However, if there were API hooks in the BlogCFC engine that a plugin could extend, that might open up the template to do some dynamic stuff in a way that's not immediately apparent when viewing the template. And that's probably better actually because the user wouldn't be forced to change the template just to install a plugin.
For THIS particular case, it is a spliiter. The header is all text before, and footer is all text after.
In other template, $$FOO is a variable and it is replaced.
Right now I'm kind of in a brain freeze for how to handle forms, like Add Comment. For forms like Search, I'm not concerned. I'll hard coded all the layout, but the page template will be, well a template. I don't think people care enough to want to modify the search output via a template engine. But Add Comment.... that one thing there is killing me.