<?xml version="1.0"  encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="http://blah.thingsinjars.com/includes/style/rss.css" ?>
<rss version="2.0">
<channel>
<title>thingsinjars</title>
<link>http://blah.thingsinjars.com/</link>
<description>???</description>
<language></language>
<docs>This file is an RSS 2.0 file, please see: en.wikipedia.org/wiki/RSS_(file_format) for more info.</docs>
<lastBuildDate>Array PDT</lastBuildDate>
<ttl>45</ttl><item>
<title>licences.xml</title>
<link>http://blah.thingsinjars.com/post/290/licencesxml/</link>
<guid>http://blah.thingsinjars.com/post/290/licencesxml/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-290">
    				<div><p>JavaScript libraries and CSS frameworks are very popular these days. With each library, plugin, extension and template, comes another licencing statement. For most of these licences (<a href="http://www.opensource.org/licenses/mit-license.php">MIT</a>, for instance), you must include the licence statement in order to be able to use the code. In many cases, you also have to provide the original source and your own modifications. While, for uncompiled technologies such as these, this is a trivial matter, both this requirement and that of including the licence are awkward to implement if you like to minify your code. The licence is usually kept in an uncompressed comment at the top of the library (the YUI compressor specifically takes this into account with comments marked /*!  */ ) and, although anyone can read your modifications to whatever you've used, post-minification code is much harder to follow (cf. three of my last four blog posts) and is really not 'in the spirit' of sharing your code.</p>
<p>I'd like to be able to bundle all the licences and sources together outside the production files. Somewhere the interested user would be able to look them up if they liked but not somewhere that would automatically be downloaded on a standard visit. To that end, I have looked around for an established standard for this and not found anything. If you know of one, please let me know. Until I do find a good standard, here's my suggestion – a simple <abbr title="eXtensible Markup Language">XML</abbr> file located at /licences.xml in the format outlined below. It contains details of the file the licence pertains to, the uncompressed source (optional), the title of the licence and a URL where the full licence text can be found (on opensource.org or creativecommons.org, for instance). It also includes a (probably superfluous) shortname for the licence. I might remove that bit. You can optionally include this meta in your HTML if you want an explicit link between your source and the licence file:</p>
<pre><code>&lt;meta name="licences" value="/licences.xml" /&gt;</code></pre> 
<p>I'm currently undecided as to whether to go with XML or <abbr title="JavaScript Object Notation">JSON</abbr>. They're fairly interchangeable (barring XML attributes) but JSON takes less space. Then again, there's not as much need to save space in this file. Anyone have any recommendations? The entire format is, of course, up for discussion. Have I forgotten anything? Have I included anything unnecessary? I'm going to start using this in my projects until someone points out some major legal problem with it, I think.</p>
 
<h2>XML</h2> 
<pre> 
&lt;licences&gt;
 &lt;licence&gt;
  &lt;source&gt;
   &lt;url&gt;
    /includes/script/jquery/1.4/jquery.min.js
   &lt;/url&gt;
   &lt;uncompressed&gt;
    /includes/script/jquery/1.4/jquery.js
   &lt;/uncompressed&gt;
  &lt;/source&gt;
  &lt;deed&gt;
   &lt;title&gt;
   MIT License
   &lt;/title&gt;
   &lt;url&gt;
    http://www.opensource.org/licenses/mit-license.php
   &lt;/url&gt;
   &lt;shortform&gt;
   MIT
   &lt;/shortform&gt;
  &lt;/deed&gt;
 &lt;/licence&gt;
 &lt;licence&gt;
  &lt;source&gt;
   &lt;url&gt;
    /includes/script/custom/0.1/custom.js
   &lt;/url&gt;
   &lt;uncompressed&gt;
    /includes/script/custom/0.1/custom.min.js
   &lt;/uncompressed&gt;
  &lt;/source&gt;
  &lt;deed&gt;
   &lt;title&gt;
   Attribution Share Alike
   &lt;/title&gt;
   &lt;url&gt;
    http://creativecommons.org/licenses/by-sa/3.0
   &lt;/url&gt;
   &lt;shortform&gt;
   cc by-sa
   &lt;/shortform&gt;
  &lt;/deed&gt;
 &lt;/licence&gt;
&lt;/licences&gt;
</pre> 
<h2>JSON</h2> 
<pre> 
{
 licences:{
  {
   source:{
    url:'/includes/script/jquery/1.4/jquery.min.js',
    uncompressed:'/includes/script/jquery/1.4/jquery.js'
   },
   deed:{
    title:'MIT License',
    url:'http://www.opensource.org/licenses/mit-license.php',
    shortform:'MIT'
   }
  },
  {
   source:{
    url:'/includes/script/custom/0.1/custom.min.js',
    uncompressed:'/includes/script/custom/0.1/custom.js'
   },
   deed:{
    title:'Attribution Share Alike',
    url:'http://creativecommons.org/licenses/by-sa/3.0',
    shortform:'cc by-sa'
   }
  }
 }
}
</pre></div>    			</div>
    ]]></description>
<pubDate>Fri, 20 Aug 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Maze 1k</title>
<link>http://blah.thingsinjars.com/post/296/maze-1k/</link>
<guid>http://blah.thingsinjars.com/post/296/maze-1k/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-296">
    				<div><ul><li><a href="/widgets/js1k3.html">Random perfect maze generation, solution and rendering in 1011 bytes</a></li></ul>

<p>Okay, this is the last one for a while. Really.</p>

<p>Unlike my previous 1k JavaScript demos, I really had to struggle to get this one into the 1024 byte limit. I'd already done all the magnification and optimization techniques I knew of so I had to bring in some things which were new to me from <a href="http://qfox.nl/notes/111">qfox.nl</a> and <a href="http://benalman.com/news/2010/08/organ1k-js1k-contest-entry/">Ben Alman</a> and a few other places. This, combined with some major code refactoring, brought it down from 1.5k to just under 1. In the process, all possible readability was lost so here's a quick run through what it does and why.</p>

<h2>First up, a bunch of declarations.</h2>

<p>These are the colours used to draw the maze. Note, I used the shortest possible way to write each colour (<code>red</code> instead of <code>#F00</code>, <code>99</code> instead of <code>100</code>). The value stored in the maze array (mentioned later) refers not only to the type of block it is but also to the index of the colour in this array, saving some space.</p>
<pre><code>u = ["#eff", "red", "#122", "rgba(99,255,99,.1)", "#ff0"],</code></pre>

<p>This is used for the number of blocks wide and high the maze is, the number of pixels per block, the size of the canvas and the redraw interval. Thanks to <a href="http://github.com/cowboy/js1k-organ1k/blob/master/organ1k.js">Ben Alman</a> for pointing out in his article how to best use a constant.</p>
<pre><code> c = 21,</code></pre>

<p>Here is the reference to the canvas. Mid-minification, I did have a bunch of function shortcuts here - <code>r=Math.random</code>, for instance - but I ended up refactoring them out of the code.</p>
<pre><code>m = document.body.children[0];</code></pre>

<p>For most of the time when working on this, the maze was wider than it was high because I thought that made a more interesting maze. When it came down to it, though, it was really a matter of bytesaving to drop the distinct values for width and height. After that, we grab the canvas context so we can actually draw stuff.</p>
<pre><code>m.width = m.height = c * c;
h = m.getContext("2d");</code></pre>

<h2>The drawing function</h2>
<p>The generation and solution algorithm is quite nice and all but without this to draw it on the screen, it's really just a mathematical curio. This takes a colour, x and y and draws a square.</p>

<pre><code>l = function (i, e, f) {
  h.fillStyle = i;
  h.fillRect(e * c, f * c, c, c)
};</code></pre>

<h2>Designing a perfect maze</h2>
<blockquote>
<p>"You've got 1 minute to design a maze it takes 2 minutes to solve."<br />- Cobb, Inception.</p>
</blockquote>
<p>Apologies for the unnecessary Inception quote. It's really not relevant.</p>

<p>Algorithmically, this is a fairly standard <a href="http://en.wikipedia.org/wiki/Maze_solving_algorithm">perfect maze</a> generator. It starts at one point and randomly picks a direction to walk in then it stops picks another random direction and repeats. If it can't move, it goes back to the last choice it made and picks a different direction, if there are no more directions, all blocks have been covered and we're done. In a perfect maze, there is a path (and only one path) between any two randomly chosen points so we can make the maze then denote the top left as the start and the bottom right as the end. This particular algorithm takes 2 steps in every direction instead of 1 so that we effectively carve out rooms and leave walls. You can take single steps but it's actually more of a hassle.</p>

<p>For more on how this kind of maze-generation works, check out this article on <a href="http://www.emanueleferonato.com/2008/12/06/perfect-maze-generation-tile-based-version/">Tile-based maze generation</a>.</p>

<h3>Blank canvas</h3>
<p>This is a standard loop to create a blank maze full of walls with no corridors. The <code>2</code> represents the 'wall' block type and the colour <code>#122</code>. The only really odd thing about this is the code <code>f-->0</code> which is not to be read 'as f tends to zero' but is instead 'decrement f by 1, is it greater than zero?'</p>
<pre><code>g = function () {
  v = [];  //our stack of moves taken so we can retrace our steps.
  for (i = [], e = c; e-- > 0;) {
    i[e] = [];
    for (f = c; f-- > 0;) i[e][f] = 2
  }</code></pre>

<p>By this point, we have a two-dimensional JavaScript array filled with 2s</p>

<h3>Putting things in</h3>
<pre><code>  f = e = 1;    // our starting point, top left.
  i[e][f] = 0; // us, the zippy yellow thing</code></pre>

<h3>Carving out the walls</h3>
<p>This is our first proper <em>abuse</em> of the standard for-loop convention. You don't need to use the three-part structure for 'initialize variable; until variable reaches a different value; change value of variable'. It's 'do something before we start; keep going until this is false; do this after every repetition' so here we push our first move onto the stack then repeat the loop while there's still a move left on the stack.</p>
<pre><code>  for (v.push([e, f]); v.length;) {</code></pre>

<p>P here is the list of potential moves from our current position. For every block, we have a look to see what neighbours are available then concatenate that cardinal direction onto the strong of potential moves. This was originally done with bitwise flags (the proper way) but it ended up longer. It's also a bit of a nasty hack to set p to be 0 instead of "" but, again, it's all about the bytes.</p>
<pre><code>  p = 0;</code></pre>

<h3>Can we walk this way?</h3>
<p>These are all basically the same and mean 'if we aren't at the edge of the board and we're looking at a wall, we can tunnel into it.'.</p>
<pre><code> if (e < 18 && i[e + 2][f] == 2) p += "S"
 if (e >= 2 && i[e - 2][f] == 2) p += "N";
 if (f >= 2 && i[e][f - 2] == 2) p += "W";
 if (i[e][f + 2] == 2) p += "E";

 if (p) { //    If we've found at least one move
  switch (p[~~ (Math.random() * p.length)]) { // randomly pick one</code></pre>
<p>If there was anything to note from that last chunk, it would be that the operator <code>~~</code> can be used to floor the current value. It will return the integer below thye current value.</p>

<h3>Take two steps</h3>
<p>This is a nice little hack. Because we're moving two spaces, we need to set the block we're on and the next one to be 0 (empty). This takes advantage of the right-associative unary operator 'decrement before' and the right associativity of assignment operators. It subtracts 1 from e (to place us on the square immediately above) then sets that to equal 0 then subtracts 1 from the new e (to put us on the next square up again) and sets that to equal the same as the previous operation, i.e. 0.</p>
<pre><code>  case "N":
      i[--e][f] = i[--e][f] = 0;
      break;</code></pre>

<h3>Do the same for s, w and e</h3>
<pre><code>    case "S":
      i[++e][f] = i[++e][f] = 0;
      break;
    case "W":
      i[e][--f] = i[e][--f] = 0;
      break;
    case "E":
      i[e][++f] = i[e][++f] = 0
    }</code></pre>

<p>Whichever move we chose, stick that onto the stack.</p>
<pre><code>    v.push([e, f])</code></pre>

<h3>If there were no possible moves, backtrack</h3>
<pre><code>  } else {
    b = v.pop(); //take the top move off the stack
    e = b[0]; // move there
    f = b[1]
  }
 }</code></pre>

<h3>End at the end</h3>
<p>At the very end, set the bottom right block to be the goal then return the completed maze.</p>
<pre><code>  i[19][19] = 1;
  return i
};</code></pre>

<h2>Solver</h2>
<p>This is the solving function. Initially, it used the same algorithm as the generation function, namely 'collect the possible moves, randomly choose one' but this took too much space. So instead it looks for spaces north, then south, then west, then east. It follows the first one it finds.</p>
<pre><code>s = function () {</code></pre>

<p>Set the block type of the previous block as 'visited' (rgba(99,255,99,.1) the alpha value makes the yellow fade to green).</p>
<pre><code>  n[o][y] = 3;</code></pre>

<h3>A bit of ternary background</h3>
<p>This next bit looks worse than it is. It's the ternary operator nested several times. The ternary operator is a shorthand way of writing:</p>
<pre><code>if ( statement A is true ) {
  Do Action 1
} else {
  Do Action 2
}</code></pre>

<p>In shorthand, this is written as:</p>

<pre><code>Statement A ? Action 1 : Action 2;</code></pre>

<p>In this, however, I've replace Action 2 with another ternary operator:</p>

<pre><code>Statement A ? Action 1 : ( Statement B ? Action 2 : Action 3 );</code></pre>

<p>And again, and again. Each time, it checks a direction, if it's empty, mark it as visited and push the move onto our stack.</p>
<pre><code>(n[o + 1][y] < 2) ?
  (n[++o][y] = 0, v.push([o, y])) :
    (n[o - 1][y] < 2) ?
      (n[--o][y] = 0, v.push([o, y])) :
        (n[o][y - 1] < 2) ?
          (n[o][--y] = 0, v.push([o, y])) :
            (n[o][y + 1] < 2) ?
              (n[o][++y] = 0, v.push([o, y])) :</code></pre>

<h3>If none of the neighbours are available, backtrack</h3>
<pre><code>                (b = v.pop(), o = b[0], y = b[1]);</code></pre>

<h3>Show where we are</h3>
<p>Finally, set our new current block to be yellow</p>
<pre><code>  n[o][y] = 4;</code></pre>

<h3>Are we there yet?</h3>
<p>If we are at the bottom right square, we've completed the maze</p>
<pre><code>  if (o == 19 && y == 19) {
  n = g();    //Generate a new maze
  o = y = 1; //Move us back to the top right
  s()     //Solve again</code></pre>

<p>If we haven't completed the maze, call the solve function again to take the next step but delay it for 21 milliseconds so that it looks pretty and doesn't zip around the maze too fast.</p>
<pre><code>  } else setTimeout(s, c);</code></pre>

<h3>Paint it black. And green. And yellow.</h3>
<p>This is the code to render the maze. It starts at the top and works through the whole maze array calling the painting function with each block type (a.k.a. colour) and position.</p>
<pre><code>    for (d in n) for (a in n[d]) l(u[n[d][a]], a, d)
  };</code></pre>

<h2>Start</h2>
<p>This is the initial call to solve the maze. The function s doesn't take any arguments but by passing these in, they get called before s and save a byte that would have been used if they had been on a line themselves.</p>
<pre><code>s(n = g(), o = y = 1)</code></pre>

<h2>Done</h2>
<p>This little demo isn't as visually appealing as the <a href="/post/294/art-maker-1k/">Art Maker 1k</a> or as interactive as the <a href="/post/292/elementally-my-dear-javascript/">Spinny Circles 1k</a> but it is quite nice mathematically. There are now some astounding pieces of work in the <a href="http://js1k.com">JS1K demo competition</a>, though. I do recommend spending a good hour playing about with them all. Don't, however, open a bunch of them in the background at the same time. Small code isn't necessarily memory-efficient and you could quite easily grind your computer to a standstill.</p></div>    			</div>
    ]]></description>
<pubDate>Thu, 19 Aug 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Art Maker 1K</title>
<link>http://blah.thingsinjars.com/post/294/art-maker-1k/</link>
<guid>http://blah.thingsinjars.com/post/294/art-maker-1k/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-294">
    				<div><p>Even though the rules for <a href="http://js1k.com">js1k</a> only let me make one submission, I couldn't stop myself making another. This one is inspired by those pseudo-romantic pictures that you get <a href="http://fueledbyphotos.com/">all</a> <a href="http://icanread.tumblr.com/">over</a> <a href="http://everythingsright.com/">tumblr</a> that get reblogged endlessly (actually, it was inspired by the blog <a href="http://thatisntart.com/">That Isn't Art</a> by someone with the same opinion as myself).</p>

<p>It randomly creates a sentence, adds some softly-moving almost bokeh coloured-circles and look, I made an art! Wait for the sentence to change or click (or touch) to change it yourself.</p>

<p><a href="/widgets/js1k2.html">Art Maker 1k</a></p>

<p>And of course, don't forget the original <a href="/widgets/js1k.html">spinny-circles 1k</a></p></div>    			</div>
    ]]></description>
<pubDate>Thu, 12 Aug 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>The quest for Extreme JavaScript Minification</title>
<link>http://blah.thingsinjars.com/post/293/the-quest-for-extreme-javascript-minification/</link>
<guid>http://blah.thingsinjars.com/post/293/the-quest-for-extreme-javascript-minification/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-293">
    				<div><p>As <a href="http://blah.thingsinjars.com/post/292/elementally-my-dear-javascript/" title="Elementally, my dear JavaScript">described in detail previously</a>, I've recently taken part in the <a href="http://js1k.com">JS1K</a> competition where you have to squeeze something cool and clever into 1024 bytes of JavaScript. The quest to condense has become quite addictive and I found myself obsessing over every byte. This is the kind of stuff that the <a href="http://code.google.com/closure/compiler/">Closure Compiler</a> does quite well automatically but there are some cases where you just need to get in there and manually tweak.</p> 

<p>Here are some of the tricks I've picked up in my struggle for extreme minification:</p>

<h2>Basic improvements</h2>
<h3>Use short variable names.</h3> 
<p>This one's fairly obvious. A more useful addition to this is:</p>
<h3>Shorten long variable names.</h3>
<p>If you're going to be accessing an element more than once, especially if it's a built-in element like 'document', you'll save a few bytes every time you reference it if you create a shortened reference to it.</p>
<pre><code>  document.body.style.overflow="hidden"
  document.body.style.background="red"
  (74 characters)
</code></pre>
<p>can shorten to</p>
<pre><code>  d=document;b=d.body;s=b.style;
  s.overflow="hidden";
  s.background="red"
  (69 characters)
