<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Nick Dunn's Blog</title>
    <link>http://nick-dunn.co.uk</link>
    <description>Nick Dunn's Blog</description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/nickdunn" type="application/rss+xml" /><item>
      <title>Export a CSV report from Sifter issues</title>
      <link>http://feedproxy.google.com/~r/nickdunn/~3/dBAZrHLJFvs/</link>
      <description>&lt;p&gt;The &lt;a href="http://getsatisfaction.com/nextupdate/topics/sifter_api"&gt;Sifter API&lt;/a&gt; has been a long time coming and there’s nothing on the horizon yet. I recently embarked on my own set of scripts to automate the process of creating a report from Sifter. The idea is to parse the issues HTML list into XML and then transform to whatever the user desires using XSLT (a printable HTML page, an XML file, a CSV). But I digress.&lt;/p&gt;

&lt;p&gt;So I found a natty little update to Sifter that provides native export of your issue list as a CSV file!&lt;/p&gt;

&lt;p&gt;Spot &lt;code&gt;/issues?s=...&lt;/code&gt; in the URL and change it to &lt;code&gt;/issues.csv?s=&lt;/code&gt;. Tada!&lt;/p&gt;

&lt;p&gt;I’ll hold out for the API.&lt;/p&gt;</description>
      <pubDate>Tue, 30 Jun 2009 10:51:00 +0100</pubDate>
    <feedburner:origLink>http://nick-dunn.co.uk/article/export-a-csv-report-from-sifter-issues/</feedburner:origLink></item>
    <item>
      <title>Show latest Last.fm plays on your Symphony site</title>
      <link>http://feedproxy.google.com/~r/nickdunn/~3/9dhEOm-Udfc/</link>
      <description>&lt;p&gt;At the top of my blog I have added the name of the last track &lt;a href="http://en.wikipedia.org/wiki/Last.fm"&gt;scrobbled&lt;/a&gt; to &lt;a href="http://www.last.fm/"&gt;Last.fm&lt;/a&gt;. Symphony made this so easy, eating a biscuit with a fresh brew after five minutes. Here’s how:&lt;/p&gt;

&lt;p&gt;First you need a Last.fm user account, and one of the various applications to scrobble your tracks from iTunes (or Windows Media Player, if your life is broken). Then you need to &lt;a href="http://www.last.fm/api/account"&gt;grab an API key&lt;/a&gt;. The key will be a hash that looks something like this (note: this is not my real API key!).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;3d21e002930b853d2f048e517c577ec7
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can then create a URL using the Last.fm API to return your recent tracks as XML. We will use the &lt;code&gt;user.getRecentTracks&lt;/code&gt; method of the API. Your URL should be in this format:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&amp;user={your-username}&amp;api_key={your-api-key}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Log in to your Symphony site and create a new Data Source, choosing “Dynamic XML” as its source. Paste your API call URL into the &lt;code&gt;URL&lt;/code&gt; field and update the cache value to something small, between 1 and 10 minutes should do.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://nick-dunn.co.uk/assets/files/lastfm.png" class="figure" alt="Figure 1. Last FM Data Source"&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Note that I have also added the XPath expression &lt;code&gt;//track[1]&lt;/code&gt; so that only the first track node is included in my Page to keep things lean.&lt;/p&gt;

&lt;p&gt;Attach this Data Source to your Page and fire up &lt;code&gt;?debug&lt;/code&gt; to check you can see the fresh track node. You can? Great! I’m glad you’ve been keeping up.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://nick-dunn.co.uk/assets/files/lastfm-xml.png" class="figure" alt="Figure 2. Last FM Data Source debug XML"&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;All you need now is a little XSLT magic to write this content into your page. Where you want the track name to appear, add a template match to the &lt;code&gt;track&lt;/code&gt; node above:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:apply-templates select="/data/last-fm/track" mode="last-fm"/&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And neatly out of the way you can create a template to handle the rendering of the content. My template looks like this. Notice I’m checking whether the track has a &lt;code&gt;nowplaying&lt;/code&gt; attribute and changing the label accordingly.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:template match="track" mode="last-fm"&gt;

    &lt;xsl:choose&gt;
        &lt;xsl:when test="@nowplaying='true'"&gt;
            &lt;xsl:text&gt;Currently listening to &lt;/xsl:text&gt;
        &lt;/xsl:when&gt;
        &lt;xsl:otherwise&gt;
            &lt;xsl:text&gt;Recently listened to &lt;/xsl:text&gt;
        &lt;/xsl:otherwise&gt;
    &lt;/xsl:choose&gt;

    &lt;xsl:value-of select="concat(name, ' by ', artist)"/&gt;

