<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Ian Oxley]]></title>
  <link href="http://ianoxley.com/atom.xml" rel="self"/>
  <link href="http://ianoxley.com/"/>
  <updated>2012-05-02T23:11:42+01:00</updated>
  <id>http://ianoxley.com/</id>
  <author>
    <name><![CDATA[Ian Oxley]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Installing Mercurial 2.1 on IIS 7]]></title>
    <link href="http://ianoxley.com/blog/2012/05/02/installing-mercurial-2-on-iis-7/"/>
    <updated>2012-05-02T00:03:00+01:00</updated>
    <id>http://ianoxley.com/blog/2012/05/02/installing-mercurial-2-on-iis-7</id>
    <content type="html"><![CDATA[<p>If you ever need to set up Mercurial on Windows Server 2008 R2 then you should read Jeremy Skinner&#8217;s <a href="http://www.jeremyskinner.co.uk/mercurial-on-iis7/">Setting up Mercurial on IIS7</a>. It&#8217;s a great article that guides you every step of the way, from installing Mercurial and Python, to configuring IIS and setting up SSL.</p>

<p>Because I was using later versions of Mercurial and Python than those used in
the guide (I was using Mercurial 2.1 and Python 2.6; there&#8217;s a note in the
guide stating it used Mercurial 1.4.3 with Python 2.5.4, and should work with
Mercurial 1.5 and Python 2.6.4), there were a couple of problems I
had to workaround - if you&#8217;re using similar versions of Mercurial and Python
to me then hopefully this&#8217;ll help you out, although YMMV:</p>

<ol>
<li><p>Since Mercurial 1.6+, <code>hgwebdir.cgi</code> has been merged with <code>hgweb.cgi</code>. Therefore wherever the article mentioned <code>hgwebdir.cgi</code>, I swapped it for <code>hgweb.cgi</code>.</p></li>
<li><p>After extracting <code>library.zip</code> to <code>C:\inetpub\wwwroot\hg</code>, and copying the <code>templates</code> folder to <code>C:\inetpub\wwwroot\hg</code>, I tried to access <code>http://name_of_server/hg/hgweb.cgi</code> but Python threw an <code>ImportError</code> and complained it couldn&#8217;t find the mercurial module. To get round this I:</p>

<ul>
<li>Reverted the previous copy and extract steps i.e. removed the <code>templates</code> folder, and the extracted <code>library.zip</code>, from <code>C:\inetpub\wwwroot\hg</code></li>
<li>Downloaded <code>mercurial-2.1.1.win-amd64-py2.6.exe</code> from <a href="https://bitbucket.org/tortoisehg/thg-winbuild/downloads/">https://bitbucket.org/tortoisehg/thg-winbuild/downloads/</a> and ran the installer (<strong>NB</strong> you should download the .exe most appropriate for your server). This found the version of Python installed on my system and copied the relevant libraries / modules to Python&#8217;s site-packages folder. I was then able to browse to <code>http://name_of_server/hg/hgweb.cgi</code> without any problems.</li>
</ul>
</li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Foundation Version Control for Web Developers]]></title>
    <link href="http://ianoxley.com/blog/2012/03/24/foundation-version-control-for-web-developers/"/>
    <updated>2012-03-24T22:36:00+00:00</updated>
    <id>http://ianoxley.com/blog/2012/03/24/foundation-version-control-for-web-developers</id>
    <content type="html"><![CDATA[<p><a href="http://chrisdkemper.co.uk/">Chris Kemper</a> and I have got a book out:</p>

<p><img src="http://dl.dropbox.com/u/2234377/img/book_cover.jpg" alt="Foundation Version Control for Web
Developers" /></p>

<p>If you’re new to web development, and new to version control, you should go and
<a href="http://www.amazon.co.uk/gp/product/1430239727/ref=as_li_ss_tl?ie=UTF8&amp;tag=strasanox-21&amp;linkCode=as2&amp;camp=1634&amp;creative=19450&amp;creativeASIN=1430239727">buy
a copy</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Parsing the UNIX timestamp from an ASP.NET JSON-serialised DateTime]]></title>
    <link href="http://ianoxley.com/blog/2012/03/23/parsing-the-unix-timestamp-from-an-asp-dot-net-json-serialised-datetime/"/>
    <updated>2012-03-23T20:57:00+00:00</updated>
    <id>http://ianoxley.com/blog/2012/03/23/parsing-the-unix-timestamp-from-an-asp-dot-net-json-serialised-datetime</id>
    <content type="html"><![CDATA[<p>Scott Hanselman posted an article recently about the fun that is <a href="http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx">parsing
a JSON-serialised
DateTime</a>. Basically, instead of a DateTime being
JSON-serialised to something like <code>2012-03-08T23:12:45</code>, you end up with what
looks like a JavaScript regex in the form <code>/Date11134446542/</code>.</p>

<p>I came across this problem the other week and wrote this little function in
JavaScript to parse the JSON into a Date object:</p>

<div><script src='https://gist.github.com/1993182.js?file='></script>
<noscript><pre><code>/**
 * Returns the UNIX timestamp from the ASP.NET JSON-serialised DateTime
 *
 * @param d - a string in the format /Date(1331127585489)/
 * @return UNIX timestamp extracted from d, or zero
 * @see http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx 
 * for possible changes to the way DateTime objects are serialised to JSON
 *
 * Example usage:
 * var jsonDateTime = '/Date(1331127585489)/';
 * console.log(new Date(parseUnixTime(jsonDateTime)));
 */
function parseUnixTime(d) {
  var tmp = d.match(/\d+/);
  if (tmp &amp;&amp; tmp.length) {
    return parseInt(tmp[0]);
  }
  return 0;
}</code></pre></noscript></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Slides from my Node.js Talk at Super Mondays]]></title>
    <link href="http://ianoxley.com/blog/2011/10/03/slides-from-my-node-js-talk-at-super-mondays/"/>
    <updated>2011-10-03T23:37:05+01:00</updated>
    <id>http://ianoxley.com/blog/2011/10/03/slides-from-my-node-js-talk-at-super-mondays</id>
    <content type="html"><![CDATA[<p>Last Monday I gave a short talk on Node.js at Super Mondays. You can get hold of the <a href="http://www.slideshare.net/ianoxley/nodejs-9449273">slide deck over on SlideShare</a>.</p>

<p><strong><a href="http://www.slideshare.net/ianoxley/nodejs-9449273">Introduction to Node.js</a></strong></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DIBI (Design It. Build It.) 2011]]></title>
    <link href="http://ianoxley.com/blog/2011/06/11/dibi-design-it-build-it-2011/"/>
    <updated>2011-06-11T21:29:56+01:00</updated>
    <id>http://ianoxley.com/blog/2011/06/11/dibi-design-it-build-it-2011</id>
    <content type="html"><![CDATA[<p><a href="http://www.dibiconference.com/">DIBI</a> is a two track Web Conference that this year was held over the 7th and 8th June 2011 at The Sage, Gateshead. I&#8217;d been looking forward to it for ages, having attended last year&#8217;s inaugral event and, as good as DIBI was last year, this year it was even better.</p>

<p>New to this year&#8217;s event was the Afternoon with…Startups over at the Live Theatre, held the afternoon before the main conference. The venue was good, all the talks were really interesting and insightful - particularly those from <a href="http://twitter.com/kevinmann">Kevin Mann</a>, <a href="http://twitter.com/roanlavery">Roan Lavery</a> and <a href="http://twitter.com/bobby_paterson">Bobby Paterson</a> - and I came away from it with plenty of new ideas and inspiration.</p>

<p>The next day was the main two track conference. The first talk of the day for me was <a href="http://twitter.com/jaffathecake">Jake Archibald</a> with <strong>@font-face - Good vs Legal</strong>. This was easily one of the highlights of the day. It was a brilliant talk with a brilliant slide deck brilliantly delivered (I would highly recommend watch the video of the talk when they&#8217;re published shortly). He even used a Wii remote to change move onto the next slide :)</p>

<p>I stayed on the Build It track for the rest of the morning. <a href="http://twitter.com/intranation">Bradley Wright</a> gave an insightful look into <strong>Programming the Real-Time Web</strong>. He covered the various ways that real time info can be sent and displayed in the browser, from the forever iframe approach to newer methods such as those provided by WebSockets and Socket.IO, and also how you can keep your real time web app accessible by using WAI-ARIA attributes.</p>

<p>Rounding out the morning session was <a href="http://twitter.com/frogandcode">Rich Thornett</a> on <strong>Using NoSQL with Yo&#8217;SQL</strong>. It was an interesting look at how Dribbble makes use of MongoDB, where they&#8217;ve favoured it over relational databases and on how it can be used to eliminate <a href="http://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem">N + 1 queries</a> to help boost your site&#8217;s performance.</p>

<p>First up after lunch was <a href="http://twitter.com/atmos">Corey Donohoe</a>, with another one of the day&#8217;s highlights for me. It was a fascinating talk on all the metrics they use at GitHub to help them deploy changes to their site really, really quickly. Front-end behaviour, back-end behaviour, performance and failure rates are all monitored using a variety of tools. Plus there was plenty on the awesomeness that is Hubot!</p>

<p>Next I hopped over to the Design It track for <a href="http://twitter.com/adactio">Jeremy Keith</a> and his <strong>One Web</strong> talk. It was probably the most inspiring talks of the day. It focused on how the &#8220;mobile web&#8221; is a misnomer and shouldn&#8217;t be treated as a separate entity, but instead by adopting a <em>content first</em> approach and focusing on <em>universal access</em> to the web from any device, you can end up with a much better, scalable and richer user experience.</p>

<p>After an exceptionally well timed Red Bull break, I headed back to Build It to catch <a href="http://twitter.com/blaine">Blaine Cook</a> talk about <strong>Building the Social Kaleidoscope</strong>. It featured a really interesting look at <a href="http://webfinger.org/">Webfinger</a>, what it is, how it works and how it can help to solve the problems identifying users on the Web when they&#8217;re details are stored in multiple places and <a href="http://en.wikipedia.org/wiki/Walled_garden_(technology">walled gardens</a>).</p>

<p>The final talk of the day was the keynote from none other than <a href="http://twitter.com/zeldman">Jeffrey Zeldman</a>. Entitled <strong>What Every Web Designer Should Know</strong>, it was a very entertaining talk on the importance of designing from the content out, defining the problem before you try and solve it and, in a similar vein to Jeremy Keith, on how designing for mobile devices first can help you focus on what the user wants to do.</p>

<p>Overall DIBI was a fantastic conference, all the speakers were great and I came away feeling like I learnt a lot. Huge plaudits must go to <a href="http://twitter.com/gavinelliott">Gavin Elliot</a> and the team for all their hard work. Already I&#8217;m really looking forward to DIBI 2012.
  <em>[DIBI]: Design It Build It
  </em>[WAI-ARIA]: Web Accessibility Initiative - Accessible Rich Internet Applications</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[encdec - BaseXX Encoding and Decoding in JavaScript]]></title>
    <link href="http://ianoxley.com/blog/2011/06/03/encdec-basexx-encoding-and-decoding-in-javascript/"/>
    <updated>2011-06-03T23:13:08+01:00</updated>
    <id>http://ianoxley.com/blog/2011/06/03/encdec-basexx-encoding-and-decoding-in-javascript</id>
    <content type="html"><![CDATA[<p>Recently, while hacking around with some Python code I came up with a <a href="https://gist.github.com/865912">Gist for base58 encoding and decoding</a>. Now, just for fun, I thought it would be a good idea / exercise to port this over to JavaScript. This gave rise to <a href="https://github.com/ianoxley/encdec"><strong>encdec</strong> - a small base encoding / decoding library</a>.</p>

<p>By default if uses base58 encoding, but it does let you pass it your own base alphabet allowing you to do base16, base32 or base-whatever-you-like encoding.</p>

<p>Please <a href="https://github.com/ianoxley/encdec">have a play with it</a> and let me know what you think :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Does Google Use the Keywords Meta Tag Site Updated]]></title>
    <link href="http://ianoxley.com/blog/2011/05/27/does-google-use-the-keywords-meta-tag-site-updated/"/>
    <updated>2011-05-27T00:07:11+01:00</updated>
    <id>http://ianoxley.com/blog/2011/05/27/does-google-use-the-keywords-meta-tag-site-updated</id>
    <content type="html"><![CDATA[<p>Just a quick post to say that <a href="http://doesgoogleusethekeywordsmetatag.com/">http://doesgoogleusethekeywordsmetatag.com/</a> has been updated with some ideas from <a href="https://github.com/paulirish/html5-boilerplate">HTML5 Boilerplate</a>, and some colours from <a href="http://mothereffinghsl.com/">HSL</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Slides for my HTML5 Form Validation Talk at Super Mondays]]></title>
    <link href="http://ianoxley.com/blog/2011/04/26/slides-for-my-html5-form-validation-talk-at-super-mondays/"/>
    <updated>2011-04-26T22:36:13+01:00</updated>
    <id>http://ianoxley.com/blog/2011/04/26/slides-for-my-html5-form-validation-talk-at-super-mondays</id>
    <content type="html"><![CDATA[<p>Tonight saw the return of the <a href="http://www.supermondays.org/2011/04/15/lightning-talks/">Lightning Talks at Super Mondays</a>, with me doing a talk on HTML5 Form Validation. You can get the <a href="http://www.slideshare.net/ianoxley/html5-form-validation-7731661">slide deck over on SlideShare</a>.</p>

<p><strong><a href="http://www.slideshare.net/ianoxley/html5-form-validation-7731661">HTML5 Form Validation</a></strong></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Reliance]]></title>
    <link href="http://ianoxley.com/blog/2011/04/15/reliance/"/>
    <updated>2011-04-15T08:53:00+01:00</updated>
    <id>http://ianoxley.com/blog/2011/04/15/reliance</id>
    <content type="html"><![CDATA[<blockquote><ul>
<li>Don’t rely on other people to remove your totally fake “distractions.”</li>
<li>Don’t rely on other people to pat your beret, re-tie your cravat, and make you a nice cocoa whenever that mean man on the internet points out that your “distractions” are totally fake. (Which they are)</li>
<li>Don’t rely on other people to tell you when or whether you have enough information.</li>
<li>Don’t rely on other people to define your job.</li>
<li>Don’t rely on other people to “design your lifestyle.”</li>
<li>Don’t rely on other people to decide when your opinions are acceptable.</li>
<li>Don’t rely on other people to tell you when you&#8217;re allowed to be awesome.</li>
<li>Don’t rely on other people to make you <em>care</em>.</li>
<li>Don’t even rely on other people to tell you what you should or shouldn’t rely on.</li>
</ul>
</blockquote>

<p>From <a href="http://www.43folders.com/2010/10/05/distraction">http://www.43folders.com/2010/10/05/distraction</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What if...]]></title>
    <link href="http://ianoxley.com/blog/2011/04/11/what-if/"/>
    <updated>2011-04-11T20:48:12+01:00</updated>
    <id>http://ianoxley.com/blog/2011/04/11/what-if</id>
    <content type="html"><![CDATA[<blockquote><p>if you ask a “what if?” question and leave it unanswered, you should be ashamed</p></blockquote>

<p>From <a href="http://ajaxian.com/archives/web-ninja-interview-marcin-wichary-creator-of-google-pacman-logo-html5-slide-deck-and-more">http://ajaxian.com/archives/web-ninja-interview-marcin-wichary-creator-of-google-pacman-logo-html5-slide-deck-and-more</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to fix a cross-loader access from pre-verified class error when unit testing an Android app]]></title>
    <link href="http://ianoxley.com/blog/2011/03/13/how-to-fix-a-cross-loader-access-from-pre-verified-class-error-when-unit-testing-an-android-app/"/>
    <updated>2011-03-13T00:59:34+00:00</updated>
    <id>http://ianoxley.com/blog/2011/03/13/how-to-fix-a-cross-loader-access-from-pre-verified-class-error-when-unit-testing-an-android-app</id>
    <content type="html"><![CDATA[<p>When trying to run some Android unit tests, I was getting a <code>java.lang.IllegalAccessError: cross-loader access from pre-verified class</code> error. After Googling I came across <a href="http://stackoverflow.com/questions/2431457/why-do-i-get-a-illegal-access-error-when-running-my-android-tests/2434818#2434818">this helpful answer</a> on Stack Overflow, which linked through this article: <a href="http://dtmilano.blogspot.com/2009/12/android-testing-external-libraries.html">Android Testing: External Libraries</a></p>

<p>Basically, the problem was being caused by me using an external jar file in my project and unit tests. There were 2 steps I needed to follow to fix things:</p>

<ol>
<li>Export the external jar file from the main project i.e. <em>not</em> the test project</li>
<li>Remove the <a href="http://dtmilano.blogspot.com/2009/12/android-testing-external-libraries.html?showComment=1286842519439#c3733652962358358725">reference to the external jar file</a> from my test project</li>
</ol>


<p>Et voila - my unit tests were up and running. Getting them all to pass was another matter though :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Base58 Encoding in Python]]></title>
    <link href="http://ianoxley.com/blog/2011/03/11/base58-encoding-in-python/"/>
    <updated>2011-03-11T23:57:32+00:00</updated>
    <id>http://ianoxley.com/blog/2011/03/11/base58-encoding-in-python</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been having a play around with Python today trying to implement some base58 encoding / decoding. I&#8217;m by no means a Python expert but this is what I came up with (based on <a href="http://www.flickr.com/groups/api/discuss/72157616713786392/">this PHP flic.kr super quick note</a>):</p>

<p>Feel free to fork it or offer suggestions for improvements in the comments :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[2 Things I Learnt About JavaScript This Week]]></title>
    <link href="http://ianoxley.com/blog/2011/02/03/2-things-i-learnt-about-javascript-this-week/"/>
    <updated>2011-02-03T22:54:39+00:00</updated>
    <id>http://ianoxley.com/blog/2011/02/03/2-things-i-learnt-about-javascript-this-week</id>
    <content type="html"><![CDATA[<p>I recently picked up a copy of <a href="http://www.amazon.co.uk/gp/product/0596517742?ie=UTF8&amp;tag=strasanox-21&amp;linkCode=as2&amp;camp=1634&amp;creative=19450&amp;creativeASIN=0596517742">JavaScript: The Good Parts</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=strasanox-21&amp;l=as2&amp;o=2&amp;a=0596517742" alt="" /> and have been reading it on the train to and from work. Although the book&#8217;s preface states that the book is targeted at programmers who are venturing into JavaScript for the first time or who have been working with JavaScript at a novice level I&#8217;m still finding it enjoyable to read and am managing to pick up a few tips along the way.</p>

<p>Two such tips that I picked up this week are:</p>

<ol>
<li>When using the <code>throw</code> statement you can use an object literal to give an exception a type and a message. For example:</li>
</ol>


<pre><code>throw {
  type: 'FooError',
  message: 'Invalid foo'
};
</code></pre>

<ol>
<li>When using closures, avoid creating an anonymous function inside a loop as it can be computationally wasteful and potentially lead to confusing code. For example (this is taken from the book):</li>
</ol>


<pre><code>var add_the_handlers = function (nodes) { 
    var helper = function (i) {
        return function (e) { 
            alert(i);
        };
    }; 

    var i; 
    for (i = 0; i &lt; nodes.length; i += 1) {
        nodes[i].onclick = helper(i);
    }
};  
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My Visual Studio Settings Files]]></title>
    <link href="http://ianoxley.com/blog/2011/01/21/my-visual-studio-settings-files/"/>
    <updated>2011-01-21T00:01:05+00:00</updated>
    <id>http://ianoxley.com/blog/2011/01/21/my-visual-studio-settings-files</id>
    <content type="html"><![CDATA[<p>I thought I&#8217;d posted these on here a while ago. But, as I couldn&#8217;t find them earlier when I was looking for them, I&#8217;ll add this post now so I can find them in the future :)</p>

<p>Anyway, here they are: <a href="http://ianoxley.com/tools/ox.vssettings.zip">Visual Studio settings files</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to fix a MySQL "packet bigger than 'max_allowed_packet' bytes" error (Error 1153)]]></title>
    <link href="http://ianoxley.com/blog/2011/01/08/how-to-fix-a-mysql-packet-bigger-than-max_allowed_packet-bytes-error-error-1153/"/>
    <updated>2011-01-08T00:10:12+00:00</updated>
    <id>http://ianoxley.com/blog/2011/01/08/how-to-fix-a-mysql-packet-bigger-than-max_allowed_packet-bytes-error-error-1153</id>
    <content type="html"><![CDATA[<p>I nearly always rely on the command line when moving data and / or schema changes between two different MySQL servers, exporting data with <code>mysqldump</code> then importing via something like:</p>

<pre><code>mysql -u foo -p dbname &lt; script.sql
</code></pre>

<p>When running this the other day though I was presented with the following error:</p>

<blockquote><p>ERROR 1153: Got a packet bigger than &#8216;max_allowed_packet&#8217; bytes</p></blockquote>

<p>Fortunately help was at hand via <a href="http://forums.mysql.com/read.php?35,75794,253112#msg-253112">this forum post</a>. All I needed to do was run some SQL statements to set some global variables in MySQL like so:</p>

<pre><code>set global max_allowed_packet = 1000*1024*1024; 
set global net_buffer_length = 1000000;
</code></pre>

<p>To check whether this worked was merely a matter of running:</p>

<pre><code>-- should return 1048576000
select @@max_allowed_packet;
</code></pre>

<p>Of course, you could always set the <code>max_allowed_packet</code> in your <a href="http://dev.mysql.com/doc/refman/5.1/en/option-files.html"><code>my.cnf</code> file</a> instead.</p>

<h3>Update</h3>

<p>After upgrading my MacBook Pro to OS X Snow Leopard, error 1153 was replaced with:</p>

<blockquote><p>ERROR 2006: MySQL server has gone away</p></blockquote>

<p>Fortunately the above still fixed things. Of course, if I&#8217;d <a href="http://philsherry.com/2008/12/22/installing-mysql-for-mac-os-x-leopard-105/">listened to Phil Sherry</a> in the first place I might not have had to re-install MySQL after upgrading OS X (although installing MySQL via the binary package installer <em>did</em> seem to install in <code>/usr/local/bin</code> leaving me puzzled as to why it disappeared after the Snow Leopard upgrade. But that&#8217;s a story for another day…).
  *[SQL]: Structured Query Language</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GMail Toolbar Chrome Greasemonkey Script]]></title>
    <link href="http://ianoxley.com/blog/2010/12/10/gmail-toolbar-chrome-greasemonkey-script/"/>
    <updated>2010-12-10T21:07:38+00:00</updated>
    <id>http://ianoxley.com/blog/2010/12/10/gmail-toolbar-chrome-greasemonkey-script</id>
    <content type="html"><![CDATA[<h3>Update</h3>

<p>This no longer works with the new GMail UI</p>

<p>I quite like the toolbar at the top of GMail. You know, the one with links to Google Calendar, Google Reader, Google Docs, et al. But I&#8217;m not that keen on having to scroll right back to the top of the page each time I need access to it. So, I created a simple Greasemonkey script for Google Chrome to apply fixed positioning to the toolbar. That way it always stays at the top of your screen :)</p>

<p>(Firefox users: I did create a <a href="https://github.com/ianoxley/userContent">user stylesheet that achieves the same effect</a>
 recently. However, that relies on the <code>@-moz-document domain(mail.google.com)</code> to restrict the CSS to GMail and Google seems to send different HTML to Firefox than it sends to Chrome).</p>

<p>You can fork a copy of the script from GitHub: <a href="https://github.com/ianoxley/gmailtoolbar">https://github.com/ianoxley/gmailtoolbar</a></p>

<p>Or alternatively download it from here: <a href="http://ianoxley.com/greasemonkey/gmailtoolbar.user.js">gmailtoolbar.user.js</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to Export a List of Google Docs With GoogleCL and a Bash Script]]></title>
    <link href="http://ianoxley.com/blog/2010/10/20/how-to-export-a-list-of-google-docs-with-googlecl-and-a-bash-script/"/>
    <updated>2010-10-20T23:40:43+01:00</updated>
    <id>http://ianoxley.com/blog/2010/10/20/how-to-export-a-list-of-google-docs-with-googlecl-and-a-bash-script</id>
    <content type="html"><![CDATA[<p>I was playing around with <a href="http://code.google.com/p/googlecl/">GoogleCL</a> recently and came up with this: <a href="http://github.com/ianoxley/googlecl-export">http://github.com/ianoxley/googlecl-export</a></p>

<p>It&#8217;s a Bash script that lets you export a list of Google Docs to a specified format. For example, to export a particular folder to PDF you&#8217;d type something like this:</p>

<pre><code>googlecl-export -f pdf -d yourfolderofdocs
</code></pre>

<p>You need to have GoogleCL installed for the Bash script to work (GoogleCL can be downloaded from <a href="http://code.google.com/p/googlecl/">http://code.google.com/p/googlecl/</a>) but otherwise you should just need to make the script executable e.g. <code>chmod u+x googlecl-export</code> and possibly stick it somewhere on your <code>$PATH</code></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Show Grid Bookmarklet for the Drupal ninesixty Theme]]></title>
    <link href="http://ianoxley.com/blog/2010/09/24/a-show-grid-bookmarklet-for-the-drupal-ninesixty-theme/"/>
    <updated>2010-09-24T13:42:35+01:00</updated>
    <id>http://ianoxley.com/blog/2010/09/24/a-show-grid-bookmarklet-for-the-drupal-ninesixty-theme</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been using the Drupal ninesixty theme recently. One of the nice things about it is the ability to add a <code>show-grid</code> class to the <code>&lt;body&gt;</code> tag to display a grid as a background image grid for development / debugging.</p>

<p>But, rather than manually adding and removing this class to the page.tpl.php, I created a bookmarklet to toggle the <code>show-grid</code> class on and off. The code looks like this:</p>

<pre><code>(function() {
  if (document.body.className) {
    var b = document.body;
    if (b.className.indexOf(' show-grid') !== -1) {
      b.className = b.className.replace(' show-grid', '');
    } else {
      b.className += ' show-grid';
    }
  }
})();
</code></pre>

<p>It <em>does</em> make the assumption that your <code>&lt;body&gt;</code> tag will always have a <code>class</code> attribute, although it should be fairly straight forwards to modify the code to allow for cases where the <code>&lt;body&gt;</code> tag does <em>not</em> have a <code>class</code> attribute.</p>

<p>To save it as a bookmarklet, drag this link to your bookmarks bar: <a href="javascript:(function(">Show Grid</a>%20{if%20(document.body.className)%20{var%20b%20=%20document.body;if%20(b.className.indexOf(%27%20show-grid%27)%20!==%20-1)%20{b.className%20=%20b.className.replace(%27%20show-grid%27,%20%27%27);}%20else%20{b.className%20+=%20%27%20show-grid%27;}}})();)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to Create a Drupal Views Items Per Page Filter]]></title>
    <link href="http://ianoxley.com/blog/2010/09/23/how-to-create-a-drupal-views-items-per-page-filter/"/>
    <updated>2010-09-23T23:16:08+01:00</updated>
    <id>http://ianoxley.com/blog/2010/09/23/how-to-create-a-drupal-views-items-per-page-filter</id>
    <content type="html"><![CDATA[<p>Sometimes, depending on the site you are working on, you need to allow (or the client <em>wants</em> you to allow ;)) visitors to be able to select how many items per page will be displayed e.g. on a product listings page.</p>

<p>To do this in Drupal 6 turned out to be a lot easier than I thought. I used the code from <a href="http://foreverheavy.com/10-quick-and-dirty-drupal-tips/#itemsperpage">this blog post by Nicholas Coates</a> but, rather than add it to a views template, I added it to a <a href="http://drupalcontrib.org/api/function/hook_views_query_alter/6">hook_views_query_alter</a> function I was already using. This meant I could easily use the <code>$view</code> object passed as a parameter to this function:</p>

<pre><code>function hook_views_query_alter(&amp;$view, &amp;$query) {
  ...
  $itemCount = $_GET['itemcount']; // this is just as an example
  if ($itemCount == 0) {
    $view-&gt;set_items_per_page(10);
  } else {
    $view-&gt;set_items_per_page($itemCount);
  }
    ...
}
</code></pre>

<p>As Nicholas Coates says in his aforementioned blog post: this is a quick and painless way to implement an items per page filter.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to Fix a Can't Create/Write to File Error With SELECT INTO OUTFILE in MySQL]]></title>
    <link href="http://ianoxley.com/blog/2010/08/24/how-to-fix-a-cant-create-write-to-file-error-with-select-into-outfile-in-mysql/"/>
    <updated>2010-08-24T23:42:55+01:00</updated>
    <id>http://ianoxley.com/blog/2010/08/24/how-to-fix-a-cant-create-write-to-file-error-with-select-into-outfile-in-mysql</id>
    <content type="html"><![CDATA[<p>Have you ever tried to use <a href="http://dev.mysql.com/doc/refman/5.1/en/select.html"><code>SELECT…INTO OUTFILE</code></a> in MySQL and come across the following error?</p>

<blockquote><pre><code>  "Can't create/write to file '/path/to/folder/filename' (Errcode: 2)"
</code></pre></blockquote>

<p>I was having this problem the other day and, after checking that file permissions weren&#8217;t the cause of the problem, I came across the following <a href="http://forums.mysql.com/read.php?20,369583,370808#msg-370808">post on the MySQL forums</a>:</p>

<blockquote><pre><code>  "The problem was not in MySQL but in AppArmor on Ubuntu. I had to add the directories I wanted to write into to my /etc/apparmor.d/usr.sbin.mysqld and restart apparmor.d."
</code></pre></blockquote>

<p>So, one <code>sudo vim /etc/apparmor.d/usr.sbin.mysqld</code> later and I&#8217;d added the <code>path/to/folder</code> I needed to be able to write to (not forgetting to add the trailing comma &#8216;,&#8217; to the end of the line, which is <em>always</em> required, even for the last line).</p>

<p>All that was left to do was to restart AppArmor with:</p>

<pre><code>$ sudo /etc/init.d/apparmor restart
</code></pre>

<p>After that, <code>SELECT…INTO OUTFILE</code> worked like a charm :)</p>
]]></content>
  </entry>
  
</feed>