</code></pre>
<p>and any references to <code>s</code> after are going to save 19 characters every time.</p>
<h3>Remove whitespace</h3>
<p>This one's so obvious, I don't need to mention it.</p>
<h3>Set Interval</h3>
<p>The extremely handy <code>setInterval</code> function can take either a function or a string. If you give it an anonymous function declaration:</p>
<pre><code>  setInterval(function(){x++;y--},10);
</code></pre>
<p>You will use up more characters than if you give it just the inside of the function as a string:</p>
<pre><code>  setInterval('x++;y--',10);
</code></pre>
<p>But the outcome will be the same.</p>

<h2>Little-used aspects</h2>
<p>Not many people use JavScript's scientific notation unless they're doing scientific stuff but it can be a great byte saver. The number <code>100</code> is equivalent to <code>1 * 10^2</code> which is represented in JavaScript as 1E2. That's not a great saving for 100 but 1000 is 1E3, 10000 is 1E4. Every time you go up a factor of 10, you save 1 byte.</p>


<h2>Fight your good style tendencies</h2>
<p>In the war against space, you have to bite the bullet and accept that you may need to sacrifice some of your hard-earned practices. But only this once. Don't get in to the habit, okay?</p>
<h3>No zeroes</h3>
<pre><code>  0.5  = .5
</code></pre>
<p>Yeah, it looks ugly but it works and saves a byte.</p>
<h3>Naked clauses</h3>
<pre><code>  if {
    :
    :
  } else y
</code></pre>
<p>The <code>y</code> looks so naked out there. No braces to keep it warm. But if you only have one statement in your else clause, you don't need them...</p>
<h3>No semi-final. . . final-semi. . . Semi-colon. No final colon.</h3>
<p>You don't need a semi-colon on your last line, even if it does make it look as though you've stunted its growth.</p>

<h2>The final few bytes</h2>
<h3>Operator precedence</h3>
<p>You don't need brackets. Brackets are handy for you as the programmer to remember what's going on when and to reduce ambiguity but if you plan correctly, most of the time you won't need brackets to get your arithmetic to work out.</p>
<pre><code>  b.getMilliseconds()/(a*250) 
      is the same as
  b.getMilliseconds()/a/250 
</code></pre>
<h3>Shorthand notation</h3>
<pre><code>  l=l+1;l=l%14;
  l++;l%=14;
  l=++l%14;
</code></pre>
<p>The three lines above are equivalent and in order of bytes saved.</p>
<h3>Shorthand CSS</h3>
<p>If you need to set some CSS values in your script, remember to pick the most appropriate short form. Instead of <code>s.background='black'</code>, use  <code>s.background='#000'</code> but instead of <code>s.background='#F00'</code>, use <code>s.background='red'</code>. In the same vein, the statements <code>margin="0px"</code> and <code>margin=0</code> mean the same but the latter saves bytes.</p>

<h2>Don't be generic</h2>
<p>One final thing to mention is that these little challenges are not the norm. If you find yourself trying to squeeze code down like this you're probably working on a very specific project. Use that to your advantage and see if there are any savings to be made by discarding your usual policies on code reuse. In the JS1K challenge, we're provided with a specific <a href="http://js1k.com/demo">HTML page</a> and an empty script tag. One good saving made here (and mentioned in my previous post) was the way I grabbed the reference to the canvas element. The standard method is to use the id assigned to the canvas.</p>
<pre><code>  d.getElementById('c')
</code></pre>
<p>Which is a good generic solution. No matter what else was on the page, no matter what order stuff was in, this would return the canvas. However, we have a very specific case here and the canvas is always going to be in the same place - the first child of the body element. That means we can do this instead:</p>
<pre><code>  b.children[0]
</code></pre>
<p>This makes use of the reference we grabbed to the body earlier. If the page were rearranged, this would stop working but as it won't, we've saved 8 bytes.</p>

<h2>In conclusion</h2>
<p>Yes, this is all quite silly but it's also fun and tricky. Attempting these kinds of challenges keep us developers mindful of what it is we actually do and that makes it an extremely productive silly hobby.</p></div>    			</div>
    ]]></description>
<pubDate>Sun, 08 Aug 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Elementally, my dear JavaScript</title>
<link>http://blah.thingsinjars.com/post/292/elementally-my-dear-javascript/</link>
<guid>http://blah.thingsinjars.com/post/292/elementally-my-dear-javascript/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-292">
    				<div><p><a href="http://www.angryrobotzombie.com">The Angry Robot Zombie Factory</a> launched its second iPhone/iPad app <time datetime="2010-08-01">this week</time>. I haven't mentioned it much yet because I spotted a minor typo in the final version after it had been approved so I submitted an update immediately. To get an early copy (like those misprinted stamps where the plane is upside down), go check out <a href="http://itunes.apple.com/app/the-elementals/id383675775?mt=8">The Elementals</a>. It's free, too. It's a simple, cartoonish periodic table.</p>
<p>Yesterday, the <a href="http://js1k.com">1k JavaScript demo contest</a> (<a href="http://twitter.com/#search?q=js1k">#js1k</a>) caught my eye. The idea is to create something cool using 1024bytes of JavaScript or less. I rootled around in the middle of The Elementals, grabbed the drawing function and 20 minutes later had made <a href="http://js1k.qfox.nl/demo/21">my entry</a>.</p>
<p>The code I submitted is quite minified but isn't obfuscated. When it's unfolded, you can follow the flow fairly easily.</p>

<pre><code>var d = document,
b = d.body,
s = b.style,
w = innerWidth,
h = innerHeight,
v = b.children[0],
p = 2 * Math.PI,
Z = 3,
x = tx = w / 2,
y = ty = h / 2;
</code></pre>

<p>The above is a bunch of declarations. Using things like <code>d = document</code> and <code>b = d.body</code> allows reuse later on without having to resort to the full <code>document.body.style</code> and saves a bunch of characters. When you've got such a small amount of space to play with, every character counts (mind you, the <a href="http://en.wikipedia.org/wiki/ZX81">ZX81</a> only had 1k of RAM and look what you could do with that). Now that I'm looking at it, I think I could have tidied this a bit more. Darn. The sneaky bit about this code is the way we grab the reference to the canvas. The code <code>d.getElementById('c')</code> uses 21 characters but if we look at the provided HTML, we can use the fact that the canvas is the first child of the body element. The code <code>b.children[0]</code> uses 13 characters instead.</p>

<pre><code>s.margin = "0px";
s.background = "black";
s.overflow = "hidden";
v.width = w;
v.height = h;
t = v.getContext("2d");
</code></pre>

<p>This sets the provided canvas to be the full width and height of the window then grabs the drawing context of it so we can make pretty pictures.</p>

<pre><code>zi = function () {
 Z++;
 Z %= 14
};
m = function (X) {
 return (X * 200) % 255
};
</code></pre>

<p>Functions to be reused later. <code>zi</code> increases the number of spinning circles and is used by onmousedown and ontouchstart (oh yes, it works on the iPad, too). <code>m</code> is a mapping of the index of the circle to a colour. The 200 is arbitrary. I played about a bit until I found some colour combinations I liked.</p>

<pre><code> d.ontouchstart = function (e) {
 zi();
 tx = e.touches[0].pageX;
 ty = e.touches[0].pageY
};
d.onmousemove = function (e) {
 tx = e.clientX;
 ty = e.clientY
};
d.onmousedown = zi;
</code></pre>

<p>Setting the event handlers.</p>

<pre><code>function r() {
 t.globalCompositeOperation = 'lighter';
</code></pre>

<p>I played about with the <a href="https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html">various composite operations</a>. Lighter seemed the nicest.</p>

<pre><code> t.clearRect(0, 0, w, h);
 t.save();
 x = x + (tx - x) / 20;
 y = y + (ty - y) / 20;
 t.translate(x, y);
</code></pre>

<p>Originally, the circles followed the mouse pointer exactly but it lacked any life. By adding in this bit where the movement is delayed as if pulling against friction, it suddenly became a lot more fun and dynamic.</p>

<pre><code> var c = new Date();
 for (var i = 1; i <= Z; i++) {
  t.fillStyle = 'rgba(' + m(i) * (i % 3) + ', ' + m(i) * ((i + 1) % 3) + ',' + m(i) * ((i + 2) % 3) + ', 0.5)';
  t.beginPath();
  t.rotate((c.getSeconds() + i) / (i / 4) + (c.getMilliseconds()) / ((i / 4) * 1000));
  t.translate(i, 0);
  t.arc(-10 - (Z / 5), -10 - +(Z / 5), 100 - (Z * 3), 0, p, false);
  t.fill()
 }
</code></pre>

<p>Erm. Yeah. In essence, all this does is figure out where to draw the circles, how big and what colour. It looks worse than it is. Line-by-line, it translates to:</p>
<ol>
	<li>Find out the current time</li>
	<li>For each circle we want to draw, </li>
	<li>Pick a colour based on the index of the circle</li>
	<li>Start drawing</li>
	<li>Turn by some amount based on the time and the index</li>
	<li>Move by a small amount based on the index</li>
	<li>Actually draw, making the circles smaller if there are more of them.</li>
	<li>Fill in the circle with the colour.</li>
	<li>Right curly bracket.</li>
</ol>

<pre><code> t.save();
 t.fillStyle = "white";
 for (var i = 1; i <= Z; i++) {
  t.beginPath();
  t.rotate(2);
  t.translate(0, 28.5);
  t.arc(-120, -120, 5, 0, p, false);
  t.fill()
 }
 t.restore();
 t.restore()
}
</code></pre>

<p>This does pretty much the same as the one above but always the same size and always the same colour. The <code>t.save</code> and <code>t.restore</code> operations throughout mean we can add the transformations onto each other and move stuff relative to other stuff without messing up everything. Goshdarn, that was technical.</p>

<pre><code>setInterval(r, 10);
</code></pre>
<p>Kick it all off.</p>

<p>That make sense? Good. Now go make your own <a href="http://js1k.com">js1k</a> entry and submit it. Then download <a href="http://itunes.apple.com/app/the-elementals/id383675775?mt=8">The Elementals</a>. Or <a href="http://harmoniousapp.com">Harmonious</a>.</p></div>    			</div>
    ]]></description>
<pubDate>Wed, 04 Aug 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>PhoneGap - The Drupal of App development</title>
<link>http://blah.thingsinjars.com/post/291/phonegap---the-drupal-of-app-development/</link>
<guid>http://blah.thingsinjars.com/post/291/phonegap---the-drupal-of-app-development/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-291">
    				<div><p>I'm a fan of <a href="http://drupal.org/">Drupal</a> even though I don't use it that often. I like that I can see exactly what's going on. I can easily follow the execution from URL request to page serve.</p>
<p>What I usually end up doing on any Drupal project is:</p>
<ol>
	<li>build the majority of the site in a few hours</li>
	<li>find one small piece of functionality missing that's absolutely essential</li>
	<li>dig into the core to make it happen</li>
	<li>find a simpler way of doing it and step out of the core a bit</li>
	<li>find an even simpler way and step back a bit more</li>
	<li>figure out how to do it in a single module file and put the core back the way it was.</li>
</ol>
<p>That probably seems utterly inefficient but it has served me well since Drupal 4 and it means I've got a really good picture in my head of the internal workflow.</p>
<p>This is in stark comparison to other systems, particularly some .NET <acronym title="Content Management Systems">CMSs</acronym> where a request comes in, <em>something</em> happens and the page is served. There are even some <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> frameworks and <acronym title="Content Management Systems">CMSs</acronym> where everything is so abstracted, the only way you can get an accurate picture of what is happening is to already <em>have</em> an accurate picture of what is happening.</p>
<p>I've used several different ones and I keep coming back to Drupal (also, recently, <a href="http://grabaperch.com/">Perch</a>, but that's besides the point here).</p>
<p><em>“What on earth does this have to do with PhoneGap?”</em> I hear you ask. Quite rightly, too.</p>
<p>When I was planning <a href="http://harmoniousapp.com/">Harmonious</a>, I looked at various frameworks for turning a combination of <acronym title="Hyper Text Mark-up Language">HTML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym> & JavaScript into an app - <a href="http://www.phonegap.com/">PhoneGap</a>, <a href="http://www.appcelerator.com/">Appcelerator Titanium</a>, <a href="http://rhomobile.com/">Rhomobile</a>. Rhomobile (or the Rhodes Framework) is built on Ruby so I didn't investigate too far. That's not to say it's not a good framework, I couldn't say either way. The idea behind using one of these frameworks is to save you the time of having to learn Objective-C and seeing as I've only done very minimal amounts of Ruby, I'd be replacing 'learn Objective-C' with 'learn Ruby'. That said, I've always thought Ruby developers opinion of themselves was <a href="http://god.rubyforge.org/">slightly too high</a>.</p>
<p>The first framework I properly spent some time with was Appcelerator. It seemed quite shiny and I liked having single interface access to compilation for iPhone and Android but I wasn't so keen on having to sign up for an account with them for no obvious reason. Some further investigation suggested that this was so you could send your project to their servers for proprietary cross-platform compilation of your desktop app. This is less useful, however, if you're developing just for iPhone and Android as for both, you need the SDK installed locally and the compilation is done on your own machine.</p>
<p>The main thing that I wasn't comfortable with in Appcelerator was that there seemed to be a lot happening behind the scenes. This is not necessarily a bad thing, of course, but it started that little buzz in the back of my head that I get when working on .NET. When I press 'compile', I want to know exactly <em>what</em> it's doing. I want to know exactly how it takes my JavaScript and embeds it, when does it include its own API files and what do I change to make it do stuff it doesn't do by default?</p>
<p>After that, I moved to PhoneGap (version 0.8.3) and found myself immediately falling into my Drupal workflow. The app fell into place in less than an hour (with a liberal sprinkling of <a href="http://www.jqtouch.com/">jQTouch</a> and the <a href="http://www.glyphish.com/">Glyphish</a> icons). I then needed to take a screenshot and couldn't see an obvious way to do it but, due to the nature of PhoneGap being completely <a href="http://github.com/sintaxi/phonegap">open-source</a>, it was easy to spot where to jump into the code. I hacked in a screenshot function in another hour, spent another half hour making it better and another making it simpler. Just to complete the cycle, I have now wrapped up all my code into a plugin and removed my hacking from the core. Hmmm... that all seemed eerily familiar.</p>
<p>That's not to say PhoneGap is perfect. All the benefits of a completely open-source project referred to previously also come with all the drawbacks. The current version (0.9.0) is fiendishly difficult to download and get started with. It has been split into one parent project and several child projects (one per mobile platform) and it's no longer obvious what you do. It's easy enough if you're already set up but actually getting there is tricky. The most common failing of any open-source project is also true: poor documentation. There's a wiki but it's mostly out-of-date. There's a section on phonegap.com called 'docs' but they're also out-of-date. There's an API reference but it's autogenerated from comments and is also out-of-date. The only place to get accurate information is the Google group but that's not documentation, that's solutions to problems.</p>
<p>There have also been some claims that PhoneGap is unstable and crashes but personally, I haven't seen that. It's possible that the crashes and performance issues are the result of memory leaks in the JavaScript. Appcelerator automatically runs <a href="http://www.jslint.com/">JSLint</a> on your code before compilation so it will highlight any problems. If you can fit that into your standard workflow, you might be able to avoid some of the instability.</p>

<h2>Additional comments</h2>
<aside>
<p>It seems that <a href="http://disqus.com">Disqus</a> (the commenting system I'm using below) has some problems with Safari 5 &amp; Chrome so this comment was sent via <a href="http://gist.github.com/">gist</a> (I knew I shouldn't have stopped using <a href="http://blah.thingsinjars.com/post/180/noodle/" title="Noodle">Noodle</a>).</p>
<p>I'll respond later. I've just got back from the Apple store and have toys to play with.</p>
</aside>

<p><em>Comment from Jeff Haynie (<a href="http://twitter.com/jhaynie">@jhaynie</a>)</em></p>
<p>A few comments about Appcelerator.</p>
<p>1. We're completely open source and you can see all our active development every single commit on github.com/appcelerator.  We have plenty of outside core open source contributors.</p>
<p>2. Yeah, to do what we're doing, it's complicated - much more than Phonegap - so it does mean with complexity it's hard to grok.  however, the source is all there. Also, it's full extensible through our SDKs and we this SDK as the way we build Titanium itself.</p>
<p>3. For Desktop, we _only_ upload to our build servers as a convenience to cross-platform packaging.  Nothing mysterious and all the scripts we run are included (and open source) so you can run them on your own. Plenty of our customers do this behind the firewall.  When you're developing locally (say on a OSX machine), it's all local during dev. Only cross-platform packaging is done as a convenience to developers.  We have to pay for this bandwidth and storage and we do it to make it easier.  And it's free.</p>
<p>Hope this clarifies some of the above.   Phonegap's a great project and we love the team - but I think we're trying to do different things and come at it from different approaches. In the end, this is good for developers as it gives everyone more choice based on their needs.</p></div>    			</div>
    ]]></description>
<pubDate>Thu, 17 Jun 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>List of Touch UI gestures</title>
<link>http://blah.thingsinjars.com/post/289/list-of-touch-ui-gestures/</link>
<guid>http://blah.thingsinjars.com/post/289/list-of-touch-ui-gestures/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-289">
    				<div><p>Just now, I'm trying to improve the <acronym title="User Interface">UI</acronym> for the <a href="http://www.angryrobotzombie.com">Factory's</a> first <a href="http://itunes.apple.com/uk/app/harmonious/id363375481" title="harmonious. for iPhone, iPod touch, and iPad on the iTunes App Store">iPhone app</a>. While doing this, I've come up with a list of available areas and gestures in a touch-driven app that you can use for actions. I thought I'd put them here so other people could point out where I've gone wrong and what I've forgotten:</p>
