Improving Radio's Story Shortcut Automation

By Mark Woods, November 4, 2002

Revised 11/5/02; 11:17:50

I like Radio's shortcuts feature. Actually, it is not so much the screen within Radio that I like as the ability to use shortcuts when I write. Some time back Userland added a feature to Radio that automatically creates shortcuts for stories. However, this only works if you create the stories through Radio's browser-based desktop. It does not work if you create your stories in some other way (from Radio's outliner or some other text editor, for example). I would really like to have Radio automatically create shortcuts for all of my stories, no matter how they were created.

Thoughts on Designing a Solution

Warning: You may want to skip to the Conclusion below, unless you really want to read the details of how I finally arrived at a working solution. The next few paragraphs are kind of a programmer's diary of how I went about solving this problem. Maybe useful if you are trying to monkey around with adding similar functionality, mind-numbingly boring otherwise (I imagine).

I think the best way to do this is to use Radio's callback mechanism to detect when a story has been rendered and then use the story's title to create (or update) a shortcut. Radio provides two candidate callbacks for this task, but I am not yet sure which I want to use. user.radio.callbacks.upstream gets called with a list of files that have changed and are about to be upstreamed to the server. user.radio.callbacks.upstreamFileRendered gets called after a file has been rendered (and is now elgible for upstreaming). The former callback would require me to loop through all of the files to see if any of them are stories from which I should create a callback. On finding one, I would have to open it, read the text (or OPML), and look for a #title attribute. This all sounds pretty inefficient. The latter sounds easier because it provides the callback script with the text (HTML) that has been rendered. The downside is that I cannot easily tell if the file represents a story or not.

A third solution presents itself after some thought. I could handle this in the same way I did metatags. That is, specify a new macro invocation ("addStoryShortcut()") in the #template.txt file. The advantages are a) I can easily ensure that I am only adding shortcuts for stories; b) it is fast and fairly efficient. The disadvantage is that I must update the #template.txt file with a new macro that "automatically" creates the shortcut. That is not a big issue, just another thing to remember should I change my themes.

Solution Attempts

I tried the last solution since it is so easy to implement. I created a new macro, user.radio.macros.addShortcut(), that looks for the title directive in the page table (pta^.title), then adds it as a shortcut (using radio.shortcuts.addStory()) - associating the title with the url (also from the page table). This works. Almost. The page table URL is file-based. I did not take into account the fact that Radio is rendering to a file, then upstreaming the file to the server. From the rendering engine's point of view, the URL is a file pointer.

My next attempt was to copy the code Radio uses to automatically create a shortcut for a new story. I found it in radio.file.newStoryFile(). A couple of things broke along the way. First, the URL path was incomplete, missing the Stories directory structure altogether. Not good. Second, the file name was mysteriously truncated. On investigating I realized I copied a little bit too much code too blindly. Suffice it to say that I was using an orange peeler to core an apple when it came to determining the name of the rendered file. Oops! I simplified things by getting the weblog URL, using radio.weblog.getUrl(), and appending the path (using pta^.path) of the rendered file. That seems to do the trick.

Now I want to make this work for category-specific stories. radio.weblog.getUrl only works for stories on the "main site". Supporting automatic shortcuts for category-specific stories will require a different technique for determining the category's URL (which might be on a completely different machine). My first attempt was to use the category metadata in weblogData.categories, but that fails because it does not tell you how the category directory structure is mapped to the server URL. For example, I host most of my categories on a machine separate from my main weblog (the one you are reading now). I eliminate the "categories" string from the URL on these categories - using the category name alone as a differentiator. What I would really like is a way to take the path of the rendered file and find out where it was upstreamed to, then use that value to create my shortcut.

It finally occurrs to me (what did it take, about five iterations?) that Radio has a structure that maps file names to the upstreamed URL. It is in user.radio.settings.files. This very large table keeps track of every file in and under Radio's www folder. In this, hopefully final, iteration I use the file path from the page table to look up the URL that the story was upstreamed to. Once this worked I realized I could generalize the code a bit; I can use the same solution (the files metadata) for both category-specific stories and regular stories.

Dateline November 5. Last night I realized that the macro solution will not work for a new story because the URL is not yet available (during the rendering process). It becomes available during the upstreaming process. Therefore I had to go back to the drawing board. I decided to use the upstream callback, my first inclination, but use the user.radio.settings.files table to glean the title and url for the article. I am modifying the below instructions accordingly.

Conclusion

To quote young Anakin, "It's working"! I feel good about that. Here is how you too can get Radio to automatically create shortcuts for your stories - no matter how you create the story or where you create the story. The only real requirement is that the story must be rendered using Radio's templates. That is, tossing a complete HTML file into your stories directory will not trigger this mechanism.

Download and install this script. Be sure to download it rather than trying to open it from your browser. Open the downloaded file using Radio's File/Open menu. You will be prompted to load the script into "user.radio.callbacks.upstream". Accept this location. Test it out by opening a new outline in Radio, creating a story (be sure to provide a #title directive), and saving the outline in a stories subfolder. Happy shortcutting!

Special Note to Early Adopters

If you downloaded and installed the original addStoryShortcut macro (posted November 4, 2002), you will want to uninstall it. The new design, though it uses the same name, works differently. It will not cause any conflicts to have both solutions installed, but it does waste processor time. To uninstall the old macro do the following:

Open Radio (from the System Tray icon) Open user.radio.macros (you can use the Ctrl-J shortcut key) Delete the addStoryShortcut script In each #template.txt file you modified, omit the line you inserted, namely:

<%user.radio.macros.addStoryShortcut()%>
That should do it.