Learning UserTalk: the myRecentTitledPosts Macro
Today, we add the finishing touches to our macro. This project was inspired by Userland's recentTitledBlogPosts macro, but I wanted something more appropriate for my daily weblog pages. My macro displays posts that were originally published around the date associated with each page (example below). My issue with recentTitledBlogPosts is that recent is defined relative to when the page is rendered – if an older page is re-rendered, then the dates of the post links and the page will be far out of sync.
First, let's add a local macro to prepend text to our list. This is simply an analog of the append local macro. We'll be using this to add items on to the head of our list.
on prepend(s) { htmlText = "<li>" + s + "</li>\n" + htmlText };
Next, we'll add a block of code to list any preceding posts. I've chosen to list any posts on the current page as plain text. This works for me, as I rarely post more than twice on a day. More prolific posters may prefer to style the day's links with CSS instead. Note that we decrement maxPosts on today's posts and increment cnt (testing against prvPosts) otherwise. This insures that we generate the correct number of previous posts and total posts.
if radio.weblog.file.getArchiveFileDate( file,\@date ) {
if radio.weblog.getLastPostBeforeDate( adrBlog,date,\@adrPost,catName ) {
bfrPost = indexOf(adrPost^);
for i = (bfrPost + 1) to numPost {
adrPost = @adrBlog^.posts[i];
if date.sameday(date,adrPost^.when) {
txt = getTitle(adrPost,catName);
if txt != "" {
prepend(txt);
--maxPosts };
} else {
txt = getTitleLink(adrPost,catName);
if txt != "" {
prepend(txt);
if ( ++cnt >= prvPosts ) {break}}}}}};
After executing this block of new code, then we just iterate down through out blog posts as in our previous post: Learning UserTalk: Categories and Post Links.
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. Note that this example has been restricted to the sports category.
<%
on myRecentTitledPosts( adrBlog=radio.weblog.init(), catName="",
prvPosts=3, maxPosts=10 ) {
local (htmlText="");
on append(s) { htmlText = htmlText + "<li>" + s + "</li>\n" };
on prepend(s) { htmlText = "<li>" + s + "</li>\n" + htmlText };
on getTitle(adrPost,categoryName) {
if not defined( adrPost^.title ) {return ""};
if categoryName == "" {
if defined( adrPost^.flNotOnHomePage ) {
if adrPost^.flNotOnHomePage { return "" }};
return adrPost^.title;
} else {
if defined( adrPost^.categories[categoryName] ) {
if adrPost^.categories[categoryName] { return adrPost^.title }};
return "" };
};
on getTitleLink(adrPost,categoryName) {
local(title=getTitle(adrPost,categoryName));
if title == "" { return "" };
local(url);
if radio.weblog.getUrlForPost(adrPost,\@url,categoryName,adrBlog) {
return "<a href=\"" + url + "\">" + title + "</a>" };
return title;
};
local (adrPost, numPost=sizeof(adrBlog^.posts), bfrPost=numPost);
local (date, file = radioResponder.fileBeingRendered);
local (i,txt,cnt=0);
if radio.weblog.file.getArchiveFileDate( file,\@date ) {
if radio.weblog.getLastPostBeforeDate( adrBlog,date,\@adrPost,catName ) {
bfrPost = indexOf(adrPost^);
for i = (bfrPost + 1) to numPost {
adrPost = @adrBlog^.posts[i];
if date.sameday(date,adrPost^.when) {
txt = getTitle(adrPost,catName);
if txt != "" {
prepend(txt);
--maxPosts };
} else {
txt = getTitleLink(adrPost,catName);
if txt != "" {
prepend(txt);
if ( ++cnt >= prvPosts ) {break}}}}}};
for i = bfrPost downto 1 {
adrPost = @adrBlog^.posts[i];
txt = getTitleLink(adrPost,catName);
if txt != "" {
append(txt);
if ( ++cnt >= maxPosts ) {break}}};
return "<ul>" + htmlText + "</ul>"};
myRecentTitledPosts(catName:"sports")
%>
When executed on my system the results are:
- dateless entry …/draft/work.html
- A list of the 10 most recent posts in the sports category (at the time of writing):
- dated entry …/draft/2004/12/10.html
- Ten sports category posts that surround 10 December 2004:
There are just a couple of issues with this macro. First, all posts should have titles; the browsing experience breaks down quickly with untitled posts. Second, strictly correct display of preceding posts requires that posts be re-rendered as new posts are published. If you also display the calendar, then calendar driven re-rendering will keep things mostly correct. But it really needs to force re-rendering of previous pages to be strictly correct.