<ul>
  <li>Menus
    <ul>
      <li>Permanent on-screen menu</li>
      <li>Transient on-screen menu (requires trigger)</li>
      <li>Different screen menu (any number of them, requires trigger)</li>
    </ul>
  </li>
  <li>Static (can be overloaded with function based on position)
    <ul>
      <li>Single-tap
        <ul>
        <li>Single-tap 1 touch</li>
        <li>Single-tap 2 touches</li>
        <li>Single-tap 3 touches</li>
        </ul>
      </li>
      <li>Double-tap
        <ul>
          <li>Double-tap 1 touch</li>
          <li>Double-tap 2 touches</li>
          <li>Double-tap 3 touches</li>
        </ul>
      </li>
      <li>Touch and Hold
        <ul>
          <li>Touch and Hold 1 touch</li>
          <li>Touch and Hold 2 touches</li>
          <li>Touch and Hold 3 touches</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Dynamic (Gestures)
    <ul>
      <li>Touch and Move 1 touch
        <ul>
          <li>Up</li>
          <li>Down</li>
          <li>Left</li>
          <li>Right</li>
        </ul>
      </li>
      <li>Touch and Move 2 touches
        <ul>
          <li>Up</li>
          <li>Down</li>
          <li>Left</li>
          <li>Right</li>
          <li>Apart (Zoom)</li>
          <li>Together (Pinch)</li>
          <li>Rotate clockwise</li>
          <li>Rotate anticlockwise</li>
        </ul>
      </li>
      <li>Touch and Move 3 touches
        <ul>
          <li>Up (Swipe)</li>
          <li>Down (Swipe)</li>
          <li>Left (Swipe)</li>
          <li>Right (Swipe)</li>
          <li>Apart (Spread)</li>
          <li>Together (Gather)</li>
          <li>Rotate clockwise</li>
          <li>Rotate anticlockwise</li>
        </ul>
      </li>
    </ul>      
  </li>
</ul></div>    			</div>
    ]]></description>
<pubDate>Sat, 10 Apr 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Scene and Herd archive</title>
<link>http://blah.thingsinjars.com/post/288/scene-and-herd-archive/</link>
<guid>http://blah.thingsinjars.com/post/288/scene-and-herd-archive/</guid>
<description><![CDATA[
      			<div class="teaser " id="teaser-288">
    				<div>Continuing the webcomic theme from yesterday, I finally uploaded the archive of strips from the webcomic I used to do in 2003.

It actually started off as a cartoon on flyers advertising Baby Tiger gigs before developing into music reviews for a while before ending up in the final version.

Start at the <a href="/cartoons/last/">far end of the cartoon department</a>, third floor.</div>    			</div>
    ]]></description>
<pubDate>Wed, 10 Mar 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Rules: The Comic</title>
<link>http://blah.thingsinjars.com/post/266/rules-the-comic/</link>
<guid>http://blah.thingsinjars.com/post/266/rules-the-comic/</guid>
<description><![CDATA[
      			<div class="teaser " id="teaser-266">
    				<div>I found some old sketches at the weekend and decided that I shouldn't just leave them in a drawer doing nothing.

I, therefore, present to you:

<a href="http://blah.thingsinjars.com/widgets/rules/index.html">The Rules</a>

It's kind of a web comic but it only has 19 issues, no plot and won't be continuing.</div>    			</div>
    ]]></description>
<pubDate>Tue, 09 Mar 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>The Shadow Government and a Hyperbagel</title>
<link>http://blah.thingsinjars.com/post/265/the-shadow-government-and-a-hyperbagel/</link>
<guid>http://blah.thingsinjars.com/post/265/the-shadow-government-and-a-hyperbagel/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-265">
    				<div><p>I <a href="http://blah.thingsinjars.com/post/262/synchronised-podcasts/">listen to a bunch of podcasts</a>. I watch the Daily Show and the Colbert Report. I <a href="http://www.last.fm/user/thingsinjars">listen to a lot</a> of They Might Be Giants. When you combine this with the audiobooks I listen to, the <a href="http://www.twitpic.com/ewagy">shows I go to</a> and the paper books I read, you start to spot a pattern. A slightly sinister pattern...</p>
<ul class="gallery">
<li>
<a href="/uploaded/images/expanded/theshadowgovernment.png" rel="lightbox[265]" title="The Illiternati"><img src="/uploaded/images/thumbs/theshadowgovernment.png" alt="The Illiternati" /></a></li>
</ul>
<p>This originally started as a connectivity diagram of American Literary Non-fictionists but after I'd finished I realised it's not entirely American, it's not entirely non-fictionists. It's not entirely comedy and not entirely literary. After showing it to a friend though, he immediately suggested 'The New Illuminati' or possibly the Literary Illuminati. Maybe just the Illiternati. Any way round you have it, John Hodgman appears to be as some kind of Literpope in the middle of a literspiracy.</p>
<p>From what I can figure, I need to write some world economics expos&eacute; with Planet Money, discuss the software I used to analyse the markets with This Week in Tech and appear onstage at The Moth to tell the audience how the experience changed my life then I can join the dots on the diagram and reveal the secret Iliternati symbol. I think it'll be somewhere between the <a href="http://en.wikipedia.org/wiki/File:Peace_symbol.svg">CND logo</a> and a hyperbagel.</p></div>    			</div>
    ]]></description>
<pubDate>Mon, 08 Mar 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Some kind of monster</title>
<link>http://blah.thingsinjars.com/post/263/some-kind-of-monster/</link>
<guid>http://blah.thingsinjars.com/post/263/some-kind-of-monster/</guid>
<description><![CDATA[
      			<div class="teaser " id="teaser-263">
    				<div>I've been trying to make myself sketch a lot more recently. This was mostly prompted by my decision to start up <a href="http://www.angryrobotzombie.com/">The Angry Robot Zombie Factory</a> as an actual company doing web development and illustration.

I've been keeping an <em>almost</em> daily sketch blog over on <a href="http://thingsinjars.tumblr.com/">tumblr</a> and promoting any good pieces over onto my actual <a href="http://permanentpencil.com">illustration portfolio</a>. At some point, I'll bring all these different sites and things together. Until then, here's a sketch of a few things from the last couple of weeks.</div>    			</div>
    ]]></description>
<pubDate>Thu, 04 Mar 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Synchronised Podcasts</title>
<link>http://blah.thingsinjars.com/post/262/synchronised-podcasts/</link>
<guid>http://blah.thingsinjars.com/post/262/synchronised-podcasts/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-262">
    				<div><p>This must exist somewhere. I just can't find it.</p>
<p>I listen to a lot of podcasts in a week and I use quite a few different computers. One desktop at home, one laptop while out and about and a PC and an iMac at work. I want some service (or combination of web service and application) that I can use to manage my podcast subscriptions regarless of where I am.</p>
<p>At the moment, I have iTunes installed on my desktop, my laptop and the iMac at work and I have subscribed to my collection of podcasts in each of them. I want to be able to plug in my iPod and have it delete the podcasts I've listened to and get the latest episodes of each of my subscriptions. At the moment, I plug it into the desktop, copy on the latest 'Planet Money' and listen. A couple of days later, there's another episode released so I plug into my laptop and it offers the episode I've just finished listening to and the new one. A few days later, I'm working on the office iMac and plug in my iPod, it suggests the last weeks-worth of episodes. I have to manually go into every subscription and drag over the individual files that I want to listen to.</p>
<aside>
<p>This is, of course, ignoring my usual niggle about iTunes which is its insistence on pausing downloads with the message "iTunes has stopped updating this podcast because you have not listened to any episodes recently". No, keep downloading, iTunes. I didn't tell you to stop.</p>
</aside>
<p>What I'd like to have is a web site where I can put in my podcast subscriptions and it will track the latest episodes of each. I can then either point iTunes to this site so that I can point all my installations at it or it will provide an application which can be used to put the latest episodes onto my iPod. When I plug in my iPod, the application tells the site which ones I've listened to and it removes them from my listening queue. The application could, also be stored on the iPod itself to enable it to be used wherever the iPod is plugged in, not just on computers with iTunes.</p>
<p>Am I explaining myself clearly enough? It just seems so simple, it should already exists within iTunes. It is entirely possible that Apple's recent acquisition of <a href="http://lala.com">Lala</a> could be the first step in an online iTunes which would solve these problems. If anyone has any suggestions for the best way to achieve this, please let me know. I thought of a way of doing it with <a href="http://dropbox.com">Dropbox</a> but it would only work if the music bit of my iTunes library weren't bigger than my Dropbox account.</p></div>    			</div>
    ]]></description>
<pubDate>Fri, 26 Feb 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Still Life Under Ice</title>
<link>http://blah.thingsinjars.com/post/261/still-life-under-ice/</link>
<guid>http://blah.thingsinjars.com/post/261/still-life-under-ice/</guid>
<description><![CDATA[
      			<div class="teaser flickr" id="teaser-261">
    				<div><p><a href="http://farm3.static.flickr.com/2528/4053678593_65aacdba4a.jpg"  rel="lightbox[{smod:id}]"  title="Still Life Under Ice"><img src="http://farm3.static.flickr.com/2528/4053678593_65aacdba4a_m.jpg" alt="Still Life Under Ice"/></a>I like the textures in this one but I might prefer it black & white. Hmmm.. undecided.</p>
<p>Originally uploaded by <a href="http://www.flickr.com/photos/thingsinjars/4053678593/">thingsinjars</a> on <a href="http://www.flickr.com">flickr</a></p></div>    			</div>
    ]]></description>
<pubDate>Tue, 26 Jan 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Appreciate the artisans</title>
<link>http://blah.thingsinjars.com/post/259/appreciate-the-artisans/</link>
<guid>http://blah.thingsinjars.com/post/259/appreciate-the-artisans/</guid>
<description><![CDATA[
      			<div class="teaser " id="teaser-259">
    				<div>I know that every professional thinks their bit of the process is more important than people give them credit for. Designer's don't just colour in wireframes handed to them by the Information Architect. IAs don't just draw boxes and arrows. Copy writers don't just copy-and-paste the company brochure over the lorem ipsum.

Now that I've said that, I must now point out: Developers don't get nearly enough credit.

This may be something to do with the odd confusion that is 'web designer vs. web developer'. In some - and possibly the majority of - agencies, the web <em>designer</em> not only designs what the page looks like in Photoshop/Fireworks/Whatever but also produces the HTML templates, CSS and whatever JavaScript they feel comfortable with (the tutorials at <a href="http://jqueryfordesigners.com/">jQuery for Designers</a> probably help, too). In these agencies, if there is such a person as a web <em>developer</em>, they are most likely responsible for moving the relevant bits of HTML into template files, adding in any back-end integration and possibly writing some of the trickier JavaScript. The confusion arises in the other kind of agencies. The kind where web <em>designers</em> make Photoshop files and web <em>developers</em> turn them into HTML. The designer doesn't necessarily need to know anything about HTML, semantics or scripting. Not to minimise the importance of this kind of designer - they'll know a lot about typography, and visual relations, probably quite a lot about user experience and the process involved in bridging the gap between what the client wants to say and how the user wants to hear - but it's this kind of web developer I think doesn't get enough credit. 

If you're designing a site with a full knowledge of how it could be marked up, you will naturally - even if it's subconsciously - be marking it up in your head. This will influence your design and not necessarily in a bad way. You might ensure the semantics are just that little bit clearer or you might nudge these bits over that way so they can be grouped with those other ones there. If, however, you design with no thought at all about how this is going to be made, you will, most likely, do some things that you wouldn't otherwise. If your front-end developer can take this and turn it into a perfectly semantic, clean-coded masterpiece of HTML and CSS then apply JavaScript to progressively enhance the heck out of it and still keep it looking like you designed, they deserve to be lauded, applauded, praised and thanked. Publicly. The usual outcome of this situation is that the designer gets asked along to the awards ceremonies, puts it on their portfolio, an article in <a href="http://www.thedrum.co.uk/">the Drum</a>, happy. The developer gets a pat on the back from the team leader and asked if they could just tidy up how it looks in IE5.5 before they head home for the night, that'd be great, thanks.

Sure, maybe we just need some better awards ceremonies for geeks. The kind of thing that the agency sales team will be able to brag about to potential customers (as that, in essence, seems to be the point of awards ceremonies) but I also think there might need to be a bit of a change of opinion in the industry. Just as designers don't just colour in wireframes, developers don't just open the designs in Photoshop and press 'Save for web...'.

I hope this doesn't sound too ranty. These thoughts were prompted after seeing a few designer and copy writer portfolios which contained sites that either I'd built or one of my team had built. Writers credited, designers credited, developers (who built some awesome stuff on them, by the way) lost in the mists of time.</div>    			</div>
    ]]></description>
<pubDate>Mon, 25 Jan 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Heidi</title>
<link>http://blah.thingsinjars.com/post/258/heidi/</link>
<guid>http://blah.thingsinjars.com/post/258/heidi/</guid>
<description><![CDATA[
  			<div class="teaser audio" id="teaser-258">
							</div>
]]></description>
<pubDate>Fri, 22 Jan 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>User style</title>
<link>http://blah.thingsinjars.com/post/256/user-style/</link>
<guid>http://blah.thingsinjars.com/post/256/user-style/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-256">
    				<div><p>A few years ago, I made a prediction about the way the web was going and so far it hasn't come true but it's definitely coming closer. To me it seems that the logical extension of us developers separating style and substance &ndash; what we've been doing for years with semantic mark-up &ndash; is for the general consumer to take that substance and give it their own style. I'm in no way suggesting that everyone become a designer. That would be a terrible, terrible thing. What I mean is that the consumer takes in/reads/experiences whatever it is you're giving to them in the manner that best suits them. There are many examples of what I mean around already but they're still not quite where I think they will end up.</p>

<h2>RSS</h2>
<p>We (web developers) already provide RSS feeds on our sites. By subscribing to a site's RSS feed, you get the content delivered directly to your RSS reader. As long as the site is providing the full article content (shame on you, if not) the consumer gets to see your content in a design format you have little control over. There is a basic level allowed for RSS formatting but nothing you can rely on. The control for the visual appearance of your content is now in the hands of the designer of the reader and the consumer (by way of choosing which reader they use).</p>

<h2>userstyle.css</h2>
<p>This was what initially prompted my thoughts on the subject. I've used Opera as my main browser for almost 10 years and I've always liked the Author mode/User mode switch. In essence, you can quickly toggle between seeing a web page as it was intended by the designer or disregarding the original layout and applying your own stylesheets to it. For the most part, this is used to be able to set high contrast for visually impaired users or to test various criteria (showing only images that have missing alt attributes, for example) but they can be used to produce any visual effect achievable with CSS.</p>

<p>User stylesheets can also be assigned on a per-site basis rather than globally which means that you could have your Google results rendered in courier, right-aligned in green on black while your facebook pages can be set in Times in a sepia colourscheme.</p>

<p>As with many things on the web, userstyles became a lot more popular once this functionality was available in Firefox (via the add-on <a href="https://addons.mozilla.org/en-US/firefox/addon/2108">Stylish</a>) and not just Opera. Now there's a growing <a href="http://userstyles.org/">community of Userstyle developers</a> and a <a href="http://userstyles.org/styles/browse?sort=popularity&sort_direction=desc">directory of styles</a>. Unfortunately, this is still not quite ready for mainstream use. It requires at least a basic level of technical ability to enable userstyles and to install them.</p>

<h2>userscript.js</h2>
<p>The userstyles community is, however, dwarfed in comparison to the userscript community. In pretty much exactly the same way that userstyles work, users can execute a specific Javascript file whenever they visit a site. Again, this can be enabled in Opera using site preferences and in Firefox using the <a href="https://addons.mozilla.org/en-US/firefox/addon/748">Greasemonkey add-on</a>. These scripts can completely change the way a site functions as well as how it looks. Combine them with userstyles (which userscripts can include automatically) and the only thing you can rely on remaining from your original design is the URL. There's a <a href="http://userscripts.org/">massive database of userscripts</a> available.</p>

<p>Again, though, these are still just that <em>little bit too hard</em>. The standard user isn't going to install the extension, isn't going to browse for scripts and isn't going to run Opera so these are still a bit too far away.</p>

<h2>Grab now, read later</h2>
<p>There are now quite a few sites where you can save stuff to read later. If you find an interesting article or a funny blog post but don't have time to read it or if it appears on a site with a garish and unusable design, you can send it to <a href="http://www.instapaper.com/">Instapaper</a> or <a href="http://www.evernote.com/">Evernote </a>. You can then read it in their interface, on your iPhone, on your Kindle... all separated from your design.</p>

<p>It's not only text that gets this treatment, you can use <a href="http://emberapp.com/">Ember</a> and <a href="http://www.realmacsoftware.com/littlesnapper/">LittleSnapper</a> to grab and store visuals for later perusal or use <a href="http://huffduffer.com/">Huffduffer</a> to collect any audio files you find and serve them back to you as your very own personalised podcast. Again, this is <em>your</em> content separated entirely from the way you wanted it seen. And that's a good thing.</p>

<p>For content creators, all this means is that your content can be consumed anywhere, even via sites, tools and delivery mechnisms you've never heard of. Designers, don't despair, users aren't suddenly going to take their content elsewhere and not need you any more &ndash; users still want and <em>need</em> things designed well, this just means that if your design works for the user for a particular type of content, they'll use it for any content of that type. I'd much rather watch youtube videos using vimeo's layout than youtube's. Actually, I'd much rather have vimeo's comments, too.</p>

<p>We're still quite a way off the average user being able to see whatever they want however they want it but these technologies and tools are definitely heading that way. I just wish I'd made a bet on it way back when.</p></div>    			</div>
    ]]></description>
<pubDate>Fri, 15 Jan 2010 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Crowdsourced Weather - Part 2</title>
<link>http://blah.thingsinjars.com/post/255/crowdsourced-weather---part-2/</link>
<guid>http://blah.thingsinjars.com/post/255/crowdsourced-weather---part-2/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-255">
    				<div><p>So, I couldn't help myself. I had a niggling idea at the back of my head that I needed to get out. After coming up with this <a href="http://blah.thingsinjars.com/post/254/crowdsourced-weather/">Twitter weather</a> idea last week, I decided to spend a couple of hours this weekend building it. As if I didn't have other things I should have been doing instead...</p>

<p>It works pretty much exactly how the pseudocode I mentioned last time describes. Every few minutes, a script will search Twitter for mentions of any weather words from several different languages. It will then look up the location of the person who tweeted that and store it. Single reports might be wrong and users might not have stored their actual location but over a large enough sample, this system becomes more accurate. The script removes any matching twets older than 6 hours.</p>

<p>To display, I actually ended up using <a href="http://en.wikipedia.org/wiki/Geohash">Geohashes</a> instead of <a href="http://www.geotude.com/">Geotudes</a> because it is easier to simplify them when you zoom out just by cutting off the tail of the hash. For example, the physical area denoted by gcvwr3qvmh8vn (the geohash for Edinburgh) is contained within gcvwr3 which is itself contained within gcv. There are a few <a href="http://en.wikipedia.org/wiki/Geohash#Limitations">technical problems with geohashes</a> but it seems the best fit for this purpose. If anyone knows of any better suggestion, please let  me know. I do realise that this is quite possibly the slowest, most inefficient JavaScript I've ever written because it makes an <acronym title="Asynchronous JavaScript And XML">AJAX</acronym> call for every <a href="http://wiki.xkcd.com/geohashing/Graticule">graticule</a> and it probably should just send the South-East and North-West bounds and get back an array of them but, like I said, there were other things I should have been doing. Because the overlaid grid changes resolution based on zoom level, there are a few places where it is either tragically slow (resolution too fine) or terribly inaccurate (resolution too rough). That's just a case of tweaking the algorithm. Similarly, it's set to display reports of weather if there are 2 or more matches but it could be tweaked to only show if a larger number have reported something.</p>