&lt;/xsl:template&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How stupendously easy!&lt;/p&gt;

&lt;p&gt;The kettle’s boiled. Time for a cuppa.&lt;/p&gt;</description>
      <pubDate>Wed, 10 Jun 2009 17:46:00 +0100</pubDate>
    <feedburner:origLink>http://nick-dunn.co.uk/article/show-latest-lastfm-plays-on-your-symphony-site/</feedburner:origLink></item>
    <item>
      <title>Hanging Out With Humans</title>
      <link>http://feedproxy.google.com/~r/nickdunn/~3/u6bVOIiQG8k/</link>
      <description>&lt;p&gt;&lt;img src="http://nick-dunn.co.uk/assets/files/dsp.jpg" class="figure right" alt="Party. Data Select Party — Hanging Out With Humans"&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.myspace.com/dataselectparty"&gt;Data.Select.Party&lt;/a&gt; are difficult to describe. They combine the smiles of &lt;a href="http://www.myspace.com/tellison"&gt;Tellison&lt;/a&gt;, the tapped clean guitars of &lt;a href="http://www.myspace.com/thistownneedsguns"&gt;This Town Needs Guns&lt;/a&gt;, and the yelps and chants of &lt;a href="http://www.myspace.com/darts"&gt;Dartz!&lt;/a&gt; and &lt;a href="http://www.myspace.com/foals"&gt;Foals&lt;/a&gt;. I’ve seen them play a few times in and around London, and &lt;em&gt;Hanging Out With Humans&lt;/em&gt; is a fine collection of new material and several old favourites too.&lt;/p&gt;

&lt;p&gt;Indiemo kids rejoice! There be cowbells.&lt;/p&gt;

&lt;p&gt;Buy it on &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=309838397&amp;s=143444"&gt;iTunes&lt;/a&gt; now.&lt;/p&gt;</description>
      <pubDate>Wed, 10 Jun 2009 12:34:00 +0100</pubDate>
    <feedburner:origLink>http://nick-dunn.co.uk/article/hanging-out-with-humans/</feedburner:origLink></item>
    <item>
      <title>Developing with Symphony using the Firebug console</title>
      <link>http://feedproxy.google.com/~r/nickdunn/~3/egvn5YXm9AY/</link>
      <description>&lt;p&gt;With some magic from the &lt;a href="http://www.firephp.org/"&gt;FirePHP library&lt;/a&gt;, Symphony development just got a whole lot easier. Instead of having to append &lt;code&gt;?debug&lt;/code&gt; or &lt;code&gt;?profile&lt;/code&gt; to the end of a URL to view debug XML and performance profiles, you can now have this information sent directly to your Firebug console!&lt;/p&gt;

&lt;p&gt;My &lt;a href="http://github.com/nickdunn/firebug_profiler/tree/master"&gt;Firebug Profiler&lt;/a&gt; extension provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quick access to page lifecycle profiler&lt;/li&gt;
&lt;li&gt;query counts for all Data Sources&lt;/li&gt;
&lt;li&gt;optional XML fragments for each Event and Data Source on the page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://github.com/nickdunn/firebug_profiler/tree/master"&gt;Firebug Profiler source on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://nick-dunn.co.uk/assets/files/symphony.firebug-profiler.png" alt="Firebug Profiler" title=""&gt;&lt;/img&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 09 Jun 2009 11:14:00 +0100</pubDate>
    <feedburner:origLink>http://nick-dunn.co.uk/article/developing-with-symphony-using-the-firebug-console/</feedburner:origLink></item>
    <item>
      <title>An alternative 'for' loop using XSLT and template callbacks</title>
      <link>http://feedproxy.google.com/~r/nickdunn/~3/-HZ5QrEGTYE/</link>
      <description>&lt;p&gt;XSLT is planted firmly in the declarative programming style — something that regularly frustrates newcomers from procedural languages such as PHP or JavaScript. You need to change your programming mindset to approach familiar concepts in new ways. One such example is the traditional &lt;code&gt;for&lt;/code&gt; loop. In XSLT there exists a &lt;code&gt;for-each&lt;/code&gt; element which iterates over an XML nodeset:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:for-each select="countries/country"&gt;
    &lt;xsl:value-of select="text()"/&gt;
