Bartram's Bits

Tuesday, May 13, 2008

Blogger Labels in CF Part 2

A few days ago I posted a simple solution for listing Blogger Labels in a classic template using ColdFusion. I wasn't happy with just listing the Labels though, I wanted to know how many entries were in each Label. The code that follows is my solution:

<cfscript>
// Returns number of blog entries in a Blogger Label file
function CountLabels(param) {
ct = 0;
ptr = FindNoCase('<div class="post">', param) + 1;
while (ptr gt 1) {
ct = ct + 1;
ptr = FindNoCase('<div class="post">', param, ptr) + 1;
}
return ct;
}
</cfscript>

<!--- This is the first time running, so we need to create the structures in the application scope --->
<cfif Not(StructKeyExists(application, "structLabels"))>
<cfset application.structLabels = StructNew()>
<cfset application.structEntries = StructNew()>
</cfif>

<!--- Get a directory listing of the Labels folder --->
<cfset pathLabels = "#getDirectoryFromPath(getBaseTemplatePath())#labels\">
<cfdirectory name="dirLabels" action="list" directory="#pathLabels#" sort="name asc">

<cfloop query="dirLabels">
<!--- This is the first time running, so we need to count the number of entries for this Label --->
<cfif Not(StructKeyExists(application.structLabels, dirLabels.name))>
<cffile action="read" file="#pathLabels#\#dirLabels.name#" variable="fileLabel">
<cfset ctLabel = CountLabels(fileLabel)>
<cfset StructInsert(application.structLabels, dirLabels.name, dirLabels.dateLastModified)>
<cfset StructInsert(application.structEntries, dirLabels.name, ctLabel)>
<!--- The Labels file was updated, so we need to recount the number of entries for this Label --->
<cfelseif StructFind(application.structLabels, dirLabels.name) neq dirLabels.dateLastModified>
<cffile action="read" file="#pathLabels#\#dirLabels.name#" variable="fileLabel">
<cfset ctLabel = CountLabels(fileLabel)>
<cfset StructUpdate(application.structLabels, dirLabels.name, dirLabels.dateLastModified)>
<cfset StructUpdate(application.structEntries, dirLabels.name, ctLabel)>
</cfif>
</cfloop>

<ul>
<cfloop collection="#application.structEntries#" item="key">
<!--- If there are entries in a Label file, then list it as a link with the total number of entries --->
<cfif StructFind(application.structEntries,key)>
<li><cfoutput><a href="/blog/labels/#key#">#ListFirst(key,".")#</a> (#StructFind(application.structEntries,key)#)</cfoutput></li>
</cfif>
</cfloop>
</ul>

Labels: ,

Saturday, May 10, 2008

Labels in Blogger Classic Template using ColdFusion

Blogger finally got its act together a while back and introduced Labels as a way of tagging or creating categories for blogs. However, they only half-way implemented it for Classic Templates. Each posting lists the Labels that have been assigned to it, and a folder called Labels stores a file listing all the entries for each Label exists. BUT, Blogger doesn't have a $BlogLabel$ tag to display the list of Labels in the navigation column. What's a ColdFusion developer to do? Roll his own!

<cfset pathLabels = "#getDirectoryFromPath(getBaseTemplatePath())#labels\">
<cfdirectory name="dirLabels" action="list" directory="#pathLabels#" sort="name asc">

<ul>
<cfoutput query="dirLabels">
<cffile action="read" file="#pathLabels#\#dirLabels.name#" variable="fileLabel">
<li><a href="/blog/labels/#dirLabels.name#">#ListFirst(dirLabels.name,".")#</a></li>
</cfoutput>
</ul>

First, I build the path to the labels folder using ColdFusion functions enabling the code to run in both my development and live environments. Next, the CFDIRECTORY tag returns a list of the files in the Labels folder in a query structure. Looping through the file names using CFOUTPUT tag, I assemble each list element as a link. With the ListFirst function I can treat the filename as a list with the period as the separator and return the filename without an extension giving me the name of the Label.

I store the following code in /blog-cf/labels.cfm and in my Blogger template, I use the following code to call it:

<h2 class="sidebar-title">Labels</h2>
<cfinclude template="/blog-cf/labels.cfm">

Labels: ,