Author Archives: Wayne Horkan

About Wayne Horkan

I’m a technologist and engineer, typically working in enterprise architecture and systems engineering.

Roller Weblogger alternative Next Previous function

Another one of the standard roller weblogger functions I replaced: the next / previous function. Basically I just wanted this to be a little more informative, and host it as a menu list in the sidebar.

Here’s a couple of examples:

and

And here’s the code (don’t forget to change the blog handle from ‘eclectic’):


<ul class="rEntriesList">

#if ($model.results)

<li class="recentposts">» Currently viewing search results... </li>

#else

	#if($model.permalink)
		<li class="recentposts">» Reading <a href="$url.entry($model.weblogEntry.anchor)">$model.weblogEntry.title</a> </li>
                #if ($pager.prevLink)
                <li class="recentposts">» Backward: <a href="$pager.prevLink">$pager.prevName</a> </li>
                #end
                #if ($pager.prevCollectionLink)
                <li class="recentposts">» Backward: <a href="$pager.prevCollectionLink">$pager.prevCollectionName</a> </li>
                #end
                #if ($pager.nextLink)
                <li class="recentposts">» Forward: <a href="$pager.nextLink">$pager.nextName</a> </li>
                #end
                #if ($pager.nextCollectionLink)
                <li class="recentposts">» Forward: <a href="$pager.nextCollectionLink">$pager.nextCollectionName</a> </li>
                #end
                <li class="recentposts">» Return to <a href="https://web.archive.org/web/20090416190738/https://blogs.sun.com/eclectic/">main site</a>. </li>
  	#elseif($model.weblogCategory)
		<li class="recentposts">» Reading entries related to the "<a href="$url.entry($model.weblogCategory.anchor)">$model.weblogCategory.name</a>" category </li>
                <li class="recentposts">» From <a href="$url.entry($entryFirst.anchor)">$entryFirst.title</a> </li>
                <li class="recentposts">» To: <a href="$url.entry($entryLast.anchor)">$entryLast.title</a> </li>
                #if ($pager.prevLink)
                <li class="recentposts">» Backward: <a href="$pager.prevLink">$pager.prevName</a> </li>
                #end
                #if ($pager.prevCollectionLink)
                <li class="recentposts">» Backward: <a href="$pager.prevCollectionLink">$pager.prevCollectionName</a> </li>
                #end
                #if ($pager.nextLink)
                <li class="recentposts">» Forward: <a href="$pager.nextLink">$pager.nextName</a> </li>
                #end
                #if ($pager.nextCollectionLink)
                <li class="recentposts">» Forward: <a href="$pager.nextCollectionLink">$pager.nextCollectionName</a> </li>
                #end
                <li class="recentposts">» Return to <a href="https://web.archive.org/web/20090416190738/https://blogs.sun.com/eclectic/">main site</a>. </li>
	#else
		<li class="recentposts">» Reading the <a href="https://web.archive.org/web/20090416190738/https://blogs.sun.com/eclectic/">main</a> site </li>

                <li class="recentposts">» From <a href="$url.entry($entryFirst.anchor)">$entryFirst.title</a> </li>
                <li class="recentposts">» To: <a href="$url.entry($entryLast.anchor)">$entryLast.title</a> </li>
                #if ($pager.prevLink)
                <li class="recentposts">» Backward: <a href="$pager.prevLink">$pager.prevName</a> </li>
                #end
                #if ($pager.prevCollectionLink)
                <li class="recentposts">» Backward: <a href="$pager.prevCollectionLink">$pager.prevCollectionName</a> </li>
                #end
                #if ($pager.nextLink)
                <li class="recentposts">» Forward: <a href="$pager.nextLink">$pager.nextName</a> </li>
                #end
                #if ($pager.nextCollectionLink)
                <li class="recentposts">» Forward: <a href="$pager.nextCollectionLink">$pager.nextCollectionName</a> </li>
                #end
	#end

#end

</ul>

Links for this article:

Roller Weblogger Related Entries and Blog Post code

Do you have lots of blog postings, possibly over a number of years? And do you suspect that despite embedding search and tag clouds into your blog that your readers are still not finding content related to that they enjoy? In fact do you have evidence of that very problem from your web analytics data but don’t know what to do about it? Yes? So did I, so I created this roller weblogger code to generate a list of the most related blog entries based upon tag and category relationships.

To show you what I mean, here’s examples for a couple of blog entries:

Messaging Sub-Systems in the UK Government

and

My banana yellow Yamaha V-Max

The way this works is that for any given individual blog post it attempts to match both category and tags to genuinely find the most related entries (first it cycles though entries related by the same category for tag matches, then though an aggregate of all categories for tag matches, and finally, just those related by category alone).