<p>So go, play with the <a href="http://blah.thingsinjars.com/widgets/weather/index.html">Twitter-generated weather map</a>. If someone can come up with a good, catchy name, or some better graphics, that'd be great, thanks.</p>

<aside>
<p>Source code is available: <a href="/uploaded/other/twitter-weather-1.0.zip">twitter-weather-1.0.zip [Zip - 298KB]</a>.</p>
<p>You'll need your own Twitter login and database account to use it.</p>
</aside></div>    			</div>
    ]]></description>
<pubDate>Mon, 21 Dec 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Crowdsourced Weather</title>
<link>http://blah.thingsinjars.com/post/254/crowdsourced-weather/</link>
<guid>http://blah.thingsinjars.com/post/254/crowdsourced-weather/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-254">
    				<div><p>This is a more general version of the <a href="http://uksnow.benmarsh.co.uk/">#uksnow map</a> idea. It's a crowd-sourced weather map which relies on the fact that any one individual tweet about the weather might be inaccurate but given a large enough sample, enough people will mention the weather in their area to make this a workable idea. It doesn't require people to tweet in a particular format.</p>

<h2>To get info</h2>

<pre>
Have an array of weather words in various languages (rain, hail, snow, schnee, ame, yuki)
every 5 minutes:
	foreach weatherword
		search twitter for that word
			http://search.twitter.com/search.atom?q=rain
		retrieve latest 100 tweets
		foreach
			get user info
				http://twitter.com/users/show.xml?screen_name=username
			get user.location if available
			geocode
			save:
				username, time, lat, long, <a href="http://www.geotude.com/">geotude</a>, weatherword
		Remove any tweets about this weatherword older than 6 hours.
			
</pre>

<h2>To display info</h2>
<pre>
Show a Google map
Based on current Zoom level, split the current map into about 100 geotudes
foreach geotude
	search database for any weather results for that block (probably using an ilike "1234%" on the geotude field)
	sort by weatherword count descending
	draw an icon on top of that block to show the most common weatherword
	
If the user zooms in, recalculate geotudes and repeat.
</pre>

<p>I quite like that this uses <a href="http://www.geotude.com/">geotudes</a> which I think are an excellent idea.</p>
<aside>
<p>I built a <a href="http://blah.thingsinjars.com/widgets/weather/">very basic version of this</a>. Read more about it in <a href="http://blah.thingsinjars.com/post/255/crowdsourced-weather---part-2/">Part 2</a>.</p>
</aside></div>    			</div>
    ]]></description>
<pubDate>Thu, 17 Dec 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>What's your Google Suggest number?</title>
<link>http://blah.thingsinjars.com/post/253/whats-your-google-suggest-number/</link>
<guid>http://blah.thingsinjars.com/post/253/whats-your-google-suggest-number/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-253">
    				<div><ul class="gallery">
<li><a href="/uploaded/images/expanded/google-suggest.jpg" rel="lightbox[253]" title="What's your Google Suggest number?"><img src="/uploaded/images/thumbs/google-suggest.jpg" alt="What's your Google Suggest number?" /></a></li>
</ul>
<p>The next step in ego-googling: how many letters of your name do you need to type into the google search box before you are the top suggestion? The lower the better, obviously. Including spaces, My name is the top suggestion after 10 characters so I have a Google Suggest Number of 10. My <a href="http://www.flickr.com/photos/photojennic/" title="Flickr: photojennic's Photostream">darling wife</a> (who has recently changed her name) has a Google Suggest number of &infin; as she can type in her whole name and Google doesn't suggest her.</p>

<p>Turns out <a href="http://www.jerrykindall.com/2004/12/10_google_suggest_number.asp">somebody proposed this</a> first over 5 years ago. Oh well. Nothing's new on the internet.</p></div>    			</div>
    ]]></description>
<pubDate>Mon, 14 Dec 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Side Tab</title>
<link>http://blah.thingsinjars.com/post/252/side-tab/</link>
<guid>http://blah.thingsinjars.com/post/252/side-tab/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-252">
    				<div><ul class="gallery"><li><a href="http://blah.thingsinjars.com/uploaded/images/expanded/side-tab.jpg" title="Opera with Tabs down the side" rel="lightbox[252]"><img src="http://blah.thingsinjars.com/uploaded/images/thumbs/side-tab.jpg" alt="thumb of my Opera layout"/></a></li></ul>
<p>After reading Aza Raskin's post about Firefox moving its tabs <a href="http://www.azarask.in/blog/post/firefoxnext-tabs-on-the-side/">down the side</a> of the window, I decided to give it a go in Opera. It turns out to be very useful when you have a widescreen monitor. I usually end up with several dozen tabs open at once and it's much easier to be able to put them down the side in an area which is, for most websites at least, dead space. On the rare occasions I do find myself on a website which requires more than the 1470px horizontal space this gives me, I can just tap f4 and get my full 1650px back. As the window sidepanel also groups by window and lists all tabs open across all windows, I can keep them ordered thematically, too.</p>
<p>This arrangement definitely doesn't work, however, when you have a small screen. When I tried this on my netbook, I had to choose between losing half of my screen to the tab list or only being able to read the beginning of each page title, even if I only had one tab open.</p>
<aside><p>A quick aside, when I first read about moving tabs down the side, my initial thought was "It's a shame Opera doesn't have add-ons, I'd like to give this a go" and very nearly fired up Firefox before I realised that Opera already has this functionality and has had since (approximately) version 5 (almost 10 years ago). Just sayin'.</p></aside></div>    			</div>
    ]]></description>
<pubDate>Thu, 10 Dec 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Some simple tips</title>
<link>http://blah.thingsinjars.com/post/251/some-simple-tips/</link>
<guid>http://blah.thingsinjars.com/post/251/some-simple-tips/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-251">
    				<div><p><em>The views and opinions expressed within are not those of National Museums Scotland. This site is in no way affiliated with National Museums Scotland or the website <a href="http://www.nms.ac.uk/">www.nms.ac.uk</a></em></p>
<p>First of all, the disclaimer: I am not a designer. If I were to make claim to being anything creative it's an <a href="http://permanentpencil.com">illustrator</a> but there's a huge difference between the two (I've always said that an illustrator makes the thing to go on the t-shirt, the designer says <em>where</em> on the t-shirt it goes). Despite the recent trend for everyone to call themselves web designers, I'm still going to go by web developer. I make things.</p>
<p>Bearing that in mind, there are still quite a few web design and <acronym title="User Experience">UX</acronym> tips and techniques I've picked up along the way which can be applied to most sites and not interfere with the mysterious ways of designers.</p>
<p>Recently, I've been reworking templates for <a href="http://www.nms.ac.uk/">National Museums Scotland</a> for faster load times and better <acronym title="Search Engine Optimisation">SEO</acronym> and I'll illustrate what I'm talking about with a couple of examples from there. The brief on these templates is that the content can't really change and there are some chunks that the <acronym title="Content Management System">CMS</acronym> generates which can't be changed. Note: the <acronym title="National Museums Scotland">NMS</acronym> templates are completely finished yet and those that are haven't been rolled out across the whole site but sticking with that whole <a href="http://en.wikipedia.org/wiki/Release_early,_release_often">release early, release often</a> way of doing things, these little incremental improvements can be applied without affecting too much else.</p>

<p>For reference, here are before and after screen grabs of two of the templates.</p>
<ul class="gallery">
<li><a href="/uploaded/images/tips-our-before.jpg" rel="lightbox[1]" title="Main Gateway before"><img src="/uploaded/images/thumbs/tips-our-before.jpg" alt="Our Museums Before"/></a></li>
<li><a href="/uploaded/images/tips-our-after.jpg" rel="lightbox[1]" title="Main Gateway after"><img src="/uploaded/images/thumbs/tips-our-after.jpg" alt="Our Museums After"/></a></li>
<li><a href="/uploaded/images/tips-war-before.jpg" rel="lightbox[1]" title="Museum page before"><img src="/uploaded/images/thumbs/tips-war-before.jpg" alt="Museum gateway before"/></a></li>
<li><a href="/uploaded/images/tips-war-after.jpg" rel="lightbox[1]" title="Museum page after"><img src="/uploaded/images/thumbs/tips-war-after.jpg" alt="Museum gateway after"/></a></li>
</ul>

<p>Some people will find these tips blatantly obvious but the fact that pages still get made without considering these means they do need reiterating.</p>

<h2>Link the Logo</h2>
<p>The web's been around for a few years now and there are a few conventions users have gotten used to. One of them is that the logo is a link that takes you back to the home page. It doesn't harm anything to have a link there so even if 99% of visitors don't use it, why annoy the 1% who do?</p>

<h2>Don't link to the search</h2>
<p>From the moment the visitor decides they want to search your site for something, the most important thing is to get the results in front of them as quickly as possible. It therefore makes for a better experience if you bring the results one step closer to them. Rather than requiring the user to click on a link to get to the search form to do their search to get the results, put the search box on every page. They fill it in and go to the results page. If the user wants to take advantage of any advanced search features you may have, they can modify their search from the results page.</p>
<p><img src="/uploaded/images/tips-search.jpg" alt="Search box positioned within header"/></p>
<aside>
  <p>Note: the new template still contains a link to the search page due to some legacy requirements. I don't actually recommend this.</p>
</aside>

<h2>Line up</h2>
<ul class="gallery">
  <li><a href="/uploaded/images/tips-line-a.gif" rel="lightbox[2]" title="Higglty.."><img src="/uploaded/images/thumbs/tips-line-a.gif" alt="thumbnail of layout not aligned"/></a></li>
  <li><a href="/uploaded/images/tips-line-b.gif" rel="lightbox[2]" title="...and straight"><img src="/uploaded/images/thumbs/tips-line-b.gif" alt="thumbnail of layout aligned"/></a></li>
</ul>
<p>I'm sure there's more to design than this but there are a couple of well tested rules I recommend any non-designer to learn:</p>
<blockquote>
<ol>
       <li>If it doesn't line up, make it line up.</li>
       <li>If it's already lined up, make it not.</li>
</ol>
</blockquote>
<p>That and a subscription to iStock and you're done...</p>
<aside>
  <p>Note: This was a joke, real designers please don't stab me with your crayons.</p>
</aside>

<h2>Make the hit area as big as possible</h2>
<ul class="gallery">
  <li><a href="/uploaded/images/tips-hit-a.jpg" rel="lightbox[3]" title="Before and after close-up"><img src="/uploaded/images/thumbs/tips-hit-a.jpg" alt="Thumbnail of gateway panel comparison" /></a></li>
  <li><a href="/uploaded/images/tips-hit-b.jpg" rel="lightbox[3]" title="Blue bits are clickable"><img src="/uploaded/images/thumbs/tips-hit-b.jpg" alt="Thumbnail of gateway panel hit area comparison" /></a></li>
</ul>
<p>From the gateway page for <a href="http://www.nms.ac.uk/our_museums.aspx">Our Museums</a>, there are two ways the user could go. They were either looking for opening times (in which case, they're done), or they want to find out more information about the individual museums on their own pages. To that end, it makes sense to make the next step as easy as possible and bascially turn the content this page into six huge buttons. To keep everything semantic, JavaScript has been used here to extract the destinations from each of the links and apply them to the whole panel area (it'll default to linked text and image with JavaScript disabled). As you can see, doing this changes the hit area for each museum from a line of text to a veritable barn door.</p>

<h2>White text on a white background is not good</h2>
<ul class="gallery">
  <li><img src="/uploaded/images/thumbs/tips-white-a.jpg" alt="white text laid over white background"/></li>
  <li><img src="/uploaded/images/thumbs/tips-white-b.jpg" alt="white text laid over black background"/></li>
</ul>
<p>Actually, I'm not sure whether it's the fact that the link wasn't as readable as it could have been or the fact that to go home requires poking her in the eye that upset me most. Either way, if you do need to use an image that has a light bit underneath some light text and you can't shuffle it along like here, a quick wipe with the burn tool in Photoshop works wonders.</p>

<h2>Underline links</h2>
<p>I'm not going to get into the debate over whether or not <a href="http://www.gerrymcgovern.com/nt/2009/nt-2009-11-02-Web-links-actio n.htm">designers hate underlines</a> but for a high-traffic, public sector with an extremely varied demographic, I'd recommend using them. As <a href="http://boagworld.com/podcast/191">Paul Boag</a> mentions, what you do with your design and your solutions for various usability issues depends on the audience. A graphic designer's portfolio might very well eschew underlines when denoting links, a government site probably shouldn't. Especially when you remember that you should <a href="http://www.webaim.org/standards/508/checklist">never rely on colour alone to convey information</a>, including whether not a piece of text is a link.</p>

<h2>Titles are titles of something</h2>
<ul class="gallery">
  <li><img src="/uploaded/images/tips-related-a.gif" alt="titles far away from paragraph text"/></li>
  <li><img src="/uploaded/images/tips-related-b.gif" alt="titles near paragraph text"/></li>
</ul>
<p>If you have a title, it generally refers to the thing below it, not the thing above it. Make sure you keep titles and the things they are titles of together.</p>

<h2>Avoid disparate navigation</h2>
<ul class="gallery">
  <li><a href="/uploaded/images/tips-nav-a.gif" rel="lightbox[4]" title="Several different navigations"><img src="/uploaded/images/thumbs/tips-nav-a.gif" alt="navigation split over two areas"/></a></li>
  <li><a href="/uploaded/images/tips-nav-b.gif" rel="lightbox[4]" title="Slightly combined"><img src="/uploaded/images/thumbs/tips-nav-b.gif" alt="navigation combined into one area"/></a></li>
</ul>
<p>Again, another of the rules of web that has evolved over the last several years: Sections go along the top, navigation down the side. To keep consistent with the rest of the site the horizontal museum links were brought down and integrated with the rest of the navigation. This maybe isn't the most illustrative example but, basically, don't have a top nav, left nav, right nav and several others when you could have just one.</p>

<h2>Only a fraction</h2>
<p>There we are, a few handy little tips for your next build project. This hasn't gone into any issues of column width, line-height - or <a href="http://en.wikipedia.org/wiki/Leading">leading</a> (pronounced /ˈlɛdɪŋ/) as designers call it, hover states or any of the myriad other things it could, just a few of the more important and easy-to-do ones.</p></div>    			</div>
    ]]></description>
<pubDate>Mon, 07 Dec 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Building an Objective-C growlView</title>
<link>http://blah.thingsinjars.com/post/250/building-an-objective-c-growlview/</link>
<guid>http://blah.thingsinjars.com/post/250/building-an-objective-c-growlview/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-250">
    				<div><p><em>Wherein our intrepid hero learns some Objective-C and figures out the easy bits are actually quite hard.</em></p>

<aside>

  <p>This is a little guide on how to write a growl plugin to automatically send notifications as tweets. If you just want the finished thing: <a href="http://cloud.github.com/downloads/thingsinjars/GrowlBird/GrowlBird_0.2.8.zip">GrowlBird.zip [Zip - 228KB]</a></p></aside>

<p>A couple of days ago, I decided to give myself a little software development task to write a <a href="http://twitter.com">Twitter</a> <a href="http://growl.info">Growl</a> view. Growl is a centralised notification system for Mac OS X that lots of other applications can use so that there's one consistent way of showing notifications. </p>

<h2>Background</h2>

<p>The idea behind this little experiment wasn't to have tweets appear as growl notifications, there are already plenty of apps that do this, the idea was to have growl notifications sent to Twitter. Some friends have started organising a crowdsourced <a href="http://rotacoo.com/fridaymix/">Friday afternoon playlist</a> via <a href="http://spotify.com">Spotify</a> and I thought it'd be handy if Spotify tweeted each song as it started. The easiest way I could think of doing this was to tap into the fact that Spotify sends a Growl notification on track start and get the Growl display plugin to tweet it as well <sup>[<a href="#note-already">1</a>]</sup>. </p>

<h2>Build</h2>

<p>I downloaded the <a href="http://growl.info/files/DisplaySample.zip">Growl Display Plugin Sample 1.2 [Zip - 186 KB]</a> from the <a href="http://growl.info/downloads_developers.php">developer downloads</a> page and the <a href="http://mattgemmell.com/2008/02/22/mgtwitterengine-twitter-from-cocoa">MGTwitterEngine</a> library. I then downloaded <a href="http://developer.apple.com/technology/xcode.html">Xcode</a> so I could do the development. I have to point out here that this was my first foray into Objective-C programming and, indeed, my first attempt at anything vaguely C-related since I wrote a command-line calculator about 12 years ago. If I do it wrong, please forgive me.</p>

<p>The first thing to do was open the sample project in Xcode, figure out what files do what, etc. There is very little documentation on how Growl views or display styles work so I pretty much just spend an hour reading all the source from top to bottom. Here's a quick summary:</p>

<dl>

  <dt>Sample_Prefix.pch</dt><dd>Pre-compiled header. Stuff that's included before every pre-compiled file</dd><dt>Growl/</dt><dd>Folder containing standard Growl stuff. Don't need to touch.</dd><dt>GrowlSampleDisplay.h</dt><dd>Header file, didn't need to change anything</dd><dt>GrowlSampleDisplay.m</dt><dd>Class for setting up things. Again, didn't touch <sup>[<a href="#note-bugged">2</a>]</sup>.</dd><dt>GrowlSamplePrefs.h</dt><dd>Defining default preference values and naming functions to handle them. More on this later.</dd><dt>GrowlSamplePrefs.m</dt><dd>The actual functions mentioned in the previous header file</dd><dt>GrowlSampleWindowController.h</dt><dd>Not doing anything visual, really so I didn't need to mess around with this</dd><dt>GrowlSampleWindowController.m</dt><dd>As above</dd><dt>GrowlSampleWindowView.h</dt><dd>Declaring objects needed for execution</dd><dt>GrowlSampleWindowView.m</dt><dd>Instantiating the objects then actually using them later on.</dd></dl>



<p>Again, I'm not used to doing this stuff so if I'm using the wrong terminology, just pretend I'm not.</p>



