It occurs to me that the new IRC channel list feature we’ve added to MDC could serve as a sweet example of some of the nifty stuff we can do with Deki, so I thought I’d blog a bit about how it works.
There are a few components to this, some of which are hidden in the configuration of MDC. Suffice it to say that the Suggestchannels template is automatically embedded into MDC wherever the suggestchannels CSS class is used — in particular, in the table of contents box along the right-hand side of the page. The template accepts as input the ID of the page whose tags it needs to evaluate.
Feel free to take a look at the source for that page; the magic is done in the source, which uses DekiScript to build lists of tags that correspond to various IRC channels and then conditionally insert list items based on which tags are assigned to the page.
Open up the source for the template and follow along while we study how the magic happens.
The entire template is a single div block that has two custom attributes used by Deki. The first is the if attribute. This attribute specifies a Boolean expression that must be true in order for the element to be rendered. If the expression evaluates to false, the entire div block is dropped and doesn’t appear in the rendered document.
The second custom attribute is the init attribute. This specifies DekiScript code that is run before evaluating the element. In our case, we have a lengthy chunk of code that runs here. It starts by fetching the Deki page object representing the page being rendered, then grabbing the list of tags associated with the page.
After that, lists are created representing the tags associated with each IRC channel supported by the template, followed by an all list that includes all the tags recognized by the template.
The final step in the initialization code is to walk through the list of tags associated with the article and see if any of them occur in the list of tags for which IRC channels are known. If this happens, we know that the div block needs to render, and we set the value of the show variable to true.
The div block is stripped from the page if the show variable is false; this is how we suppress the display of the “Discuss in IRC” section if the article has no known appropriate channels.
We use a similar technique for each item in the list of channels; each channel item is only included in the list if the corresponding tag is found in the list of tags matching that channel.
Adding new tags to existing channels
We can easily route additional tags to IRC channels already recognized by this template by simply adding the tags to the appropriate lists. For example, if the tag “foo” should route to the channel “xforms”, we would simply add “foo” to the line for the xforms list, like this:
var xforms = [ ‘xforms’, ‘foo’ ];
Adding new channels
Adding new channels is slightly more complicated, but not ridiculously so. The first thing we have to do is add a new list for that tag. For example:
var newchannel = [ ‘tag1’, ‘tag2’, ‘tag3’ ];
Then we add the new channel to the all list:
var all = extdev .. css .. addons .. js .. xul .. devmo .. jsapi .. xulrunner .. developers .. qa .. svg .. xforms.. canvas .. embedding .. places .. venkman .. newchannel;
Finally, we add a new list item for the new channel. These are generally included in alphabetical order.
<li init=”var show = false; foreach(var tag in tags) if(list.contains(newchannel, string.tolower(tag.name))) let show=true;” if=”show”><a class=”external” href=”irc://irc.mozilla.org/newchannel”>#newchannel</a></li>
Once these changes are committed, the new channel will automatically show up on pages tagged “tag1”, “tag2”, or “tag3”.
This is a good sign for the future; we can do some very nifty stuff with this. If you haven’t done so already, check out my list of ideas for things we can do to make MDC even cooler in the future.