So this has to be my favourite roller weblogger functionality to date; simply because it offers up the most pertinent content to that which the reader is currently looking at, based upon tag affinity, without forcing them to search or link endlessly though tag clouds (which often contain large number of posts that have very little related contextual meaning).

Here’s the code:


## Related Entries
## Cycles through 100 articles of the same category - look for entries with tag matches - order by no. of matches
## Cycles through  20 articles of any category (ignoring the previous category) - look for entries with tag matches - order by no. of matches
## If still not enough items in the menu adds the most recent entries from the same category

    #if ($model.permalink)

        ## number to display (in menu) 
        #set ($dispFlag = 10)
        
        ## Cycles through 100 articles of the same category
        #set ($cycleEntriesTotal = 100)
        
        ## Go through same category first - should get most hits 
        #set ($cycleEntries = $model.weblog.getRecentWeblogEntries($model.weblogEntry.category.name, $cycleEntriesTotal))

        ## Set up other variables
        #set ($theseTags = $entry.tags)
        #set ($sawEntries = [] )
        #set ($sawCount = [] )

        #foreach ($cycleEntry in $cycleEntries)

            #if (($entry.title != $cycleEntry.title) && ($model.weblogEntry.locale == $cycleEntry.locale))

                #set ($matchBun = 1)
                #set ($bunTags = $cycleEntry.tags)

                #foreach ($thisTag in $theseTags)
                    #foreach ($bunTag in $bunTags)
                        #if ($thisTag.name == $bunTag.name)
                            #set ($matchBun = $matchBun + 1)
                        #end
                    #end
                #end

                #if ($matchBun >= 2)

                    #set ($bunEntry = $cycleEntry)
                    #set ($entryCounter = 0)
                    #set ($bunFlag = 0)

                    #foreach ($sawNum in $sawCount)
                        #if (($matchBun > $sawNum) || (($bunFlag == 1) && ($matchBun == $sawNum)))
                            #if ($bunFlag == 0)
                                #set ($bunFlag = 1)
                            #end
                            #set ($bunEntry = $sawEntries.set($entryCounter, $bunEntry))
                            #set ($matchBun = $sawCount.set($entryCounter, $matchBun))
                        #end
                        #set ($entryCounter = $entryCounter + 1)
                    #end

                    #if ($entryCounter <= $dispFlag)
                        #if ($sawEntries.add($bunEntry))
                        #end
                        #if ($sawCount.add($matchBun))
                        #end
                    #end

                #end

            #end

        #end
       
        ## Cycles through  20 articles of any category (ignoring the previous category)
        #set ($cycleEntriesTotal = 20)
        
        ## Go through all categories next - should get fewer hits 
        #set ($cycleEntries = $model.weblog.getRecentWeblogEntries("", $cycleEntriesTotal))

        ## Reset other variables
        #set ($theseTags = $entry.tags)

        #foreach ($cycleEntry in $cycleEntries)

            #if (($entry.title != $cycleEntry.title) && ($entry.category.name != $cycleEntry.category.name) && ($model.weblogEntry.locale == $cycleEntry.locale))

                #set ($matchBun = 0)

                #set ($bunTags = $cycleEntry.tags)
                #foreach ($thisTag in $theseTags)
                    #foreach ($bunTag in $bunTags)
                        #if ($thisTag.name == $bunTag.name)
                            #set ($matchBun = $matchBun + 1)
                        #end
                    #end
                #end

                #if ($matchBun >= 1)

                    #set ($bunEntry = $cycleEntry)
                    #set ($entryCounter = 0)
                    #set ($bunFlag = 0)

                    #foreach ($sawNum in $sawCount)
                        #if (($matchBun > $sawNum) || (($bunFlag == 1) && ($matchBun == $sawNum)))
                            #if ($bunFlag == 0)
                              #set ($bunFlag = 1)
                            #end
                            #set ($bunEntry = $sawEntries.set($entryCounter, $bunEntry))
                            #set ($matchBun = $sawCount.set($entryCounter, $matchBun))
                        #end
                        #set ($entryCounter = $entryCounter + 1)
                    #end

                    #if ($entryCounter <= $dispFlag)
                        #if ($sawEntries.add($bunEntry))
                        #end
                        #if ($sawCount.add($matchBun))
                        #end
                    #end

                #end

            #end

        #end

        <ul class="rEntriesList">

        ## Set up count variables
        #set ($noneFlag = 0)
        #set ($entryCounter = 0)

        ## Output related entries
        #foreach ($sawEntry in $sawEntries)

            #if ($noneFlag < $dispFlag)        
                #set ($noneFlag = $noneFlag + 1)
                #set ($matchBun = $sawCount.get($entryCounter))
                <li class="recentposts"><a href="$url.entry($sawEntry.anchor)" title="relationships: $matchBun" name="$utils.encode($sawEntry.anchor)" id="$utils.encode($sawEntry.anchor)">» $sawEntry.title</a></li>
            #end

            #set ($entryCounter = $entryCounter + 1)

        #end

        ## If still not enough items in the menu adds the most recent entries from the same category
        #if ($noneFlag < $dispFlag)

            ## Cycle though the number to be displayed (plus one including the 'calling' entry itself) 
            #set ($cycleEntriesTotal = ($dispFlag + 1))

            ## Reset variables
            #set ($cycleEntries = $model.weblog.getRecentWeblogEntries($model.weblogEntry.category.name, $cycleEntriesTotal))
  
            ## Cycle though the number to be displayed (plus one including the 'calling' entry itself) 
            #foreach ($cycleEntry in $cycleEntries)
  
                #set ($addFlag = 0)
                
                #foreach ($sawEntry in $sawEntries)
                    #if ($sawEntry.title == $cycleEntry.title)
                        #set ($addFlag = 1)
                    #end
                #end        

                #if ($addFlag == 0)
                    #if ($noneFlag < $dispFlag)        
                        #if (($entry.title != $cycleEntry.title) && ($model.weblogEntry.locale == $cycleEntry.locale))
                            #set ($noneFlag = $noneFlag + 1)
                            <li class="recentposts"><a href="$url.entry($cycleEntry.anchor)" title="relationships: 1" name="$utils.encode($cycleEntry.anchor)" id="$utils.encode($cycleEntry.anchor)">» $cycleEntry.title</a></li>
                        #end
                    #end
                #end

            #end

        #end

        </ul>

    #end