<p>I then dragged the MGTwitterEngine library into the project drawer, saved and built. At this point it successfully did nothing different which is what I was hoping it would do. Well, it popped up the 'This is a Preview of the Sample Display' message using the MusicVideo style which is what it does when you don't screw with it.</p>



<aside>

  <h2>Testing growlView</h2>

  <p>It's not actually that easy to test growlView plugins. You can't simply add and remove them. To install, you double-click on it. You should be able to see it listed in the Display tab of the preference pane. To <em>re-install</em>, you need to delete ~/Library/Preferences/com.Growl.GrowlHelperApp, ~/Library/Application Support/Growl/Plugins/Sample.growlView and restart growl (click on the paw in the menu bar). It's a bit of a hassle.</p>

</aside>

<p>The next thing was to include the MGTwitterEngine. In GrowlSampleWindowController.h, #import "MGTwitterEngine.h" and create a new object. I just followed the instructions in the <a href="http://svn.cocoasourcecode.com/MGTwitterEngine/README.txt">README</a> but be sure to follow <em>all</em> of them. If you get errors about LibXML not being installed or YAJL not working, don't worry, you just need to make sure you set USE_LIBXML to 0 in all the places you're supposed to. GrowlSampleWindowController.h now contains this:</p>

<code>

#import "GrowlDisplayWindowController.h"<br />

#import "MGTwitterEngine.h"<br />

<br />

@class GrowlBirdWindowView;<br />

<br />

@interface GrowlBirdWindowController : GrowlDisplayWindowController {<br />

	CGFloat						frameHeight;<br />

	NSInteger					priority;<br />

	NSPoint						frameOrigin;<br />

	MGTwitterEngine *twitterEngine;<br />

}<br />

	<br />

@end<br />

</code>

<p>In GrowlSampleWindowController.m, I then instantiated the new object:</p>

<code>

  @implementation GrowlBirdWindowController<br />

<br />

  - (id) init {<br />

  	  :<br />

  	  :<br />

      twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];<br />

	    [twitterEngine setUsername:@"growlbirdtest" password:@"testgrowlbird"];<br />

	  }<br />

	  :<br />

</code>

<p>And then modified the setNotification function to also send an update:</p>

<code>

- (void) setNotification: (GrowlApplicationNotification *) theNotification {<br />

    :<br />

	[view setTitle:title];<br />

	[view setText:text];<br />

  NSLog(@"sendUpdate: connectionIdentifier = %@", [twitterEngine sendUpdate:[NSString stringWithFormat:@"%@, %@", title, text]]); // The new line<br />

  :<br />

  }<br />

</code>

<p>That was enough to get growl to send messages to appear on http://twitter.com/growlbirdtest but it doesn't make it that useful for anybody else, to be honest. The next thing to figure out was the preferences. </p>

<h2>Preferences</h2>

<p>Without documentation, this took a bit longer that I expected. To start off changing the english version before worrying about localization, find the GrowlBirdPrefs.xib in resources/en.lproj/ and open it. Interface Builder will launch then you can double-click on 'Window' and see the layout of the preference pane. Search in the Library for 'text' and drag a text field into the window then spend about half and hour clicking round the interface. Open up the various inspectors (right-click on an object), look through the different tabs, click between the newly added text field and the sliders and drop-downs that are already there just to see what's different. Once I was a bit familiar, I opened the connections tab so that I could bind the value of the text field to the value 'twitterUsername' in my code. I checked 'value', Bind to 'File's Owner' and entered 'twitterUsername' in Model Key Path. I then repeated this for twitterPassword using a Secure Text Field from the Library. The option nextKeyView is used to say which item is tabbed to next when you're navigating with the keyboard so to keep things tidy, I dragged lines from nextKeyView from each of them to the right places in the layout.</p>

<p>Back in the code, I added new default preferences in GrowlSamplePrefs.h:</p>

<code>

  #define Sample_USERNAME_PREF		@"Username"<br />

  #define Sample_DEFAULT_USERNAME		@"growlbirdtest"<br />

<br />

  #define Sample_PASSWORD_PREF		@"Password"<br />

  #define Sample_DEFAULT_PASSWORD		@"testgrowlbird"<br />

  :<br />

  :<br />

  @interface GrowlBirdPrefs : NSPreferencePane {<br />

  	IBOutlet NSSlider *slider_opacity;<br />

  	IBOutlet NSString *twitterUsername;<br />

  	IBOutlet NSString *twitterPassword;<br />

  }<br />

</code>

<p>and named some handlers for them:</p>

<code>

  - (NSString *) twitterUsername;<br />

  - (void) setTwitterUsername:(NSString *)value;<br />

  - (NSString *) twitterPassword;<br />

  - (void) setTwitterPassword:(NSString *)value;<br />

</code>



<p>Be careful here, I got confused and didn't have the same spelling here for twitterUsername and twitterPassword as I had put in the interface builder as I hadn't realised the two were directly connected. They are. Obviously. The next thing to do is to write the code for these handlers:</p>

<code>

  - (NSString *) twitterUsername {<br />

  	NSString *value = nil;<br />

  	READ_GROWL_PREF_VALUE(Sample_USERNAME_PREF, SamplePrefDomain, NSString *, &value);<br />

  	return value;<br />

  }<br />

  - (void) setTwitterUsername:(NSString *)value {<br />

  	WRITE_GROWL_PREF_VALUE(Sample_USERNAME_PREF, value, SamplePrefDomain);<br />

  	UPDATE_GROWL_PREFS();<br />

  }<br />

  - (NSString *) twitterPassword {<br />

  	NSString *value = nil;<br />

  	READ_GROWL_PREF_VALUE(Sample_PASSWORD_PREF, SamplePrefDomain, NSString *, &value);<br />

  	return value;<br />

  }<br />

  - (void) setTwitterPassword:(NSString *)value {<br />

  	WRITE_GROWL_PREF_VALUE(Sample_PASSWORD_PREF, value, SamplePrefDomain);<br />

  	UPDATE_GROWL_PREFS();<br />

  }<br />

</code>



<p>Build and reinstall and this will now show the same preference pane as before but with two new text fields which allow you to enter your username and password. In fact, build at several stages along the way. Every time you make a change, in fact. If something breaks, check the error log to see if it's something predictable that should have broken at that point or if you've done something wrong. Also, keep the OS X log app Console open in the background. It will spew out error messages if you do something wrong. It's also good to have your code write out console messages to keep a track on what your code is doing like so:</p>

<code>

  - (NSString *) twitterPassword {<br />

  	NSString *value = nil;<br />

  	READ_GROWL_PREF_VALUE(Bird_PASSWORD_PREF, SamplePrefDomain, NSString *, &value);<br />

  	NSLog(@"twitterPassword = %@", value);<br />

  	return value;<br />

  }<br />

</code>



<p>You'll notice we're still sending messages to the growlbirdtest account because, even though we are reading and saving the username and password, we're not doing anything with them. That's easily remedied by editing GrowlSampleWindowView.m again and replacing the hard-coded login details with a couple of lines to read from the preferences or fall back on the default:</p>

<code>

  twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];<br />

	NSString *twitter_username = Bird_DEFAULT_USERNAME;<br />

	NSString *twitter_password = Bird_DEFAULT_PASSWORD;<br />

	READ_GROWL_PREF_VALUE(Bird_USERNAME_PREF, SamplePrefDomain, NSString *, &twitter_username);<br />

	READ_GROWL_PREF_VALUE(Bird_PASSWORD_PREF, SamplePrefDomain, NSString *, &twitter_password);<br />

	[twitterEngine setUsername:twitter_username password:twitter_password];<br />

	NSLog(@"Twitter Login: username = %@", twitter_username);<br />

</code>

<p>And, hooray! It works and posts to the account for which you entered details. Sort of. Some apps double-post. I haven't figured out why yet.</p>

<h2>Renaming</h2>

<p>After all that, the final bit (which I thought would be the easiest) was to rename the growlView from 'Sample' to 'Bird'. I have read that in the latest version of Xcode (which presumably comes with Snow Leopard), there's a global 'Rename' which will do all the relevant stuff for you. If you don't have that, you'll need to read <a href="http://arustisha.wordpress.com/2009/03/08/on-the-renaming-of-xcode-projects/">'On the Renaming of Xcode Projects'</a> and do everything there. If you're still finding your growlView is called Sample, manually open every Info.plist you can find, 'Get Info' on everything, scour through the settings for the different build environments (Debug and Release)... It took longer to rename the project than to actually build it.</p>



<aside>

<p>A trivial aside, I have also added two fields to the preferences for tweet prefix and tweet postfix in exactly the same way the username and password were added. I leave the details to the interested reader.</p>

</aside>



<p>You should now have a completed, installable growlView/Growl View/Growl Display/growlStyle/whatever it's actually called. You can export the current <a href="http://github.com/thingsinjars/GrowlBird">Git project</a> to have a look around or you can just download the finished <a href="http://cloud.github.com/downloads/thingsinjars/GrowlBird/GrowlBird_0.2.8.zip">GrowlBird.zip [Zip - 228KB]</a> if you like. Note, the Git project isn't guaranteed buildable at any moment in time, I might break it. The localisations still need done and the layout of the prefPane isn't the greatest, either.</p>



<aside>

	<p><sup>[<a id="note-already" href="#already">1</a>]</sup> Since writing this, I have discovered that someone else <a href="http://clickontyler.com/blog/2009/01/forward-your-growl-notifications-to-twitter/">already made a growlView</a> to do this, it just didn't show up on any of my Google searching.</p>

	<p><sup>[<a id="note-bugged" href="#bugged">2</a>]</sup> It turns out that I did have to modify these in the end due to a <a href="http://github.com/thingsinjars/GrowlBird/commit/0647d13355aad60401b67261a5bab0a59ed4c602">silly bug</a>. Like I said, this is my first attempt at this kind of thing.</p>

</aside></div>    			</div>
    ]]></description>
<pubDate>Sun, 01 Nov 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>It's not difficult, don't make it difficult</title>
<link>http://blah.thingsinjars.com/post/248/its-not-difficult-dont-make-it-difficult/</link>
<guid>http://blah.thingsinjars.com/post/248/its-not-difficult-dont-make-it-difficult/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-248">
    				<div>What's easier? Boiling a single potato, letting it cool, mashing it using a toothpick then repeating with a different potato until you have a plateful of mashed potato...

<em>or</em> 

Boiling all the potatoes you need at once then mashing them together with a potato masher?

Okay, choose between one of these methods of determining whether the bathroom light is on: Draw up a list of people who have visited your house recently. Interview them to build a data set of all rooms visited and by whom. Re-interview those who visited the bathroom. Determine a timeline of bathroom visits and light switch position on entry and on exit. Analyse the data to find the last visitor to the bathroom and the position of the light switch. Examine the electrical connections between the light switch and the light bulb to determine what the current status of the light itself might be.

<em>or</em>

Go look.

How are you doing on the quiz so far? Okay. So, final question: What's easier? Building a convoluted web site using proprietary code, conflicting CSS requiring you to target everything with !important, making all interaction rely on JavaScript for even the most basic functionality, fighting between form and function so much that you end up having a website that only works occasionally and even then only works for a subset of the available users.

<em>or</em>

Building a straightforward website using nothing but standard mark-up, styles which cascade in a predictable fashion and enhancing already-working functionality with a dash of JavaScript to make people go 'Ooh, shiny'?

If you thought the second option was easier, I'm sorry, you would appear to be wrong. At least, that's the impression I get every single day while wandering round the internet. It must be really easy to make a ham-fisted, in-bred, should be kept in the basement monstrous-crime-against-nature abomination of a website because otherwise, people wouldn't do it so much.

I've used Opera as my main browser for almost 10 years now and I've lost count of the number of times I've been faced with a message apologising to me because it appears my browser is out of date. If I could just update my browser to Internet Explorer 5, I could enjoy their site. Seriously, it must be a lot easier to make a web page locking me out of the site than not to. It must be a matter of a few seconds work to write browser-sniffing scripts and learn all the proprietary foibles of IE whereas <em>not</em> writing that script must take hours and <em>not</em> learning bad habits must take years.

I have some ability to forgive those websites which are obviously the work of someone whose passion is something else. If I'm looking at a site where a guy has meticulously documented the different ways different cats react to different balls of yarn, I'm guessing his interests is in yarn. Or cats. Or the combination thereof. He's not necessarily going to know the best way to make a website. I find it much harder, however, forgive big companies. Either those with an in-house web staff or those who contract agencies. Whatever way they do it, someone is getting paid to make the website. It is someone's job to write code. 

I've always been of the opinion that if you're going to do any thing, you should at least <em>try</em> to do it as well as it can possibly be done. It doesn't matter if you're playing piano, rowing, juggling chickens or making a website, you have no excuse for not at least trying to be awesome at it. If you end up being awesome at it: great! You're the world's best chicken juggler, go into the world knowing that and be happy. If you don't: great! You gave it a darn good try and you probably ended up pretty good, at least. Maybe try juggling cats next time. I have a hard enough time getting my head around the idea that not everybody follows this same level of obsession in their interests but to have people who are actually getting paid actual money to do something (in this case, making a website, not chicken juggling) and who feel it's okay to be 'okay' is a concept I have great difficulty understanding.

Okay, impassioned rant over. I'm not going to name any sites. Just consider this a warning, Internet.</div>    			</div>
    ]]></description>
<pubDate>Sun, 25 Oct 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>On holiday, by the way</title>
<link>http://blah.thingsinjars.com/post/247/on-holiday-by-the-way/</link>
<guid>http://blah.thingsinjars.com/post/247/on-holiday-by-the-way/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-247">
    				<div>In case any regular viewers are unaware, I'm currently on honeymoon. To tie in with this (and to celebrate the fact that my darling wife is almost as much of a geek as I am), there's a honeymoon blog to tide y'all over until I get back.

<a href="http://madine.tumblr.com/">The Madines' travelogue</a>.</div>    			</div>
    ]]></description>
<pubDate>Thu, 01 Oct 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Ideas</title>
<link>http://blah.thingsinjars.com/post/245/ideas/</link>
<guid>http://blah.thingsinjars.com/post/245/ideas/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-245">
    				<div>To continue from the post of <time datetime="2009-08-17">a month ago</time> about how <a href="http://noodler.net">Noodle</a> was <a href="http://blah.thingsinjars.com/post/228/a-new-niche/">awesome and ahead of its time</a>, I now have to point out <a href="http://www.google.com/sidewiki/">Sidewiki</a>. Darn it, Google. Couldn't you just have bought me out? I'd have sold. Quite cheap, too...

Anyway. Onto the next idea. Or ideas.

Keen-eyed regulars (those whose don't subscribe via RSS, anyway) will have noticed the new category for '<a href="/ideas/">ideas</a>'. I may as well put all these dumb little ideas I have out there and see if anyone wants to have a go at playing with any of them. Actually, those who subscribe via <a href="http://feeds.feedburner.com/thingsinjars/zjKY">RSS</a> may have been inundated earlier with a bunch of ideas as I uploaded the backdated ones. Sorry 'bout that.</div>    			</div>
    ]]></description>
<pubDate>Thu, 24 Sep 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Okay, unnecesary redesign</title>
<link>http://blah.thingsinjars.com/post/233/okay-unnecesary-redesign/</link>
<guid>http://blah.thingsinjars.com/post/233/okay-unnecesary-redesign/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-233">
    				<div>Not two weeks after being pleased with myself that I could subtly rejig the design without only a few lines of CSS, I decided on Friday to completely redo this site. 

Not only did I change the layout but I've made some major changes under the hood, too. I decided to have my first attempt at an HTML5 page. Granted, it might just fall apart at any moment in any given browser but...hey, it might not.

On the subject of HTML5, <a href="http://en.wikipedia.org/wiki/Mark_Pilgrim">Mark Pilgrim</a> (he of the 'Dive into...' series) brought up an interesting point in the <a href="http://blog.whatwg.org/response-to-notes-on-html-5">WHATWG Blog</a> <time datetime="2009-09-03">last week</time> on the topic of whether XHTML was actually a good idea in terms of enforcing XML syntax on an HTML document:</p><blockquote>It provides no perceivable benefit to users. Draconianly handled content does not do more, does not download faster, and does not render faster than permissively handled content. Indeed, it is almost guaranteed to download slower, because it requires more bytes to express the same meaning -- in the form of end tags, self-closing tags, quoted attributes, and other markup which provides no end-user benefit but serves only to satisfy the artificial constraints of an intentionally restricted syntax.</blockquote><p>And, I guess, it is a good point that a well-formed XHTML document will be larger than the equivalently well-formed HTML document. If, however, developers are given a strict set of rules and a strict validator and told "make your page according to these rules, this alarm will go off if you've done it wrong", they're less likely to fall into bad habits than if they are told "These are mostly rules but sometimes suggestions, this alarm will only go off if you got things very very wrong". Mark Pilgrim is, quite rightly, focusing on the user's point of view but it just seems to me that users will also benefit from more maintainable, better structured code.

Of course, none of this actually matters yet and won't for the next five years or so. It probably won't matter then, either. It is only the interwebs, after all.</div>    			</div>
    ]]></description>
<pubDate>Sun, 06 Sep 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Truly</title>
<link>http://blah.thingsinjars.com/post/232/truly/</link>
<guid>http://blah.thingsinjars.com/post/232/truly/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-232">
    				<div>I've just updated <a href="http://trulyinnovative.com">trulyinnovative.com</a> and <a href="http://www.trulyinnovative.co.uk">www.trulyinnovative.co.uk</a>.

I randomly thought it was about time for a bit of a refresh but writing it, I was amazed at just how much has changed in the 3 years between the first and the second. Despite the fact that they're both supposed to be tongue-in-cheek, they are quite accurate descriptions of two different aspects of the people who 'do web'. Must remember to update them again in 2012.</div>    			</div>
    ]]></description>
<pubDate>Wed, 02 Sep 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Not-too-subtle subtle redesign</title>
<link>http://blah.thingsinjars.com/post/231/not-too-subtle-subtle-redesign/</link>
<guid>http://blah.thingsinjars.com/post/231/not-too-subtle-subtle-redesign/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-231">
    				<div>Okay, it's one of those occasions where I get to feel a bit smug. I decided to update the layout here a little bit, just make the content a bit wider, fonts a bit bigger, that kind of thing. Not a major restyling, just a quick once-round with the vacuum-cleaner, if you like. Less than a minute messing around with CSS later and it's done. It doesn't look like much but I was quite pleased that everything scaled nicely. It's still a bit scrappy round the edges and I wouldn't use this as a CSS showcase but I'm pleased never the less.</div>    			</div>
    ]]></description>
