Go to content Go to sidebar

Learning UserTalk: Local Macros and Loops

Previously, we demonstrated how to determine the current post in UserTalk. In this installment, we'll add local macros and loops to generate a list of the most recent blog posts. Much of this code is derived from the Userland recentTitledBlogPosts macro. Let me also mention due to a lack of definitive documentation, nomenclature is a bit fuzzy and different people will use different terms for the concepts described here.

Macro append allows us to build an html list an item at a time. We simply declare and initialize an local variable to maintain the intermediate state. With each invocation of append, we wrap the argument in an <li> tag pair and append it to the intermediate.


   local (htmlText="");
   on append(s) { htmlText = htmlText + "<li>" + s + "</li>\n" };

Macro getTitle returns the title of a post with error checking. In the current implementation, we just check whether title is defined before trying to access it. In an future implementation we'll add additional code to handle home page/category issues.


   on getTitle(adrPost) {
      if not defined( adrPost^.title ) {return ""};
      return adrPost^.title};

We wrap up our new macro by adding a loop to construct an html list. The loop counts down from the Last Post Before Date and exits when we've run out of posts (downto 1) or we've reached the limit of maxPosts (++cnt >= maxPosts).


   local (i,txt,cnt=0);
   for i = bfrPost downto 1 {
       adrPost = @adrBlog^.posts[i];
       txt = getTitle(adrPost);
       if txt != "" {
          append(txt);
          if ( ++cnt >= maxPosts ) {break}}};

I am once again experimenting with Usertalk by including the code in .txt files stored in my Radio Userland post hierarchy. In this case, identical files that represent both a dateless and a dated entry:

Radio_Root/categories/draft/work.txt
at http://127.0.0.1:5335/categories/draft/work.html
Radio_Root/categories/draft/2004/12/10.txt
at http://127.0.0.1:5335/categories/draft/2004/12/10.html

Here is the complete listing of our target txt files. It consists of a macro definition followed by the invocation of that macro.

<%
on myRecentPosts( adrBlog=radio.weblog.init(), catName="", maxPosts=5 ) {
   local (htmlText="");
   on append(s) { htmlText = htmlText + "<li>" + s + "</li>\n" };
   on getTitle(adrPost) {
      if not defined( adrPost^.title ) {return ""};
      return adrPost^.title};
   local (adrPost, numPost=sizeof(adrBlog^.posts), bfrPost=numPost);
   local (date, file = radioResponder.fileBeingRendered);
   if radio.weblog.file.getArchiveFileDate( file,\@date ) {
      if radio.weblog.getLastPostBeforeDate( adrBlog,date,\@adrPost,catName ) {
         bfrPost = indexOf(adrPost^)}};
   local (i,txt,cnt=0);
   for i = bfrPost downto 1 {
       adrPost = @adrBlog^.posts[i];
       txt = getTitle(adrPost);
       if txt != "" {
          append(txt);
          if ( ++cnt >= maxPosts ) {break}}};
   return "<ul>" + htmlText + "</ul>"};
myRecentPosts()
%>

When executed on my system the results are:

dateless entry …/draft/work.html
A list of the 5 most recent posts (at the time of writing):
  • Mac mini
  • MasterMind Watch: Playoff Round 1
  • Juan Valdez Cafe - Revisited
  • New PowerBook
  • MasterMind Watch: Week 17
dated entry …/draft/2004/12/10.html
The 5 posts that precede 10 December 2004:
  • Solution is Useful and Repeatable
  • MasterMind Watch: Week 13
  • Whole Product Solution
  • Just Desserts at Notre Dame
  • We Wuz Robbed

In our next installment, we'll take a look at generating post hyperlinks and category handling.

22 Jan: Learning UserTalk: Categories and Post Links