&lt;/xsl:for-each&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As dandy as this is, it relies on having XML to iterate over. How can you achieve a &lt;code&gt;for&lt;/code&gt; loop to provide, say, ten iterations, from 1 to 10. In PHP this would be a simple as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;for($i=1; $i&lt;=10; $i++) {
    echo($i);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To achieve this using XSLT you need to take a different approach. Below I’ll outline two ideas — one a simple hack, the other more advanced and elegant — for generating a &lt;code&gt;for&lt;/code&gt; loop using XSLT 1.0.&lt;/p&gt;

&lt;h2&gt;1. Tokens at the ready&lt;/h2&gt;

&lt;p&gt;Using the &lt;code&gt;tokenize()&lt;/code&gt; function of the EXSLT &lt;code&gt;strings&lt;/code&gt; library one can break a string of a given length into individual characters and loop through each:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:for-each select="str:tokenize('..........')/token"&gt;
    &lt;xsl:value-of select="position()"/&gt;
&lt;/xsl:for-each&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are then full-stops in the string, meaning that ten &lt;code&gt;token&lt;/code&gt; nodes will be created. Not particularly elegant or maintainable. This can be improved on slightly by generating the string dynamically, making it easier to change its length:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:for-each select="str:tokenize(str:padding(10,'.'))/token"&gt;
    &lt;xsl:value-of select="position()"/&gt;
&lt;/xsl:for-each&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;padding()&lt;/code&gt; function creates a string of a given length.&lt;/p&gt;

&lt;h2&gt;2. Recursive to the max&lt;/h2&gt;

&lt;p&gt;The more ‘XSL-like’ approach is to use a recursive &lt;code&gt;call-template&lt;/code&gt; to execute the iteration. The template is supplied with start and end conditions and repeatedly calls itself until the end condition is met. The finest explanation I’ve seen is &lt;a href="http://www.ibm.com/developerworks/xml/library/x-tiploop.html"&gt;Loop with recursion in XSLT&lt;/a&gt; on IBM developerWords. Recommended reading.&lt;/p&gt;

&lt;p&gt;Writing a recursive template to achieve the above requirement is relatively trivial:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:template name="for-loop"&gt;
    &lt;xsl:param name="count" select="1"/&gt;

    &lt;xsl:if test="$count &gt; 0"&gt;
        &lt;xsl:value-of select="$count"/&gt;
        &lt;xsl:call-template name="for-loop"&gt;
            &lt;xsl:with-param name="count" select="$count - 1"/&gt;
        &lt;/xsl:call-template&gt;
    &lt;/xsl:if&gt;

&lt;/xsl:template&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem here is that the template output is muddled into the same template as the iteration/recursion logic. It would make more sense to have a single “iterator” template to perform the recursion, and have the output rendered in a separate template. Consider the following scenario:&lt;/p&gt;

&lt;p&gt;You’re building a form and need to fill a select drop down with ten options (1–10), but you also need to render five checkboxes. Using the above example you would need to replicate the template twice, naming them &lt;code&gt;select-loop&lt;/code&gt; and &lt;code&gt;checkbox-loop&lt;/code&gt;. Inside each respective template you would change the output to return either an &lt;code&gt;&lt;option&gt;&lt;/code&gt; element or a checkbox.&lt;/p&gt;

&lt;p&gt;My colleague &lt;a href="http://github.com/yourheropaul/"&gt;Paul Garrett&lt;/a&gt; and I have devised a cunning way for a &lt;code&gt;call-template&lt;/code&gt; to execute a callback template which is where the custom rendering is achieved.&lt;/p&gt;

&lt;p&gt;Consider this markup to render a select box with ten options, followed by five checkboxes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:template match="data"&gt; 

    &lt;select&gt;
        &lt;xsl:call-template name="iterator"&gt;
            &lt;xsl:with-param name="iterations" select="'10'"/&gt;
            &lt;xsl:with-param name="callback" select="'render-option'"/&gt;
        &lt;/xsl:call-template&gt;
    &lt;/select&gt;

    &lt;xsl:call-template name="iterator"&gt;
        &lt;xsl:with-param name="iterations" select="'5'"/&gt;
        &lt;xsl:with-param name="callback" select="'render-checkbox'"/&gt;
    &lt;/xsl:call-template&gt;

&lt;/xsl:template&gt;

&lt;xsl:template match="render-option" mode="iterator-callback"&gt;
    &lt;xsl:param name="position"/&gt;
    &lt;option&gt;
        &lt;xsl:value-of select="$position"/&gt;
    &lt;/option&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="render-checkbox" mode="iterator-callback"&gt;
    &lt;xsl:param name="position"/&gt;
    &lt;input type="checkbox" name="fields[checkbox-{$position}]"/&gt;
&lt;/xsl:template&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can call a generic &lt;code&gt;iterator&lt;/code&gt; template passing the number of iterations required (as you would a traditional &lt;code&gt;for&lt;/code&gt; loop) while providing the name of a callback template. The iterator template creates an XML node of the same name and selects it using an &lt;code&gt;apply-templates&lt;/code&gt;. The callback template is passed the position in the loop providing context.&lt;/p&gt;

&lt;p&gt;The full &lt;code&gt;iterator&lt;/code&gt; template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:template name="iterator"&gt;
    &lt;xsl:param name="start" select="'1'"/&gt;
    &lt;xsl:param name="iterations" select="$iterations"/&gt;
    &lt;xsl:param name="direction" select="'+'"/&gt;
    &lt;xsl:param name="callback"/&gt;
    &lt;xsl:param name="callback-params"/&gt;

    &lt;xsl:param name="count" select="$iterations"/&gt;

    &lt;xsl:if test="$callback and $count &gt; 0"&gt;

        &lt;xsl:variable name="position"&gt;
            &lt;xsl:choose&gt;
                &lt;xsl:when test="$direction='-'"&gt;&lt;xsl:value-of select="$start - ($iterations - $count)"/&gt;&lt;/xsl:when&gt;
                &lt;xsl:otherwise&gt;&lt;xsl:value-of select="$start + ($iterations - $count)"/&gt;&lt;/xsl:otherwise&gt;
            &lt;/xsl:choose&gt;
        &lt;/xsl:variable&gt;

        &lt;xsl:variable name="callback-node"&gt;
            &lt;xsl:element name="{$callback}"&gt;
                &lt;xsl:if test="$callback-params"&gt;
                    &lt;xsl:copy-of select="$callback-params"/&gt;
                &lt;/xsl:if&gt;
            &lt;/xsl:element&gt;
        &lt;/xsl:variable&gt;

        &lt;xsl:apply-templates select="exsl:node-set($callback-node)" mode="iterator-callback"&gt;
            &lt;xsl:with-param name="position" select="$position"/&gt;
        &lt;/xsl:apply-templates&gt;

        &lt;xsl:call-template name="iterator"&gt;
            &lt;xsl:with-param name="start" select="$start"/&gt;
            &lt;xsl:with-param name="iterations" select="$iterations"/&gt;
            &lt;xsl:with-param name="direction" select="$direction"/&gt;
            &lt;xsl:with-param name="callback" select="$callback"/&gt;
            &lt;xsl:with-param name="callback-params" select="$callback-params"/&gt;
            &lt;xsl:with-param name="count" select="$count - 1"/&gt;
        &lt;/xsl:call-template&gt;

    &lt;/xsl:if&gt; 

&lt;/xsl:template&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Additional parameters can be passed for more advanced iterations and callbacks:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;start&lt;/code&gt; allows you to start the iteration from a specific number, defaults to 1:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:with-param name="start" select="'3'"/&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;iterations&lt;/code&gt; is the number of iterations to perform:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:with-param name="iterations" select="'100'"/&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;direction&lt;/code&gt; allows you to count down (“-“) rather than the default up (“+”)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:with-param name="direction" select="'-'"/&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;callback&lt;/code&gt; is the name of the XML node created to match on with your callback template&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:with-param name="callback" select="'my-template'"/&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;callback-params&lt;/code&gt; accepts XML which are then passed to the callback template&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;xsl:with-param name="callback-params"&gt;
    &lt;name&gt;Nick Dunn&lt;/name&gt;
&lt;/xsl:with-param&gt;

&lt;xsl:template match="render-user" mode="iterator-callback"&gt;
    &lt;xsl:param name="position"/&gt;
    &lt;p&gt;Name: &lt;xsl:value-of select="name"/&gt;&lt;/p&gt;
&lt;/xsl:template&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Note: you will need to include the EXSLT &lt;code&gt;common&lt;/code&gt; namespace in your stylesheet to use the &lt;code&gt;node-set&lt;/code&gt; function in the template above!)&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;We have seen the different ways of achieving a numeric &lt;code&gt;for&lt;/code&gt; loop in XSLT, and in doing so created a re-usable recursive template with a dynamic callback. I’ve not seen this callback method documented anywhere else, so this may be a new technique that has novel applications beyond this example. Recurse to the max, don’t tokenize.&lt;/p&gt;</description>
      <pubDate>Wed, 20 May 2009 12:55:00 +0100</pubDate>
    <feedburner:origLink>http://nick-dunn.co.uk/article/an-alternative-for-loop-using-xslt-and-template-ca/</feedburner:origLink></item>
  </channel>
</rss>