<pubDate>Thu, 27 Aug 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>A new niche?</title>
<link>http://blah.thingsinjars.com/post/228/a-new-niche/</link>
<guid>http://blah.thingsinjars.com/post/228/a-new-niche/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-228">
    				<div><em>"And several months later, our intrepid hero returns to the village to find it full of people he doesn't know..."</em>

A quick update. It's now over a year since <a href="http://noodler.net">Noodle</a> launched and about 4 months since <a href="http://www.ittering.com/">Wwwitter launched</a> and I seem to have started a whole new niche of web-conversation sites. Most of them, I won't mention here but there are two notable examples: <a href="http://convotrack.com">Convotrack</a> and <a href="http://tweetboard.com/alpha/">Tweetboard</a>. If only I'd figured out a way to make money out of it before others did...oh well. 

As I've said many times before, I need some kind of marketing genius to take all these little projects of mine and find out where the money-making potential is. I'll quite happily sit in my room repeatedly coming up with the Next Big Thing if someone will then go off and sell it. On a related note, if anyone fancies marketing MonkeyTV, let me know...</div>    			</div>
    ]]></description>
<pubDate>Mon, 17 Aug 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>The Digital Whateveritscalled</title>
<link>http://blah.thingsinjars.com/post/227/the-digital-whateveritscalled/</link>
<guid>http://blah.thingsinjars.com/post/227/the-digital-whateveritscalled/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-227">
    				<div>Recently, I've been trying to get to grips with this Brave New Digital Future that I've been hearing so much about. I figured that, seeing as I do this for a living, I should probably try and engage, interface, interact, give face time, connect and generally be a bit proactive about...oh, I don't know. Some buzzword or other.

That's why I joined Twitter and it has proven to be moderately useful in providing inspiration for the rebirth of Noodle. <a href="http://www.ittering.com">Wwwitter</a> has had a few thousand unique visitors and several nice reviews (as an aside, I always find the best reviews have a sprinkling of exclamation marks and the worst have a smattering of question marks). The only real issue I have with Twitter is that in order to truly <strong>get</strong> Twitter, you need to follow the right number of people. Too few and it's like overhearing someone having a good conversation on the telephone – "Yeah, and that was only the first colour!" – too many and checking your feed is like sticking your head into a sugar-rushed playgroup – "I like ham!", "Ha-ha-ha!", "@everybody Look at me, look at me!"

This connected, emergent, digital whateveritis is also the reason I joined LinkedIn. I am, however, having a hard time trying to figure out what on earth it is. Is it "Your CV online"? I already have that. Is it "Facebook for business professionals"? Surely the business professionals who sign up to LinkedIn are already on Facebook so...why? I don't accept the argument that Facebook is for your fun side and LinkedIn is for your serious side. If it's online, it's out there in the public domain. If you are embarrassed by the possibility that someone from work might log into facebook and see "Jane Fakename joined the group 'LOL, I got drunk and dropped my mobile in the toilet'", the most obvious course of action is to not join that group, no?

I'm straying from my point, however. I had a look at LinkedIn. It keeps asking me for my goals, my objective, my "Specialties in Your Industries of Expertise". What is it asking? I always thought my goal was "Get old, fat and happy". The way I figure it, if I can do that, I've won whatever game the goal counts in. 

Maybe it's just not aimed at people like me. Then again, I am a "Digital Media Professional" or at least, I play one on TV. I even have the word 'Manager' in my job title. I should be slap-bang in the middle of the target demographic, no? 

Ugh. I need to become a pioneer in anti-social media.</div>    			</div>
    ]]></description>
<pubDate>Thu, 12 Mar 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Oh, hi again</title>
<link>http://blah.thingsinjars.com/post/226/oh-hi-again/</link>
<guid>http://blah.thingsinjars.com/post/226/oh-hi-again/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-226">
    				<div>And after a six-month hiatus, I'm back at the blog. Coincidentally, for the same six month period I stopped studying Japanese. Pretty much the day I got back from Tokyo, I put away my dictionary and didn't open it again until yesterday. Still, I'm back now and I'm starting private lessons again tonight so sit down and I'll make you a cuppa.

So, what's been keeping me away from the blogs and books for the last six months? Loads of stuff, to be honest. The new job for one: Digital Media Studio Manager for <a href="http://www.whitespacers.com/">Whitespace</a>. I wish I could say it's like herding monkeys just because I want to use the phrase "just like herding monkeys" but as it is, it's more like...managing a digital media studio. Or something like that. Outside work (but still within the geek realm), I've been working on <a href="http://www.ittering.com/">Wwwitter</a>, a cool little tool to show twitter discussions about a web page. Regular readers will of course recognise this as a direct copy of <a href="http://noodler.net/">noodle</a> but using someone else's content. It turns out that was all that was required to grab the attention of the internets.

The biggest thing to keep me busy, however, was getting engaged to my beautiful lady, <a href="http://www.flickr.com/photos/photojennic/">Jenni</a> and all the organising that entails. Well, all the organising Jenni's been doing and the confused nodding from me that entails. I'll try and post when I have more details but the big day is 12th September. Don't worry if you haven't received any kind of 'save the date' notification or anything, Jenni's sent hers out, I've just been a bit slow.</div>    			</div>
    ]]></description>
<pubDate>Thu, 05 Mar 2009 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>New Rose Hotel</title>
<link>http://blah.thingsinjars.com/post/225/new-rose-hotel/</link>
<guid>http://blah.thingsinjars.com/post/225/new-rose-hotel/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-225">
    				<div>So there we are, It's my last night in Tokyo and I've definitely got that Case feeling. Standing at my hotel window with a jar of sake, face lit up by the flashing neon outside. Behind me, the room has a cold glow under the light from my computer screen. Unfortunately, the laptop doesn't contain the Dixie Flatline but it's close enough.

I never did find a Chiba chop shop...</div>    			</div>
    ]]></description>
<pubDate>Mon, 25 Aug 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Video Encoding on the Sony Mylo COM 2</title>
<link>http://blah.thingsinjars.com/post/224/video-encoding-on-the-sony-mylo-com-2/</link>
<guid>http://blah.thingsinjars.com/post/224/video-encoding-on-the-sony-mylo-com-2/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-224">
    				<div>Those who know me will know that I have - using the parlance of the modern kids - mad skillz when it comes to video encoding and transcoding. I'll happily admit to wasting far too many hours learning the finer points of ffmpeg, mencoder and vlc, combining them with all manner of shell scripts, web interfaces, cron jobs and the like to set up my own mediacentre, video RSS feeds and <a href="http://www.aninfinitenumberofmonkeys.co.uk/">shared video chatrooms</a> (currently in maintenance mode).

So imagine my combination of frustration ("it should just work") and elation ("ooh, a challenge") when I discovered that my shiny new Mylo is extremely temperamental when it comes to video. I had assumed PSP-friendly video would have been fine but it turns out I was wrong. Any slight variation in frame-rate, bitrate, frame-size, aspect ratio, codec or container and I'd get a lovely "Sorry, the Mylo doesn't support this format" error (but in Japanese).

Anyway. In case you're interested, here's a shell script:

#!/bin/bash
ffmpeg -i "$1" -y -threads 2 -map 0.0:0.0 -f mp4 -vcodec xvid -b 768 -aspect 4:3 -s 320x240 -r ntsc -g 300 -me epzs -qmin 3 -qmax 9 -acodec aac -ab 64 -ar 24000 -ac 2 -map 0.1:0.1 -benchmark "$1.MP4"

call this from the command-line with the path to the file you want converted and 10 minutes later, your Mylo-ready file will be sitting next to the original.

I'm really only posting this here because in about 6 months, I'll have forgotten all about this and, given my current luck with technology, all my computers and all their backups will have simultaneously formatted themselves.</div>    			</div>
    ]]></description>
<pubDate>Tue, 12 Aug 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Some kind of code...</title>
<link>http://blah.thingsinjars.com/post/223/some-kind-of-code/</link>
<guid>http://blah.thingsinjars.com/post/223/some-kind-of-code/</guid>
<description><![CDATA[
      			<div class="teaser flickr" id="teaser-223">
    				<div><p><a href="http://farm4.static.flickr.com/3271/2738666792_9d87b58758.jpg"  rel="lightbox[{smod:id}]"  title="Some kind of code..."><img src="http://farm4.static.flickr.com/3271/2738666792_9d87b58758_m.jpg" alt="Some kind of code..."/></a>I found this Ema (votive tablet) in the grounds of Meiji Jingu last month. A month of playing around with various cyphers has yeilded no results. It's not a straightforward substitution code so frequency analysis doesn't work, I've tried substitutions with an increasing or decreasing offset, backwards and forwards alphabets...<br />
<br />
Obviously the person who wrote it wants to keep it a secret so we probably shouldn't probe further but...anybody got any ideas?</p>
<p>Originally uploaded by <a href="http://www.flickr.com/photos/thingsinjars/2738666792/">thingsinjars</a> on <a href="http://www.flickr.com">flickr</a></p></div>    			</div>
    ]]></description>
<pubDate>Wed, 06 Aug 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Kotoba</title>
<link>http://blah.thingsinjars.com/post/222/kotoba/</link>
<guid>http://blah.thingsinjars.com/post/222/kotoba/</guid>
<description><![CDATA[
  		<div class="teaser smallimage" id="teaser-222">
		  <a href="/post/222/kotoba/"><img src="/uploaded/images/thumbs/kotoba.jpg" alt="Kotoba"/></a>
			<div>After some shuffling around of code and some gradient paint-bucket in Photoshop, the <a href="/widgets/kotoba/Kotoba.mylow">translation widget</a> is done. Remember, of course, that you need a Sony Mylo to use it. Unless you just want to download it, unzip it and have a look at the code, that is.

You can also download it from the <a href="http://www.mylolabs.com/Gallery/WidgetDetails.asp?WidgetID=225">official widget gallery</a>. I'd be interested to find out how well/badly it functions on a non-Japanese Mylo. I have no idea about the language capabilities of other versions.</div>		</div>
]]></description>
<pubDate>Sun, 03 Aug 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Coding Sickness</title>
<link>http://blah.thingsinjars.com/post/221/coding-sickness/</link>
<guid>http://blah.thingsinjars.com/post/221/coding-sickness/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-221">
    				<div>Okay, it's time to accept I have a coding problem. A sickness, an obsession, if you will. 

I was sitting in my kitchen studying Japanese, my shiny new Sony Mylo sitting next to me. I was enjoying having the opportunity of having my computer switched off (seeing as I can just switch on skype on my Mylo). I found a word I didn't recognise in my notes. My paper dictionary was over the other side of the room. Surely there must be a way for me to look up this word easily...

This is the point at which you can spot the obsession. Any normal person would have opened up the mylo, launched the web browser and looked up the word online. Job done*. I, on the other hand, fired up my laptop, downloaded the reference documents and tech specs of the Mylo and spent two hours writing a Japanese-English dictionary widget for it. It's fully functional and translates between English, romaji Japanese and kana Japanese. I'll upload it here and on the official <a href="http://www.mylolabs.com/">Sony Mylo Widget gallery</a> once I've come up with a cool name and a shiny logo.

It's a sickness, I tell you, a sickness...

* [edit] In retrospect, a normal person would have just walked across the room to get the dictionary.</div>    			</div>
    ]]></description>
<pubDate>Sat, 02 Aug 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Weather</title>
<link>http://blah.thingsinjars.com/post/220/weather/</link>
<guid>http://blah.thingsinjars.com/post/220/weather/</guid>
<description><![CDATA[
  		<div class="teaser smallimage" id="teaser-220">
		  <a href="/post/220/weather/"><img src="/uploaded/images/thumbs/one-bolt.jpg" alt="Weather"/></a>
			<div>I'm currently sitting outside typing on my new Sony Mylo watching another mad lightning storm. I'm able to sit outside because there's absolutely no rain at all. The storm is happening directly above me but it's so high, the thunder barely makes it down here. It's also been going on for a surprisingly long time. Normally - in my experience at least - storms come and go in a few minutes but for the last hour, the entire sky's been flickering like a broken fluorescent light. I like the weather here, it's interesting.

Also, despite having sat patiently through several lightning storms taking photos, this is the closest I've come to a proper photo of a fork. One single bolt barely visible round the corner of my flat. Must try harder.</div>		</div>
]]></description>
<pubDate>Tue, 29 Jul 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Extension building is complicated</title>
<link>http://blah.thingsinjars.com/post/219/extension-building-is-complicated/</link>
<guid>http://blah.thingsinjars.com/post/219/extension-building-is-complicated/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-219">
    				<div>With Firefox releasing version 3.0.1 yesterday, I spent a chunk of last night trying to update the <a href="/post/214/noodle-firefox-extension/">noodle extension</a>. I decided it would probably be a good idea to enable automatic updates so keen users would be able to take advantage of the latest features immediately (or some such marketing gubbins).

Basic extension building itself is unnecessarily complicated in my opinion. For a start, <a href="http://www.mozilla.org/projects/xul/">XUL</a> is an extremely clever and powerful tool but has abysmal documentation. I've now done two sizeable projects using it and I still don't have a clue how it works. Once you've got that bit sorted, however, you then need to package up your extension in a very particular way taking care not to forget updating all of the required versioning bits.

If you want to enable automatic updating, you now need to digitally sign it. Not a bad idea, really. It just makes the whole process even more complicated.

My process roughly goes as follows:

<ul>
<li>Update Extension</li>
<li>Update install.rdf with the new version number</li>
<li>On the terminal, run './build.sh' (automatic shell script to package, zip, remove hidden files, copy, paste, resequence, etc)</li>
<li>Upload noodle.xpi to this server</li>
<li>On the terminal, run 'md5 noodle.xpi' (to calculate one of the application hashes)</li>
<li>copy key to <a href="/post/214/noodle-firefox-extension/">noodle extension post</a> for in-browser installation</li>
<li>update update.rdf with the new version number</li>
<li>run 'openssl sha1 noodle.xpi' to generate another application hash)</li>
<li>update update.rdf with new update hash</li>
<li>resign update.rdf with <a href="http://developer.mozilla.org/en/docs/McCoy">McCoy</a> (embeds another application hash)</li>
<li>upload update.rdf to server</li>
<li>cross fingers</li>
</ul>

This process is somewhat more complicated the first time you do it as you also have to use McCoy to digitally sign the install.rdf before you build your extension. McCoy itself is also password-protected.

In total, you have 1 password to run McCoy, 1 extension signature, 1 md5 hash to allow in-browser installation, 1 sha1 hash to allow add-ons menu automatic updating and 1 signed update.rdf. I'm sure I've missed one.</div>    			</div>
    ]]></description>
<pubDate>Thu, 17 Jul 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>The Legend of the Travelling Nev</title>
<link>http://blah.thingsinjars.com/post/218/the-legend-of-the-travelling-nev/</link>
<guid>http://blah.thingsinjars.com/post/218/the-legend-of-the-travelling-nev/</guid>
<description><![CDATA[
  		<div class="teaser smallimage" id="teaser-218">
		  <a href="/post/218/the-legend-of-the-travelling-nev/"><img src="/uploaded/images/thumbs/travelling-nev.jpg" alt="The Legend of the Travelling Nev"/></a>
			<div>The Legend of the Travelling Nev

Whenever world-weary travellers gather to share a yarn or spin a tale, there will always be a clean shaven, leather-skinned old man with a thick bushy beard who settles in the corner with a whisky in each hand and a pipe in the other, pushes his hat to the back of his head and peers out from under it.

"Have ye heard the tale o' the trav'llin' Nev?", he'll say, eyes glinting in the moonlight, sun shining through the boarded up windows. Experienced travellers - those that have been around the world twice and back again - will smile to themselves quietly and eye their glass thinking about the next drink. They've heard the tale before and they'll doubtless hear it again but it's never the same twice; maybe this old fellow can weave a good belly laugh or two in there, maybe he can't. We'll keep an ear on him and another can listen for the call for last orders. The other can pick up the gasps of amazement coming from the younger travellers during the telling of the tale.

Ah, those youngsters...fresh faced and naive as they come. Everyone here was like that at some point but were they ever <em>that</em> young? First time they've been involved in a good old gab and they've thrown themselves into it with every little event that's happened since they left home. Everyone smiles. They're keen. There's nothing nobody's heard a hundred times before. Now they're gathering closer to the old man to find out more about the Travelling Nev.

"Some say he started his journey many years ago in the foothills of Edinburgh, some say that when he started, there was no such thing as Edinburgh. Either way, it's been many a year since he was able to settle anywhere." the old man takes a deep draught from his glass, wipes the beer from his beard and beckons the youngsters closer.

"Cursed he was, y'see. With a terrible curse. A terrible, terrible curse had been cursed upon him like a curse. No-one knows why, how, when or why but, since many a year past, the Trav'llin' Nev has been cursed to wander the planet until he finds a town where nobody knows who he is but wherever he goes, his story is already known. Of course, that's the cunningness o' the curse - the more he travels, the more his tale is spread; the more his tale is spread, the further he has to travel to find peace."

The youngsters are spellbound, their glasses sitting untouched, their mouths open in wonderment. No, it can't be true, can it? Is it? A man travelling endlessly around the world only to find he already knows everyone? No...?

"Ah, I see fr'm yer faces we've a coupla disbelievers amoungst ye. Well, feast yer eyes on this...", the old man fishes in the inside pocket of his travelling jacket, a jacket that's circumnavigated the globe a few times now and looks like it could probably do it once more on its own. He pulls out an old wrinkled, faded photograph that's been folded more than a few times and hands it over to the group which now includes the season travellers whose interest had been piqued.

"That, my friends, is the Trav'llin' Nev", he says as he sits back in his chair, a faintly triumphant smile spreading across his lips, and falls asleep.

<hr />

In other news, I bumped into Nev this week.</div>		</div>
]]></description>
<pubDate>Thu, 10 Jul 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>How to hose your website...</title>
<link>http://blah.thingsinjars.com/post/217/how-to-hose-your-website/</link>
<guid>http://blah.thingsinjars.com/post/217/how-to-hose-your-website/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-217">
    				<div>...in several easy steps.

1: Have a too-clever-for-its-own-good CMS that is child-like in its simplicity yet Canadian-lumber-forest-like in its ability to be hacked.
2: Build several different websites using said CMS, each with their own unique hacks.
3: Have all the sites open in your FTP client and in your text editor
4: Play an episode of Firefly in the background to distrct you.

Now, the next few steps must be done in very quick succession:

5: Upload files from site A to site B
6: Realise mistake, download replacements from site C
7: Upload replacements to site D
8: Realise mistake, reset Subversion backup C
9: Upload site C to site A
10: Watch River Tam kick ass
11: Realise you're getting confused, delete everything and start again
12: Delete Subversion backup B
13: Delete entire project B

Now that you've done that, all that's left is to put everything back the way it was on A, C and D and trawl old backup disks and Google cached pages to try and get B back.

14: Watch Mal shoot someone.
15: Write it up in a post on the freshly-restored, looks-like-it-was-never-broken site B.

Fairly straightforward, really.</div>    			</div>
    ]]></description>
<pubDate>Sat, 28 Jun 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Again with the Barber stories...</title>
<link>http://blah.thingsinjars.com/post/215/again-with-the-barber-stories/</link>
<guid>http://blah.thingsinjars.com/post/215/again-with-the-barber-stories/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-215">
    				<div>Regular readers will, of course, remember my <a href="http://blah.thingsinjars.com/post/176/japanese-barbers-are-great/">previous experiences</a> with my Japanese barber. Well, I started to look like some kind of scruffy hippie again so I braved the rain, grabbed the infamous umbrella and headed out for another haircut. This time, I decided to go the whole hog and find out what the full shave-and-a-haircut experience was like.

He shaved my forehead.

My forehead! Shaved! With a cut-throat razor! Exclamation mark!11One!Factorial

I was so busy being shocked that I only just noticed he followed it by shaving my earlobes. I'm now hairless in places that have had hair since before I was born.

I don't really have any conclusion to take from it other than - He Shaved My Forehead...</div>    			</div>
    ]]></description>
<pubDate>Sun, 22 Jun 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Noodle Firefox Extension</title>
<link>http://blah.thingsinjars.com/post/214/noodle-firefox-extension/</link>
<guid>http://blah.thingsinjars.com/post/214/noodle-firefox-extension/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-214">
    				<div>You can either download the Noodle Firefox extension from the <a href="https://addons.mozilla.org/en-US/firefox/addon/7383">Mozilla Addons Site</a> (recommended but requires registration) or below.

<a href="http://blah.thingsinjars.com/noodle/noodle.xpi" iconURL="http://noodler.net/images/exticon.png" hash="md5:46a9cc1daff4afb0d883f80737bf92e0" onclick="var params = {'Noodle': { URL: event.target.href,IconURL: event.target.getAttribute('iconURL'),Hash: event.target.getAttribute('hash'),toString: function () { return this.URL; }}};InstallTrigger.install(params);return false;">Noodle Firefox extension</a> [1.0.5].

If you download from the Mozilla site, you can leave a review and increase the chance it'll get accepted into the public area (no registration required).

It has been tested with Firefox 2 and 3. Surprisingly, it also works fine with both of them, too.</div>    			</div>
    ]]></description>
<pubDate>Fri, 13 Jun 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Stormy weather</title>
<link>http://blah.thingsinjars.com/post/213/stormy-weather/</link>
<guid>http://blah.thingsinjars.com/post/213/stormy-weather/</guid>
<description><![CDATA[
  		<div class="teaser smallimage" id="teaser-213">
		  <a href="/post/213/stormy-weather/"><img src="/uploaded/images/thumbs/Just-before-Flash.jpg" alt="Stormy weather"/></a>
			<div>I was out on my balcony last night taking photos of the moody stormy weather.

It turns out lightning isn't quite so pretty when you see it up close. Click through the picture to see more.<a href="/uploaded/images/expanded/Just-before-Flash-2.jpg" rel="lightbox[213]" title="Still dull and dark"></a><a href="/uploaded/images/expanded/Flash.jpg" rel="lightbox[213]" title="Holy $£@!"></a></div>		</div>
]]></description>
<pubDate>Tue, 10 Jun 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Aww, shucks...</title>
<link>http://blah.thingsinjars.com/post/212/aww-shucks/</link>
<guid>http://blah.thingsinjars.com/post/212/aww-shucks/</guid>
<description><![CDATA[
  		<div class="teaser largeimage" id="teaser-212">
		  <a href="/post/212/aww-shucks/"><img src="/uploaded/images/thumbs/cards.jpg" alt="Aww, shucks..."/></a>
			<div>Despite the fact that I generally keep my birthday a fairly well-hidden secret, it seems that some people just won't let it lie. It's not that I'm trying to keep my age a secret - I'm proud to say I was born in 1978, the Golden Age of Disco - I just tend to avoid the kerfuffle that goes with presents, parties and cards.

Having said that, I was still over the moon on Thursday night when my <a href="http://www.flickr.com/photos/photojennic">wonderful other half</a> threw a mini surprise birthday party in a cool little cafe/bar called the <a href="http://orblightcafe.blog27.fc2.com/">Orblight Caf&eacute;</a> (Note: I'm not saying Thursday was my birthday, Jenni just happened to be in the country then). Then, after getting over the surprise (and after the first Guinness), she presented me with what seems to have been several months in the planning: cards and birthday e-mails from practically everyone I know! Really, everyone!* There were all kinds: cards written in binary, cartoon cats, even a picture of me when I was 20 (although I look 14)

Thanks everybody. I'm now going off to listen to some Bee Gees.

*except Gary who seems to have completely disappeared. Seriously, e-mail me.</div>		</div>
]]></description>
<pubDate>Mon, 09 Jun 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Comments</title>
<link>http://blah.thingsinjars.com/post/211/comments/</link>
<guid>http://blah.thingsinjars.com/post/211/comments/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-211">
    				<div>I've removed the comment form from below each post here and replaced it with a Noodle button. I figured there's no sense in making a <a href="http://noodler.net/">website devoted to instant commenting</a> if I'm not going to use it myself.

This does coincide with the evil evil spambots cracking my (previously thought to be impregnable) anti-spam system earlier this week but it isn't related. Honest. Darned spam. So it may not have been impregnable but it had a fairly decent run. It lasted seven months and several tens of thousands of attempts to bypass it. Oh well.

At least Noodle uses Google Accounts. If spam starts to come through on it, I'll just remove the ability to post anonymously so everyone will need a google account. I'd rather not do that unless I really have to, though.</div>    			</div>
    ]]></description>
<pubDate>Sun, 11 May 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Noodle</title>
<link>http://blah.thingsinjars.com/post/180/noodle/</link>
<guid>http://blah.thingsinjars.com/post/180/noodle/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-180">
    				<div>I think my latest little project is pretty much done. It still doesn't work absolutely perfectly in Internet Explorer 6 but I figure I'll fix that if enough people ask me to.

So, here it is: <a href="http://noodlesinjars.appspot.com/">Noodle</a>.

"Okay, what is it?", I hear you ask (I don't but play along). Noodle is a variation on a good old-fashioned forum except that every page on the internet has its own thread. Any time you're looking at something, you just press a button and you get to see the discussion for that page. Sometimes a page won't have any comments on it for months (or ever, even), sometimes a page will be extremely busy. 

The pages that are currently the most popular will appear on the Noodle homepage (it's set to show the top 10 at the moment but I might change that) along with the most recent comments.

"So, where's this magic button?" you ask (you're full of questions today, aren't you?). It's here:
<a title="noodle" href="javascript:void(things_z=document.body.appendChild(document.createElement('script')));void(things_z.language='javascript');void(things_z.type='text/javascript');void(things_z.src='http://noodlesinjars.appspot.com/scripts/framer.js');void(things_z.id='things');"><img src="/uploaded/images/button.png" alt="noodle" style="float:none;"/></a>

If you're using Firefox with the bookmarks bar switched on or Opera with the status bar switched on, you can just grab the button, yank it off the page and drag it to your bar. If you're using Internet Explorer 6 or 7, right-click and 'Add to Favourites'. Bear in mind that IE6 is...flaky at times.

<h3>Known issues</h3>
At the moment, the 'Most popular now' section looks a bit daft, seeing as it only has 1 site in it. 

The google account login screen is cut off at the top.

The google logout screen gives a nastly looking error. This is a problem at google's end. Apparently, you don't get this error in the USA but you do in the UK and Japan.

Nicknames are cut short. After my <a href="http://blah.thingsinjars.com/post/175/language/">earlier musings</a>, I decided the safest way to display nicknames (until google fix it) is just to trim bits out. If anyone has a better RegEx for doing this than the one I'm using, let me know.

I'm sure I'll post more about this soon, I'm now off to bang my head against IE for a while.

Yes, I do need better hobbies.</div>    			</div>
    ]]></description>
<pubDate>Sun, 27 Apr 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Japanese Barbers are great.</title>
<link>http://blah.thingsinjars.com/post/176/japanese-barbers-are-great/</link>
<guid>http://blah.thingsinjars.com/post/176/japanese-barbers-are-great/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-176">
    				<div>A quick transcript of the conversation I had with my barber just as I was about to leave:

Barber: Do you have an umbrella?
Me: No, is it raining? (look outside, it's not)
Barber: Ah, wait a second
Barber runs off through the back, comes back with an umbrella.
Barber: Please, take this.
Me: But it's not raining.
Barber: Ah, but it might.
Me: No, really, it's okay, I live just round the corner.
Barber: (looking sad) Please? You don't even need to bring it back.

I took the umbrella. He also gave me a hairbrush.
</div>    			</div>
    ]]></description>
<pubDate>Sat, 19 Apr 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Language</title>
<link>http://blah.thingsinjars.com/post/175/language/</link>
<guid>http://blah.thingsinjars.com/post/175/language/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-175">
    				<div>My latest pointless programming project is just about finished. There's just one little bit left to figure out and then it's done. 

I'm building this using the new Google AppEngine system (mostly because I needed an excuse to learn <a href="http://www.python.org/">python</a>) but there seems to be a bit of a problem with the User object. They haven't finished the <a href="http://code.google.com/appengine/docs/users/userclass.html#User_nickname">User nickname</a> bit yet so when you sign into an AppEngine application or site using a standard Google Account, it uses the bit of your e-mail address that comes before the '@' and, although Google accounts can use any e-mail address, the majority of them will be gmail.com or googlemail.com. This means that if you want to make any kind of public forum, you have to do one of the following:

<ul>
 <li>Implement your own nickname system (not really in the spirit of a unified User object)</li>
 <li>Obfuscate the nickname before displaying</li>
 <li>Display the nickname and open users up to spam or other unwanted e-mail</li>
</ul>

None of these are particularly great. If it were even possible to access the user's first name, that'd solve the problem but, until the nickname functionality is finished, it's not as useful as it could be.

<hr />

As an aside, doing a project in python means that I've written code in pretty much every mainstream (i.e. not <a href="http://en.wikipedia.org/wiki/Esoteric_programming_language">esoteric)</a> programming language except <a href="http://en.wikipedia.org/wiki/COBOL">COBOL</a>.</div>    			</div>
    ]]></description>
<pubDate>Fri, 18 Apr 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Edited Millionaire</title>
<link>http://blah.thingsinjars.com/post/171/edited-millionaire/</link>
<guid>http://blah.thingsinjars.com/post/171/edited-millionaire/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-171">
    				<div>Here's an updated version of my Ramen Millionaire story. Honestly, I'm going to write an english version soon...

<hr />

ラーメン長者

むかしばなしじゃない。さいきん、渋谷にうんのわるい男が住んでいました。毎日、朝から晩まで　まじめに働きましたけどなかなか金持ちになりませんでした。ある日、おなかがぺこぺこだから、ラーメンやたいにいきました。食べながらラーメンやたいの人と話していました。

「どうしてなかなか金持ちにならない？何をするればいんだろう？」と言いました。

「ここから出る時に、ころびます。こたいをみつけます。」とおかしく言いました。

「えええ。。。？彼はあたまがへん。。。」と思っていました。そしてらラーメンやたいを出ました。

「がんばって」らラーメンやたいの人大きい声で言いました。

ふりかえったら男がころびました。しかし、立つ前にやたいの下におもしろい物をみつけました。小さいドラエモンのケータイのストラップでした。立ってからラーメンやたいの人に「ああ。。。かわいい物、ね。。。」と言ったけど彼はいませんでした。

「ええ。。。どこ？」と言いました「じゃ。。。」





それから道を歩き出しました。「よく考えなくちゃ。。。」と思っていました「たぶん。。。ああ！うるさい！なんか？」

お母さんと赤ちゃんが店を出ました。赤ちゃんがうるさくないていました。

「あああ。。。かわいい、ね」

とつぜん思い出したーストラップ！

「えーんえーん！」赤ちゃんと大声でないていました。

男は赤ちゃんにドラエモンのスストラップをあげました。赤ちゃんはすぐに静かになりました。

お母さんは「どうもありがとう」と言いました。「赤ちゃんがよろこんだんからお礼がしたいんです」。ハンドバッグの中をさがしてペットボトルを取り出した　「あ！ウロン茶どうぞ」お母さんからウロン茶をもらいました。





男は歩きつづけました。まもなく、女の人と合いました。顔色がよくありません。

「スポーツクラブ。。。から。。。つかれった。。。のど。。。かわく。。。」と言いました。

男がお茶をあげまてから女の人が飲み出した。

「あああ。どうもありがとうございます。体がよくなりました。ああ！明日、KAT-TUNのコンサートがあります。時間がないので、行くことができません。」

男は女の人にチケットをもらいました。



男は歩きつづけました。まもなく、サラリマンを見ました。サラリマンの車が壊れました。彼は車をけりつけていました。



男は「どうしたの？」と言いました。

サラリマンは「分かりません。動かない。。。」と言いました。「むすめにKAT-TUNのチケットを買ってあげたかったけど店がしまっちゃいました。。。」

男は「どうぞ」と言ってチケットをあげました。

サラリマンはよろこびました。車のかぎをあげました。

「どうもありがとう。車はあなたの。。。」と言って家に走って帰りました。

男は車の中を見ました。小さいワイアが切れていました。男は繕いました。簡単でした。



車のとなりにたっていたらおじいさんが来ました。

「ああっ！さいこう！」と言いました。

おじいさんは有名な映画のディレクターでした。

「古いしおもしろいし僕の新しい映画のシーンで車はパフェクトです」。

「いっしょうに行こう！」と言いました。

男とディレクターさんはさつえい場所にいったら女の人が来ました。

ディレクターさんは「こちらは娘です。映画のしゅやくです。もうすぐ、有名じょゆうになります。」

彼女はスポーツクラブの女の人です！



アシスタントディレクターがディレクターのところに来て静かに耳打ちしました。

ディレクターさんは男に「映画のしゅやくが止めたであなたはこの映画の新しいしゅやく。」と言いました。



後で映画はとても人気になりました。男とディレクターの娘さんも人気になってけっこんしてうれしくなって億万長者になりました。



皆が幸せになりました。</div>    			</div>
    ]]></description>
<pubDate>Wed, 09 Apr 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>A bit too social?</title>
<link>http://blah.thingsinjars.com/post/167/a-bit-too-social/</link>
<guid>http://blah.thingsinjars.com/post/167/a-bit-too-social/</guid>
<description><![CDATA[
  		<div class="teaser smallimage" id="teaser-167">
		  <a href="/post/167/a-bit-too-social/"><img src="/uploaded/images/thumbs/bookmarking.jpg" alt="A bit too social?"/></a>
			<div>I've been looking at adding some more features to <a href="http://dooze.thingsinjars.com/" title="Dooze">the greatest PHP CMS around</a> and decided that simple social bookmarking doohickeys would be useful. The idea is to have a little panel in the admin area where you can check which ones you want listed on your page. Straightforward enough so far, right? Nothing groundbreaking or difficult or anything.

It got tricky when I started trying to figure out what sites should be included. It turns out that while I wasn't looking, social bookmarking sites became quite popular.  Full points go anyone who can name them all.</div>		</div>
]]></description>
<pubDate>Fri, 28 Mar 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Hachiko Crossing</title>
<link>http://blah.thingsinjars.com/post/166/hachiko-crossing/</link>
<guid>http://blah.thingsinjars.com/post/166/hachiko-crossing/</guid>
<description><![CDATA[
      			<div class="teaser flickr" id="teaser-166">
    				<div><p><a href="http://farm4.static.flickr.com/3244/2352102308_52b600820d.jpg"  rel="lightbox[{smod:id}]"  title="Hachiko Crossing"><img src="http://farm4.static.flickr.com/3244/2352102308_52b600820d_m.jpg" alt="Hachiko Crossing"/></a>I have nothing much to say about this photo other than I like it.

Originally uploaded by <a href="http://www.flickr.com/photos/thingsinjars/2352102308/">thingsinjars</a> on <a href="http://www.flickr.com">flickr</a></p></div>    			</div>
    ]]></description>
<pubDate>Sat, 22 Mar 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>That 'back-of-the-wardrobe' feeling...</title>
<link>http://blah.thingsinjars.com/post/164/that-back-of-the-wardrobe-feeling/</link>
<guid>http://blah.thingsinjars.com/post/164/that-back-of-the-wardrobe-feeling/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-164">
    				<div>I've just realised what's so odd about being back in Edinburgh. It feels exactly like I've just come back from an adventure in Narnia. I left normality behind 6 months ago and travelled to a magical, mystical land full of everything I could possibly dream of (mostly really cool geek stuff) where everybody spoke strangely. I stayed just long enough for everything to become normal, where I'd come to expect onigiri to be sold in every corner shop then I travelled back and stepped into life exactly where I left. Everything and everyone exactly the same as it was when I left. That's what's weird about it.

Still, I'll be clambering back into the wardrobe next week now that I've got my new visa.

In other news, I highly recommend <a href="http://en.wikipedia.org/wiki/Heima">Heima</a> by <a href="http://en.wikipedia.org/wiki/Sigur_R%C3%B3s">Sigur Rós</a></div>    			</div>
    ]]></description>
<pubDate>Thu, 06 Mar 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Ramen Millionaire</title>
<link>http://blah.thingsinjars.com/post/163/ramen-millionaire/</link>
<guid>http://blah.thingsinjars.com/post/163/ramen-millionaire/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-163">
    				<div>For my japanese lessons, I've been writing short little essays recently. Usually it's opinions on the weather or plans for the weekend but last week I went a bit mad and rewrote the traditional japanese story "Warashibe Chouja" or "Straw Millionaire" in a modern setting.

My current version is below but I'll probably update/rewrite it as I continue my studies. I'll also get round to typing up the english translation. Apologies to anyone reading on a PC, you'll probably just see a load of boxes...

<hr />