After writing this article I got a mention by Dave Johnson, which inspired me to change the code based on his comments so it only grabs the last 100 entries of the same category and then the last 20 entries of the other categories to analyse. Obviously you can change this by editing #set ($cycleEntriesTotal = 100) to whatever you feel appropriate.

I’ve also removed all redundant variables, fixed a bug due to non-allocation of variables, and changed the sort code so that it keeps date and time based precedence (so entries with the same number of matches will remain in date and time sequence).

Rather than repost another article I’ve retconned the code example into this article; the code displayed is the newer, healthier code; the old code is still there, but hidden in a non-displayed “div” code block at the end (just after this text in fact).

Links for this article:

links for 2008-12-24

That’s cloud computing; But not as we know it, JimThe Register Readers poll of likely adoption of key cloud applications. …..

links for 2008-12-11

Blog of helios: Linux – Stop holding our kids back A US school teacher ignorantly confiscates a boy’s Linux discs and puts him on detention; all because she believed that anything that wasn’t Windows was illegal and immoral. …..

links for 2008-12-10

Why the Great-British-Pædowall is a dumb idea – Paul Jakma’s Weblog Paul Jakma point’s out how poorly thought out and implemented the Internet Watch Foundation’s filtering solution is for UK ISPs and sadly how open to exploitation it could become. …..

links for 2008-12-09

Oliver Postgate – Creator of Bagpuss, The Clangers, Ivor the Engine and other Childrens TV classics Oliver Postgate passed away yesterday; famous for being a founder of Smallfilms (with Peter Firmin) the co-creators of children’s TV favorites like “The Saga of Noggin. …..

links for 2008-12-04

Harvey Nash Annual Business Breakfast, October 2008 Richard Lambert, DG of the CBI, gives the best overview of the “Credit Crunch” that I’ve heard so far. …..

links for 2008-12-02

A Framework for Enterprise Architectures – Archi-TECH Documents the Open Groups struggle to get TOGAF more widely adopted in the US. …..

Apologies to Alec Muffett

I’ve wanted to apologise to Alec Muffett for some time about a blog post I wrote back in January ’08. Called “Links for DD-MM-YYYY Not Likely” it questioned the effectiveness of “Links for” type posts to connect with your readership in a meaningful way; as well as being a response to Alec’s post “A disappointed (occasional) reader…“.

This has become especially ironic as eight months later I followed up with “Setting up del.icio.us blog posting on blogs.sun.com“, a post showing in detail how to configure delicious, the online bookmark system, to post entries to Roller Weblogger (and specifically the implementation powering the Sun blog server). To top it all I’ve become a regular provider of “Links for” posts since then too.

Furthermore I’ve found the “Links for” type post a useful way to communicate in a conversational manner with my readers. It allows me to post short opinion based entries to my blog, giving me a chance to have my say when circumstances wouldn’t or shouldn’t allow a longer blog post, as well as improving the overall cadence of updates, which has suffered when I’ve been time constrained.

I actually gave Alec a call a couple of months ago and apologised in person; I wrote this blog post after being reminded by Carolyn’s comment that I had a responsibility to put things straight online too.

Thanks to Tim Caynes

Thanks to Tim Caynes I have a brand new look and feel on the blog; thankfully this is much more minimalist and I’m hoping easier to navigate for you. …..