ラーメン長者
むかしばなしじゃない。さいきん、渋谷にうんのわるい男が住んでいました。毎日、朝から晩まで　まじめに働きましたけどなかなか金持ちになりませんでした。ある日、おなかがぺこぺこだから、ラーメンやたいにいきました。食べながらラーメンやたいの人と話していました。
「どうしてなかなか金持ちにならない？何をするんの？」と言いました。
「ここから出る時に、ころびます。こたいをみつけます。」とおかしく言いました。
「えええ。。。？彼はあたまがへん。。。」と思っていました。そしてらラーメンやたいを出ました。
「がんばって」らラーメンやたいの人とどなていました。
ふりかえって男がころびました。しかし、立つ前にやたいの下におもしろい物をみました。小さいドラエモンのケータイのストラップでした。立ってからラーメンやたいの人に「ああ。。。かわいい物、ね。。。」と言ったけど彼はいませんでした。
「ええ。。。どこ？」と言いました「じゃ。。。」


道を歩きました。「よく考えなくちゃ。。。」と思っていました「たぶん。。。ああ！うるさい！なんか？」
お母さんと赤ちゃんが店を出ました。赤ちゃんがうるさくないていました。
「あああ。。。かわいい、ね」
とつぜん思い出したーストラップ！
「わああああああ！」赤ちゃんと大声ないていました。
男は赤ちゃんにドラエモンのスストラップをあげました。赤ちゃんはすぐに静かになりました。
お母さんは「どうもありがとう」と言いました。「赤ちゃんがよろこぶしてからお礼がしたいんです」。手かばんの中にさがしてペットボテルを取り出した　「あ！ウロン茶どうぞ」お母さんからウロン茶をもらいました。


男が歩きつづけました。まもなく、女の人と合いました。顔色がよくありません。
「スポーツクラブ。。。から。。。つかれった。。。のど。。。かわく。。。」と言いました。
男が茶をあげまてから女の人が飲み出した。
「あああ。どうもありがとうございます。体がよくなりました。ああ！明日、KAT-TUNのコンサートがあります。時間がないので、行くことができません。」
男は女の人にチケットをもらいました。

男が歩きつづけました。まもなく、サラリマンを見ました。サラリマンの車が壊れました。彼は車をけりつけていました。

男は「どしたの？」と言いました。
サラリマンは「分かりません。動かない。。。」と言いました。「むすめにKAT-TUNのチケットを買ってあげたかったけど店は閉店しました。。。」
男は「どうぞ」と言ってチケットをあげました。
サラリマンはよろこびました。車のかぎをあげあした。
「どうもありがとう。車があなたの。。。」と言って家に走りました。
男は車の中を見ました。小さいワイアが切れていました。男は繕いました。簡単でした。

車のとなりにたっておじいさんが来ました。
「ああっ！さいこう！」と言いました。
おじいさんは有名な映画のディレクターでした。
「古いしおもしろいし僕の新しい映画のシーンで車はパフェクトです」。
「いっしょうに行こう！」と言いました。
男とディレクターさんは映画の場所にいったら女の人が来ました。
ディレクターさんは「こちらは娘です。映画の大切の人です。まもなく、有名じょゆうになります。」
彼女はスポーツクラブの女の人です！

アシスタントディレクターがディレクターに来て静かに耳打ちにしました。
ディレクターさんは男に「映画のしゅやくが止めた。あなたは僕の新しいしゅやく。」と言いました。

後で映画はとても人気になりました。男とディレクターの娘さんも人気になってけっこんしてうれしくなって長者になりました。

皆が幸せになりました。</div>    			</div>
    ]]></description>
<pubDate>Wed, 13 Feb 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Too much code...</title>
<link>http://blah.thingsinjars.com/post/162/too-much-code/</link>
<guid>http://blah.thingsinjars.com/post/162/too-much-code/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-162">
    				<div>I've obviously been reading and writing far too much code recently. I find myself mentally adding markup to my normal conversations. When I say something like "Despite having a sore back, I managed to vacuum the flat.", I mentally wrap an href round "Despite having a sore back", linking it to a previous conversation (usually with someone completely different) so that the interested listener can open that conversation in a background tab and check it out later...

As long as I don't start carrying around a small yellow sign saying '<a href="http://digg.com/submit?url=blah.thingsinjars.com/post/162/too-much-code/&title=Too%20much%20code...">Digg this</a>', I'll probably recover...</div>    			</div>
    ]]></description>
<pubDate>Wed, 06 Feb 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>The answer to your question</title>
<link>http://blah.thingsinjars.com/post/161/the-answer-to-your-question/</link>
<guid>http://blah.thingsinjars.com/post/161/the-answer-to-your-question/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-161">
    				<div>Because I've been doing lots of development work lately, I've had to spend more time than I'd like in various techie forums trying to find answers to various programming issues. I tend not to hang around forums when I don't need to because I largely find them depressingly full of people like me.

Even though these are technical forums for technically-minded people, there are still too many demonstrations of fuzzy thinking, lots of "Does anyone know how to package xulrunner for OS X", "Has anyone managed to install VLC on an iPhone", "Can anyone make the whatsit do the thing?". Keeping with the free and open sharing of ideas and nurturing of curiosity that The Internet is supposed to encourage, I've created two handy pages with the answer to all these questions.

For all those times someone asks a question like "Does anyone know how to...":

<ul>
<li><a href="/the-answer.html">The Answer</a></li>
<li><a href="/the-other-answer.html">The Other Answer</a></li>
</ul>

To be used in the same frame of mind as <a href="http://tinyurl.com/22c6t">this handy tool</a>.</div>    			</div>
    ]]></description>
<pubDate>Sun, 27 Jan 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Window Sucks.</title>
<link>http://blah.thingsinjars.com/post/159/window-sucks/</link>
<guid>http://blah.thingsinjars.com/post/159/window-sucks/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-159">
    				<div>No real surprises there, I just needed to point out that it's now five past one and I started installing IE7 just under 3 hours ago. Three. Hours.

I needed to test some layouts on IE7, I don't trust IE7 enough to not mess up my <a href="http://www.parallels.com/en/products/desktop/">parallels</a> install so I decided to put it on my development machine in the office in edinburgh via <a href="http://sourceforge.net/projects/cotvnc/">VNC</a>, ran windows update... wait... security updates... wait... restart... windows update...  IE7. Yes, install, please. Installing... wait... restart... run IE7.

"Do you want to run the Phishing filter?"
No.

"Welcome to IE7. Do you want to run the Phishing Filter?"
No.

"Ah, you've opened a new tab. Do you want to run the Phishing Filter?"
No.

I go to the site I wanted to test. True enough, it's gebroken.

Click "Developer toolbar".

Crash... wait... restart... run IE7.

Re-download the Developer Toolbar.

"Do you want to run this?"
Yes.

"Finished downloading. Do you want to run this?"
Yes.

"This program may be unsafe. Do you want run this?"
Dear god, if this computer wasn't in a different hemisphere, I'd lamp it one right now.

Run the installer, fail.

Shut down IE7, run the installer again.

Run IE7.

Go to the site again.

"This site may be unsafe, do you want to run the Phishing Filter?"

Log out of VNC. Step away from the computer, spend 10 minutes ranting to nobody in particular. Feel somewhat better.</div>    			</div>
    ]]></description>
<pubDate>Sun, 20 Jan 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Firemen's Parade</title>
<link>http://blah.thingsinjars.com/post/157/firemens-parade/</link>
<guid>http://blah.thingsinjars.com/post/157/firemens-parade/</guid>
<description><![CDATA[
  		<div class="teaser smallimage" id="teaser-157">
		  <a href="/post/157/firemens-parade/"><img src="/uploaded/images/thumbs/posterl_dzm.jpg" alt="Firemen's Parade"/></a>
			<div>I went to the Tokyo Fire Department's annual parade today and took over 200 photos. It was very impressive, all in all.  The only thing that bothered me was the poster advertising the event...

Am I the only person who expects to see Eric Cartman standing in the middle?<a href="/uploaded/images/expanded/south-park.jpg" rel="lightbox[157]" title="Familiar?"></a></div>		</div>
]]></description>
<pubDate>Sun, 06 Jan 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Banzai!</title>
<link>http://blah.thingsinjars.com/post/153/banzai/</link>
<guid>http://blah.thingsinjars.com/post/153/banzai/</guid>
<description><![CDATA[
  			<div class="teaser video" id="teaser-153">
							</div>
]]></description>
<pubDate>Wed, 02 Jan 2008 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Sushi is good for you</title>
<link>http://blah.thingsinjars.com/post/149/sushi-is-good-for-you/</link>
<guid>http://blah.thingsinjars.com/post/149/sushi-is-good-for-you/</guid>
<description><![CDATA[
  		<div class="teaser smallimage" id="teaser-149">
		  <a href="/post/149/sushi-is-good-for-you/"><img src="/uploaded/images/thumbs/Sushi For Dinner.jpg" alt="Sushi is good for you"/></a>
			<div>It's also very filling. I visited a friend from Edinburgh today who's over here helping her mum pack and they made this excellent dinner.</div>		</div>
]]></description>
<pubDate>Sun, 30 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Christmas Card</title>
<link>http://blah.thingsinjars.com/post/137/christmas-card/</link>
<guid>http://blah.thingsinjars.com/post/137/christmas-card/</guid>
<description><![CDATA[
  		<div class="teaser largeimage" id="teaser-137">
		  <a href="/post/137/christmas-card/"><img src="/uploaded/images/thumbs/mug-shot.jpg" alt="Christmas Card"/></a>
			<div>Before I get any concerned e-mails, I haven't been arrested. I just thought this would be a funny card. I also don't look that rough. At least, I hope not. I've included a couple more recent photos in the pop-up in case you need proof.

Everything here's going well, my Japanese is coming along slowly but surely. I'm now getting private lessons twice a week to help overcome the fact that Japanese is <em>really</em> hard.

I think I must have made it to every area of Tokyo by now, I've been going to a different one each weekend but I still keep finding cool new stuff. I'm also deliberately not going near <a href="http://en.wikipedia.org/wiki/Akihabara">Akihabara</a> at this time of year just in case I get tempted to buy a bunch of stuff as christmas presents to myself.

Anyway, y'all have a good Christmas and New year...
<a href="/uploaded/images/expanded/beard.jpg" rel="lightbox[137]" title="Lookie, it's a beard"> </a>
<a href="/uploaded/images/expanded/christmas.jpg" rel="lightbox[137]" title="Christmas Cheer"> </a></div>		</div>
]]></description>
<pubDate>Thu, 20 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Dooze Done</title>
<link>http://blah.thingsinjars.com/post/136/dooze-done/</link>
<guid>http://blah.thingsinjars.com/post/136/dooze-done/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-136">
    				<div>Just to keep up my current focus on extreme geekery, <a href="http://dooze.thingsinjars.com/">Dooze</a> (formerly known as "s is small") is now available for download. It's kind of ended up as a CMS for people who could probably write their own if they wanted to but just haven't the time. It's still possible to install, customize and use it without knowing any PHP but there's a bunch more stuff you can do with it if you do.

Anyway, enjoy...</div>    			</div>
    ]]></description>
<pubDate>Tue, 18 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Monkeying about with XUL</title>
<link>http://blah.thingsinjars.com/post/135/monkeying-about-with-xul/</link>
<guid>http://blah.thingsinjars.com/post/135/monkeying-about-with-xul/</guid>
<description><![CDATA[
  		<div class="teaser largeimage" id="teaser-135">
		  <a href="/post/135/monkeying-about-with-xul/"><img src="/uploaded/images/thumbs/monkeytv.jpg" alt="Monkeying about with XUL"/></a>
			<div>I've been playing with <a href="http://www.mozilla.org/projects/xul/">XUL</a> for a couple of days now. Kind of interesting and kind of really confusing.

It looks like it could be really useful for making cross-platform applications and the way it works means that it's not a huge jump from HTML development to XUL layouts but getting plugins to work on OS X? Ugh.

The large number of folders called 'plugins' within the standard application structure definitely didn't help. At the moment, my application works but I have no idea why. It's probably a quantum thing, you can either know what it does or how it does it but not both.

Still, it's available for download on the (almost finished) <a href="http://www.aninfinitenumberofmonkeys.co.uk">MonkeyTV</a> site. Now I just need to go through the process again for Windows...</div>		</div>
]]></description>
<pubDate>Mon, 17 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Finally Gapless...</title>
<link>http://blah.thingsinjars.com/post/134/finally-gapless/</link>
<guid>http://blah.thingsinjars.com/post/134/finally-gapless/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-134">
    				<div>A while back I decided to try and fully embrace 'The Mac Way' and use iTunes to listen to my music/update my iPod/browse podcasts/etc.  So I fired it up, told it to catalogue my music collection and sat back hoping to be listening to Ben Folds within minutes. 

Hmmmm...

It's now six weeks later and it finished processing about 10 minutes ago.  During those 6 weeks, it was completely unusable while it tried to 'determine gapless playback information'. While it was waiting, I found out how you prevent it from doing this but that has to be done before you start.

Six weeks. Six. Weeks.

To be fair, it probably doesn't expect your music collection to be quite so large or &ndash; and this is where I think the problem is &ndash; live on a server on the other side of the world.

Still, it's done now.  I just need to make sure I never add any more music ever.</div>    			</div>
    ]]></description>
<pubDate>Thu, 13 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Monkey TV</title>
<link>http://blah.thingsinjars.com/post/133/monkey-tv/</link>
<guid>http://blah.thingsinjars.com/post/133/monkey-tv/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-133">
    				<div>So, my latest little project, <a href="http://www.aninfinitenumberofmonkeys.co.uk">Monkey TV</a> is about to shift from the aleph to the bet testing stage (Hebrew's much more fun than greek).  The site's only been up in its current state for less than 3 days and already it's been hammered by hundreds of spam bots. Really, they're faster than google.

More info and cool stuff when I finish.</div>    			</div>
    ]]></description>
<pubDate>Wed, 12 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Finally, It's cold!</title>
<link>http://blah.thingsinjars.com/post/128/finally-its-cold/</link>
<guid>http://blah.thingsinjars.com/post/128/finally-its-cold/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-128">
    				<div>After an excessively long summer, it's finally beginning to cool down here. I can't believe I was getting a tan in November.

Of course, I'm now beginning to realise that this flat is built for the summer. Air conditioning, thin curtains, no heaters... but I shan't complain.  I survived typhoon season unscathed and there are a lot fewer cockraches around at this time of year...</div>    			</div>
    ]]></description>
<pubDate>Tue, 04 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Earthquakes = Bad</title>
<link>http://blah.thingsinjars.com/post/126/earthquakes--bad/</link>
<guid>http://blah.thingsinjars.com/post/126/earthquakes--bad/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-126">
    				<div>That's it, I've decided. On the whole, earthquakes are a bad idea. Not that I've experienced any particularly bad ones while I've been here – the biggest being a 5.2 about 70 miles north-east – but the ones I have had have been...unsettling. 

A particularly strange thing happens when I'm on Skype to someone during an earthquake, though.  Due to the computer being on the desk, the desk being in the room and the whole room moving as one, it appears on the other end that I start swaying slightly for no apparent reason.

I have prepared myself a little emergency bag, though, just in case there's a big one. It's got spare socks, my solar charger and – when I'm not using it – my Nintendo DS.  At least if there's a disaster, I'll still be able to play Mario Kart.</div>    			</div>
    ]]></description>
<pubDate>Sat, 01 Dec 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>s is small</title>
<link>http://blah.thingsinjars.com/post/65/s-is-small/</link>
<guid>http://blah.thingsinjars.com/post/65/s-is-small/</guid>
<description><![CDATA[
      			<div class="teaser html" id="teaser-65">
    				<div><p>The reason I finally got round to finishing my site is that I built a neat little <acronym title="Content Management System">CMS</acronym> temporarily called 's is small' and wanted to do something interesting with it. It doesn't really do anything that other CMSs don't, I just felt like making it.</p>
<p>It does, however,  have some fairly cool things built in:</p>
<h3>Media</h3>
<ul>
<li>If you attach a video to a post, it'll be automatically converted from whatever format you have (AVI, MPG, WMV, MP4, MOV, etc) into <acronym title="Flash Video">FLV</acronym> and embeded in your post using Jeroen Wijering's <a href="http://www.jeroenwijering.com/?item=JW_FLV_Player">FLV Player</a>.</li>
<li>If you upload an image, it'll get resized then wrapped in <a href="http://www.huddletogether.com/projects/lightbox2/">Lightbox</a></li>
<li>MP3s are automatically embedded in a <a href="www.jeroenwijering.com/?item=jw_mp3_player">flash MP3 player</a></li>
</ul>
<h3>Integration</h3>
<ul>
<li>Put your <a href="http://last.fm">last.fm</a> username in and you  can get a flash or image based list of your Top 10 artists (or most recent played or whatever...)</li>
<li>Put your <a href="http://flickr.com">flickr</a> username in and it'll include your latest photos.</li>
<li>You can set up your flickr account to 'blog this' to automatically include people's flickr posts in your blog (using the Metablog API)</li>
<li>Put your <a href="http://opensourcefood.com">Open Source Food</a> username in and it'll randomly include one of your recipes.</li>
<li>You can set it to be your personal <a href="http://openid.net">OpenID</a> server</li>
<li>Automatic inclusion of a bunch of Google stuff: <a href="http://calendar.google.com">calendars</a>, <a href="http://www.google.com/analytics/">analytics</a> and <a href="http://maps.google.com">maps</a>.</li>
</ul>
<h3>Other stuff</h3>
<ul>
<li>RSS feeds for each category</li>
<li>Some nifty anti-spam stuff...</li>
<li>...which comes in handy for the comments</li>
<li>A simple way to add on any kind of extra functionality as modules</li>
<li>Support for MySQL and PostgreSQL</li>
<li>Automatic installation and database setup (just upload the files and everything will install the first time you visit your site)</li>
<li>Depending on your server setup, the whole thing generally comes in at about 2MB (including the flash movie player and everything)</li>
</ul>
<p>Of course, the next thing I need to do is make a site for the CMS itself and let other people have a go at it.</p></div>    			</div>
    ]]></description>
<pubDate>Tue, 23 Oct 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item><item>
<title>Hey, It's a website...</title>
<link>http://blah.thingsinjars.com/post/1/hey-its-a-website/</link>
<guid>http://blah.thingsinjars.com/post/1/hey-its-a-website/</guid>
<description><![CDATA[
      			<div class="teaser textonly" id="teaser-1">
    				<div>I've finally gotten round to making my own site.</div>    			</div>
    ]]></description>
<pubDate>Tue, 23 Oct 2007 00:00:00 GMT</pubDate>
<category>home</category>
</item></channel>
</rss>