<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Legends of the Sun Pig: Everything (blog, reviews, et al.)</title>
    <link rel="alternate" type="text/html" href="http://sunpig.com/martin/" />
    <link rel="self" type="application/atom+xml" href="http://sunpig.com/martin/feeds/everything-atom.xml" />
    <id>tag:sunpig.com,2008-02-11:/martin//everything</id>
    <updated>2012-05-12T20:52:40Z</updated>
    <subtitle>Combined feed for Legends of the Sun Pig: blog, reviews, and other stuff.</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 5.11</generator>

<entry>
	<title>Amsterdam tourist tip: the free ferries across the river</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/05/05/amsterdam-tourist-tip-the-free-ferries-across-the-river.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2317</id>
    
	<published>2012-05-05T14:34:02Z</published>
	<updated>2012-05-12T20:52:40Z</updated>
    
	<summary><![CDATA[As a tourist in Amsterdam, there's a good chance you will arrive at Centraal Station, leave by the front, and spend most of your time in "the centre" &mdash; the concentric canals, bridges, merchant houses, cafés, museums, and sights make it a beautiful place to wander and cycle. But if...]]></summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>As a tourist in Amsterdam, there's a good chance you will arrive at <a href="http://en.wikipedia.org/wiki/Amsterdam_Centraal_railway_station">Centraal Station</a>, leave by the front, and spend most of your time in "the centre" &mdash; the <a href="http://en.wikipedia.org/wiki/Canals_of_Amsterdam">concentric canals</a>, bridges, merchant houses, cafés, museums, and sights make it a beautiful place to wander and cycle.</p>

<p>But if you want a slightly different view of the city, try heading out of the station in the opposite direction. Out the back is where you will find the river Ij (pronounce it "eye" or "aye", and you'll be close enough), and the ferries to take you to "Noord" (North).</p>

<p class="center"><img src="http://sunpig.com/martin/images/2012/ij-veer.jpg" /></p>

<p>With the exception of the green "<a href="http://www.iamsterdam.com/en/placestogo/fast-flying-ferry/3a04e014-f4ef-48eb-b02f-2b3b1ed8a669">Fast Fying Ferry</a>" <a href="http://en.wikipedia.org/wiki/Hydrofoil">hydrofoil</a> to Ijmuiden, the passenger ferries across the river are completely free. No tickets, no hassle &mdash; you just walk on (bikes and scooters are allowed on board), and enjoy the ride. There are various routes, but the ones I take most often are the "short ferry" to Buiksloterweg and the "long ferry" to NDSM.</p>

<p>The short ferry runs at least every 10 minutes day and night, and the crossing only takes a few minutes. The Buiksloterweg is on the other side of the river, directly opposite the station. You can sit yourself down at the very pleasant <a href="http://www.tolhuis.nl/">Tolhuis</a> café and restaurant for a drink or something to eat, and watch the river traffic go by, with a great view of the back of the station. Film (and architecture) buffs may also be interested in the newly opened <a href="http://www.eyefilm.nl/en/">Dutch Film Museum</a> in the eye-opening <a href="http://www.flickr.com/photos/filmmuseum/sets/72157624294356568/">EYE building</a>.</p>

<p class="center"><img src="http://sunpig.com/martin/images/2012/ij-crossing.jpg" /></p>

<p>The long ferry is my favourite, though. It leaves once every 30 minutes throughout the day (every 15 minutes during commute hours), and is a relaxing 12-minute trip a couple of kilometers down the Ij to the NDSM Werf, a former shipbuilding an industrial area that is gradually transforming into a hot spot for local festivals and fresh startups. The ferry docks right next to an <a href="http://en.wikipedia.org/wiki/File:Soviet_submarine_Amsterdam.jpg">abandoned Zulu-class Soviet submarine</a>.</p>

<p>Right at the end of the NDSM ferry you can relax at the trendy <a href="http://www.ijkantine.nl/">Ijkantine</a>, or walk a bit further to hang out at the more funky and organic <a href="http://www.noorderlichtcafe.nl/">Noorderlicht</a>. (Ask for a cup of <a href="http://www.coffeemuffins.com/fresh-mint-tea/3561/">fresh mint tea</a> if you're into that kind of thing.) Both places have outdoor seating with great views of the river if it's a nice day. NDSM is also a good point for setting off on a cycle ride to the countryside North of the city: <a href="http://nl.wikipedia.org/wiki/Het_Twiske">Het Twiske</a>, a lovely nature reserve (with a windmill!), is just a few miles away.</p>

<p>NDSM is the home of the <a href="http://www.pannenkoekenboot.com/home.aspx">Pancake Boat</a>: a small cruise ship that will take you on an hour-long trip up and down the Ij, while serving an all-you-can-eat pancake buffet. Great views of the city, and enough food to choke a horse; fun for all the family.</p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>My son, the Dragonborn</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/04/19/my-son-the-dragonborn.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2316</id>
    
	<published>2012-04-19T20:05:46Z</published>
	<updated>2012-04-19T20:08:07Z</updated>
    
	<summary></summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p class="center"><img src="http://sunpig.com/martin/images/2012/fus-ro-dalex.jpg" alt="fus-ro-dalex" /></p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Hacked, grr</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/04/18/hacked-grr.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2315</id>
    
	<published>2012-04-18T21:39:17Z</published>
	<updated>2012-04-25T09:07:17Z</updated>
    
	<summary>Late this afternoon, I happened to do a Google search for something I had written on my blog last year. The article came up in the search results, but when I clicked on it, I was redirected to a different site (a .ru domain). The target page didn&apos;t load, though....</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>Late this afternoon, I happened to do a Google search for something I had written on my blog last year. The article came up in the search results, but when I clicked on it, I was redirected to a different site (a .ru domain). The target page didn't load, though.</p>

<p>Primary investigative steps:</p>

<ol>
<li>Try it again. Still happens.</li>
<li>Try search in a different browser. Still happens.</li>
<li>Shit, I've been hacked.</li>
<li><code>ssh</code> to my server. Because I use Movable Type as my blog software, there are physical HTML files on disk for all my blog entries. Looking at the source code that <em>should</em> have been served up showed nothing unusual.</li>
<li>Examine the .htaccess file for my site. This is where the damage was being done. The .htaccess file controls things like redirects, and a bunch of code had been added to mine. Interestingly, it was checking the <strong>referer</strong> on each incoming HTTP request, and only redirecting viewers that had come from a search engine. If you typed "http://sunpig.com/martin" directly into the address bar of your browser, or if you arrived via a bookmark or a non-search engine link, you would be let in as normal. The hack was designed purely to bleed off search engine traffic.</li> 
</ol>

<p>Next step: find out <em>when</em> the damage was done, and how long this had been going on. The modified time on the .htaccess file was very recent - just an hour previously, in fact. It seemed unlikely that I had caught the hack so quickly after it had happened.</p>

<p>I logged in to my host's control panel, and checked the account access logs. These logs showed that no-one but me had logged in to my account using ssh or the control panel in the last month. Good. I changed my account password anyway. I also notified my host, and told them what I'd found so far.</p>

<p>I used the unix <code>find</code> command to see what files had been changed in the last 7 days:</p>

<pre class="code"><code class="shell" data-language="shell">find . -mtime -7</code></pre>

<p>This showed a bunch of files I knew I had changed or added myself, some log files that I would have expected to be changed, and also: a stack of .htaccess files where there should not have been any, a bunch of unfamiliar PHP files all called "pagenews.php", and two "index.php" files that I shoud not have been altered in the last week.</p>

<p>Next, I identified <em>all</em> .htaccess files in my account, and all files called pagenews.php:</p>

<pre class="code"><code class="shell" data-language="shell">find . -name ".htaccess"
find . -name "pagenews.php"</code></pre>

<p>Then I looked for common text signatures in the files, to see if there was anything else I was missing:</p>

<pre class="code"><code class="shell" data-language="shell">grep -r "on\.ru" .
grep -r "FilesMan" .</code></pre>

<p>Okay, infection identified. I could clean up the affected files, but I still didn't know how the attacker got in in the first place. Without knowing that, there would be nothing to stop them getting straight back in again.</p>

<p>The time stamps on all the affected files went back three days. Some were stamped today, some were stamped yesterday; only one dated back to Monday. I checked the Apache log files of web traffic, and found that yesterday's time stamps matched up with unusual HTTP POST requests to the two index.php and pagenews.php files. Those files used some kind of obfuscation, so I couldn't figure out what they were actually doing; but the fact that the file timestamps matched the web access logs, it seems like a reasonable assumption that those POST requests were actually writing files on my server.</p>

<p>However, the one index.php file with a timestamp of Monday didn't have a matching entry in the HTTP logs. I checked the file permissions, and found that they were set to <strong>666</strong>: readable and writeable by everyone on the server.</p>

<p>So my working theory was: at some point on Monday, a process owned by some other user on the same server process on the shared server discovered that I had an index.php file ripe for taking over. It injected the malicious code, but didn't do anything else immediately. Then, on Tuesday, some other part of the attack kicked in, and started making HTTP requests to the infected PHP file. Because the affected PHP code is running under <em>my</em> account now, it's free to muck around with other files that belong to me. So the infection spreads to other areas around my server...</p>

<p>Recovery steps:</p>

<ul>
<li>Remove the newly created pagenews.php files. Manually remove the infection code from the index.php files, and the .htaccess files. (The .htaccess files were modified, not overwritten. The malicious code was added to the start and end end of the file.)</li>
<li>Lock down permissions on all files and folders in my account, so that no-one else on the shared server has permission to write to them.</li>
<li>Remove unused code (old versions of Movable Type, Thinkup, lessn, inactive dev sites) to minimize attack surface for the future.</ul>
<li>Upgrade to latest version of Movable Type (<a href="http://www.movabletype.com/blog/2012/02/movable-type-513-507-and-438-security-updates.html">5.13</a>)</li>
</ul>

<p>To recursively apply <strong>755</strong> permissions to directories, and <strong>644</strong> permissions (read/write by me, read-only by others) to files:</p>

<pre class="code"><code class="shell" data-language="shell">find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;</code></pre>

<p>Steps for the future: run a scheduled backup job for static files on the server. I already use <a href="http://sourceforge.net/projects/automysqlbackup/">autoMySQLBackup</a> for daily backups of the databases on the server, but clearly I need to consider the static files, too. <a href="http://vasilis.nl/">Vasilis van Gemert</a> has an example here: <a href="https://gist.github.com/2415901">https://gist.github.com/2415901</a>.</p>

<p>Lessons learned:</p>

<ul>
<li>If you're running on a shared server, make sure that your files are not writeable by others on that server.</li>
<li>Backups. It's not a matter if <em>if</em> something goes wrong, it's a matter of <em>when</em>. My home backup strategy is pretty solid; my server backups are still lacking.</li>
<ul>
]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Walking through London</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/04/15/walking-through-london.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2313</id>
    
	<published>2012-04-15T17:28:55Z</published>
	<updated>2012-04-18T20:41:48Z</updated>
    
	<summary>I just finished reading Kate Grifin&apos;s The Midnight Mayor, and last week I read Christopher Fowler&apos;s Bryant &amp; May Off The Rails. Both books are love letters to London. They revel in the thick layers of history, above ground and below. The city is a living thing, metaphorically for Arthur...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p><a href="http://www.goodreads.com/book/show/6465697-the-midnight-mayor"><img src="http://sunpig.com/martin/images/2012/midnight-mayor.jpg" class="left" /></a>I just finished reading <a href="http://www.kategriffin.net/">Kate Grifin's</a> <i><a href="http://www.goodreads.com/book/show/6465697-the-midnight-mayor">The Midnight Mayor</a></i>, and last week I read <a href="http://www.christopherfowler.co.uk/blog/">Christopher Fowler's</a> <i><a href="http://www.goodreads.com/book/show/7348101-bryant-may-off-the-rails">Bryant & May Off The Rails</a></i>. Both books are love letters to London. They revel in the thick layers of history, above ground and below. The city is a living thing, metaphorically for Arthur Bryant and John May, and literally for Matthew Swift, the protagonist of Kate Griffin's series. In both cases, the city can be angered or appeased, coaxed and cajoled into giving up its secrets. Bryant and May, detectives, discover a vital clue in the different patterns of upholstery used on the Underground's 12 lines; Matthew Swift, a sorcerer, uses the Underground's terms and conditions of carriage as a powerful magical ward to defend himself.</p>

<p><a href="http://www.goodreads.com/book/show/7348101-bryant-may-off-the-rails"><img src="http://sunpig.com/martin/images/2012/off-the-rails.jpg" class="right" /></a>I've never lived in London, only visited, and so I only know it through the eyes of a tourist. But my most vivid memories of the city are of <em>walking</em> through it, not of the shopping or glitzy attractions.</p>

<p>Walking around Covent Garden when Abi and I took the train down from Edinburgh on day in the late 90s, just to have lunch at Belgo's, and coffee with James. Walking from my hotel near Victoria to the QEII conference centre in the mornings and back again in the evenings, in June 2006 for the @Media conference; a steady soundtrack of <i>At War With The Mystics</i> by The Flaming Lips on my iPod. Walking from Waterloo to the Tower with Abi &amp; the kids, and Jules &amp; Becca; deciding that we were too tired to visit, so camping out at a nearby Starbucks for a cool frappucino instead. Walking from Victoria to Southwark last September for lunch with Bora, because it was a glorious day, and I had the time; gazing up in awe at the Shard under construction.</p>

<p>I'm more than a little tempted to plan a holiday in London solely for the purpose of walking the city, North to South, East to West. Not planning for any stops along the way; just taking it as it comes. Getting underway before dawn, and watching the city come to life around me. Lunch from a sandwich shop, dinner from a chippie. I don't know how far I'd get, or what I'd see; I don't actually know the city that well; but that's part of the point. To walk, to see, to be.</p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Bookmarks, the physical kind</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/04/15/bookmarks-the-physical-kind.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2312</id>
    
	<published>2012-04-15T16:42:19Z</published>
	<updated>2012-04-15T22:47:07Z</updated>
    
	<summary>For bookmarks, I like using markers of a time and place: bus, train, and plane tickets; cinema or concert tickets; significant receipts, especially from holidays; appointment cards; other people&apos;s business cards, just after I met them. After finishing the book, I leave the marker in the book for my future...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>For bookmarks, I like using markers of a time and place: bus, train, and plane tickets; cinema or concert tickets; significant receipts, especially from holidays; appointment cards; other people's business cards, just after I met them.</p>

<p>After finishing the book, I leave the marker in the book for my future self to discover, years later, and to remember the circumstance of the journey or meeting. Sometimes fondly, sometimes not at all.</p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>A responsive experience begins on the server...</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/30/a-responsive-experience-begins-on-the-server.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2311</id>
    
	<published>2012-03-30T09:04:23Z</published>
	<updated>2012-04-02T17:56:48Z</updated>
    
	<summary>...But it doesn&apos;t end there. On MobiForge a few weeks ago, Ronan Cremin pointed out that most top sites use some form of server-side detection to send different HTML to different devices. In a follow-up article, he takes Google as a specific example to show just how widely its content...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>...But it doesn't <em>end</em> there.</p>

<p>On <a href="http://mobiforge.com/">MobiForge</a> a few weeks ago, Ronan Cremin pointed out that <a href="http://mobiforge.com/designing/blog/server-side-device-detection-used-82-alexa-top-100-sites">most top sites use some form of server-side detection to send different HTML to different devices</a>. In a follow-up article, he takes Google as a specific example to show just <a href="http://mobiforge.com/designing/story/anatomy-a-mobile-web-experience-google-com">how widely its content varies between an iPhone, a BlackBerry Curve, and a Nokia 6300</a>.</p>

<p>I'm not arguing against server-side detection, and sending different content to different devices. I think it's an essential part of an adaptation strategy. But I just want to quickly point out a few reasons why it's not <em>enough</em> in order to cover the whole spectrum of browsers. Here are a few things that <em>you won't know</em> when a browser makes its first request to your web server:</p>

<ul>
<li><strong>The height and width of the viewport being used.</strong> (Including the device's portrait/landscape orientation.) If you detect a mobile device, you will be able to look up the device's "standard" dimensions in a device database, but the user's actual viewport may be different. If you place a web app on your iPhone's home screen, and run it without browser chrome, it will send the same user-agent string as when it is running in a browser with chrome (thus reducing the available height). The user may be viewing your site in a browser panel embedded in a separate app, which may present a different viewport. As Stephanie Rieger explained in "<a href="http://stephanierieger.com/viewports-all-the-way-down/">Viewports all the way down...</a>", <em>anyone</em> can create embed a web view of arbitrary size in a home-made ebook.</li>
<li><strong>The zoom level.</strong> Lyza Gardner wrote about how <a href="http://blog.cloudfour.com/the-ems-have-it-proportional-media-queries-ftw/">zoom levels and different text sizes can mess up pixel-based responsive layouts.</a> A user-agent string contains no information about whether a user has changed the default font size in their browser. It does happen, and probably more often than you think.</p>
<li><strong>Whether the user has cookies, and/or JavaScript enabled</strong>. <a href="http://sunpig.com/martin/archives/2011/05/10/the-spectrum-of-commonly-disabled-browser-features.html">I mentioned some of the reasons people <em>disable</em> JavaScript last year</a>. I think that on mobile devices, which are commonly bandwidth-capped and/or rate-limited, people have a greater than normal incentive to disable JavaScript. (I don't have any statistics to back this up, though; it's just a feeling.) Lack of JavaScript can play havoc with some client-side detection techniques. (And lack of cookies will trip you up in many more ways; treat that as a general personalization problem.)</p>
</ul>

<p>Basically, just because the user-agent string says "iPhone" doesn't automatically mean you're dealing with 320 x 480. Server-side detection alone will not give you the full picture, and only doing adaptation client-side robs you of the opportunity to perform really useful server-side optimizations. The best approach is a blend of the two, as Luke Wroblewski describes in "<a href="http://www.lukew.com/ff/entry.asp?1392">RESS: Responsive Design + Server Side Components</a>".</p>

<p>RESS is MORE.</p>

<h3>Further reading:</h3>
<ul>
<li>Dave Olsen: <a href="http://www.dmolsen.com/mobile-in-higher-ed/2012/02/21/ress-and-the-evolution-of-responsive-web-design/">RESS, Server-Side Feature-Detection and the Evolution of Responsive Web Design</a></li>
<li>Ronan Cremin: <a href="http://mobiforge.com/starting/story/mobile-web-content-adaptation-techniques">Mobile web content adaptation techniques</a></li>
</ul>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Uploading photos from iPhoto (11) to Flickr</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/28/uploading-photos-from-iphoto-11-to-flickr.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2310</id>
    
	<published>2012-03-28T08:51:26Z</published>
	<updated>2012-03-28T09:46:40Z</updated>
    
	<summary><![CDATA[I used to use the Flickr Uploadr tool a lot to upload photos to Flickr, but over the last year or so I've found myself doing it less and less &mdash; even to the point of wondering if I should keep up my Flickr Pro membership. I think this was...]]></summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>I used to use the Flickr <a href="http://www.flickr.com/tools/uploadr/">Uploadr</a> tool a lot to upload photos to Flickr, but over the last year or so I've found myself doing it less and less &mdash; even to the point of wondering if I should keep up my Flickr Pro membership. I think this was because I started using iPhoto. I don't used iPhoto a <em>lot</em>, but adding one more tool to my photo workflow was enough to make the act of working with photos a <em>burden</em>.</p>

<p>Before iPhoto, my workflow was:</p>

<ol>
  <li>Copy photos from camera memory card onto my computer</li>
  <li>Rename folders &amp; organize photos into archive structure</li>
  <li>Use Flickr Uploadr to upload photos from hard disk to Flickr, setting correct rotation, photo set and tags</li>
  <li>Go to Flickr to add photos to the map. Maybe add some titles manually.</li>
</ol>

<p>iPhoto never simplified these steps for me. It only added to them:</p>

<ol start="5">
  <li>Import photos into iPhoto</li>
  <li>Use iPhoto to organize photos into events, and set the correct rotation. Maybe add some titles manually.</li>
</ol>

<p>Over time, I drifted into the habit of only placing photos into my own archive and importing them into iPhoto, and skipping the steps of uploading to Flickr. Flickr is not a bad tool by any means, but rotating and sorting in iPhoto is much faster and more immediately rewarding. The extra effort of doing all this again for Flickr put me off doing it at all.</p>

<p>However, at some point in the past, I must have noticed that iPhoto allows you to connect a Flickr account. (Go to iPhoto → Preferences → Accounts, and you'll see the option to add Flickr, Facebook, MobileMe, and Email accounts. Selecting Flickr will take you to the Flickr website, where you can authorise iPhoto to post photos to your stream on your behalf.) I just didn't do anything with this option until yesterday, when I discovered the "share" button in the bottom right corner of iPhoto:</p>

<p><img src="http://sunpig.com/martin/images/2012/share-on-flickr.jpg" /></p>

<p>From here, you can add the selected photos to an existing Flickr set or create a new one. You can set the usual privacy options, and you can choose whether to upload a scaled-down image or the full version.</p>

<p>This means that I can organize all of my photos in iPhoto, rotate them, name them, add descriptions, set a map location, etc.; and then push them up to Flickr at the press of a button. No added effort. Awesome. <em>This</em> is a workflow I can live with.</p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Vertical alignment of child and parent</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/27/vertical-alignment-of-child-and-parent.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2309</id>
    
	<published>2012-03-27T15:08:28Z</published>
	<updated>2012-03-27T15:15:59Z</updated>
    
	<summary>Which are the blog entries I will enjoy looking back on most in ten years&apos; time: the hard-core techie ramblings about irrelevant ancient technical obscurities, or the personal musings that give insight into where my heart was at? Thought so. I don&apos;t remember when I got to be as tall...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>Which are the blog entries I will enjoy looking back on most in ten years' time: the hard-core techie ramblings about irrelevant ancient technical obscurities, or the personal musings that give insight into where my heart was at?</p>

<p>Thought so.</p>

<p>I don't remember when I got to be as tall as my mum, but Alex is getting pretty close now. This photo is from last week (21 March 2012). Alex will be 11 in just a couple of weeks.</p>

<p class="center"><a href="http://sunpig.com/martin/images/2012/vertical-align-large.jpg"><img src="http://sunpig.com/martin/images/2012/vertical-align-small.jpg" /></a></p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Outdenting properties for debug CSS</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/25/outdenting-properties-for-debug-css.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2308</id>
    
	<published>2012-03-25T17:28:09Z</published>
	<updated>2012-03-27T12:27:46Z</updated>
    
	<summary>Whenever I&apos;m tinkering with CSS for experimental or debugging purposes, I usually end up adding a ton of properties to help me figure out how things fit together: weird background colours, borders, alternate fonts, etc. I don&apos;t want to leave these properties in place when I put the CSS live,...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>Whenever I'm tinkering with CSS for experimental or debugging purposes, I usually end up adding a ton of properties to help me figure out how things fit together: weird background colours, borders, alternate fonts, etc. I don't want to leave these properties in place when I put the CSS live, though. To mark a CSS property as a temporary/debug property, I <em>outdent</em> it, putting it at column 0 in the file:</p>

<pre class="code"><code class="css" data-language="css">.monkey{
    position:absolute;
    height:200px;
    width:300px;
    top:20px;
    left:20px;
    background:url(/images/monkey.jpg) no-repeat;
border:2px solid green;
    z-index:10;
}</code></pre>

<p>If you diff your code and review your changes before you commit to your version control system <em>(you do use a VCS, don't you?)</em>, it's often easy enough to spot a debug property, and fix it before you actually check it in. But sometimes the changes are subtle, and they slip through anyway. By outdenting properties, they remain visually obvious in your code even <em>after</em> accidentally pushing them to production.</p>

<p>Sometimes adding a property isn't the right debugging technique. Sometimes you want to override a property instead &mdash; and set yourself a reminder to change it back when you're done. Because <em>later</em> property values overrides earlier ones, this technique works just as well:</p>

<pre class="code"><code class="css" data-language="css">.fez{
    position:absolute;
    height:200px;
    width:300px;
    top:20px;
top:100px;
    left:20px;
    background:url(/images/fez.jpg) no-repeat;
    z-index:10;
}</code></pre>

<p>You can do the same by commenting out the original property, of course, but I find the outdenting technique faster to clean up afterwards.</p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Goldilocks and the Three Device Pixel Ratios</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/18/goldilocks-and-the-three-device-pixel-ratios.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2307</id>
    
	<published>2012-03-18T19:42:22Z</published>
	<updated>2012-05-08T09:05:06Z</updated>
    
	<summary>By default, your typical mobile browser (Mobile Safari, Android browser) will pretend to have a &quot;desktop-sized&quot; viewport when it renders a web page. The web page will appear zoomed-out and tiny, and you&apos;ll have to zoom in to read most of the text. The photo below shows three Android devices...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>By default, your typical mobile browser (Mobile Safari, Android browser) will pretend to have a "desktop-sized" viewport when it renders a web page. The web page will appear zoomed-out and tiny, and you'll have to zoom in to read most of the text. The photo below shows three Android devices side-by-side, rendering a plain web page, so you can compare what they look like. From left to right, the devices are:</p>

<ol>
<li>Samsung Galaxy Y running Android 2.3. Screen size: 240px x 320px; physically 4.5cm x 6cm (~135 pixels/inch)</li>
<li>Samsung Galaxy Ace running Android 2.2. Screen size: 320px x 480px; physically 4.9cm x 7.8cm (~166 pixels/inch)</li>
<li>Motorola Defy+ running Android 2.3. Screen size: 480px x 854px; physically 4.5cm x 8.1cm (~271 pixels/inch)</li>
</ol>

<a href="http://sunpig.com/martin/images/2012/01-viewport-android-desktop-large.jpg"><img src="http://sunpig.com/martin/images/2012/01-viewport-android-desktop-small.jpg" /></a>

<p>As expected, the page is zoomed out, and the JavaScript I use to read the screen width reports 800px.</p>

<p>If you are building for mobile, you probably don't want this. You can use the <code>viewport</code> meta tag in the head of your document to tell the browser to render at the actual width of the device.</p>

<pre class="code"><code data-language="html">&lt;meta name="viewport" content="width=device-width"&gt;</code></pre>

<p>The photo below shows the Android browser rendering a page with this meta tag:</p>

<a href="http://sunpig.com/martin/images/2012/02-viewport-android-device-width-large.jpg"><img src="http://sunpig.com/martin/images/2012/02-viewport-android-device-width-small.jpg" /></a>

<p>Wait, what? They all show a screen width of 320px? Don't those three devices all have different screen sizes? Shouldn't they go 240px, 320px, 480px? I paid for a high-resolution 480x854px phone, damn it; where are my pixels?!</p>

<p>Let's have a look in Opera Mobile:</p>

<a href="http://sunpig.com/martin/images/2012/03-viewport-opera-device-width-large.jpg"><img src="http://sunpig.com/martin/images/2012/03-viewport-opera-device-width-small.jpg" /></a>

<p>240px, 320px, 320px. O-kaaaay...</p>

<p>What's going on is that the device/browser manufacturers are trying to be helpful. The screen of the Defy+ phone is physically narrower than the Galaxy Ace, but it squeezes more pixels into each square inch of the display. Using one <em>device pixel</em> for each <em>CSS pixel</em> of a 480px-wide layout on a 4.5cm-wide screen would result in some very small text. So there is a <em>zoom factor</em> to adjust the way the page is rendered. In Opera Mobile, you can see (and change) the zoom factor by going to Settings → Zoom. The picture below shows the zoom zettings on these three phones:</p>

<a href="http://sunpig.com/martin/images/2012/04-opera-settings-zoom-large.jpg"><img src="http://sunpig.com/martin/images/2012/04-opera-settings-zoom-small.jpg" /></a>

<p>You can see that on the third device, the zoom level is set to 150%, which is how 480px gets turned into 320px. If I set that to 100%, then the results are as expected:</p>

<a href="http://sunpig.com/martin/images/2012/05-viewport-opera-device-width-large.jpg"><img src="http://sunpig.com/martin/images/2012/05-viewport-opera-device-width-small.jpg" /></a>

<p>The stock Android browser has a similar setting, found under Menu → More → Settings → Default zoom. In the Android browser your choices are limited to "Close", "Medium", and "Far".</p>

<a href="http://sunpig.com/martin/images/2012/06-android-settings-zoom-large.jpg"><img src="http://sunpig.com/martin/images/2012/06-android-settings-zoom-small.jpg" /></a>

<p>By default, all of the Android browsers had their zoom set to "Medium". By setting the first device to "Close", and the third device to "Far", I can persuade the devices to render at their natural hardware resolution.</p>

<a href="http://sunpig.com/martin/images/2012/07-viewport-android-device-width-large.jpg"><img src="http://sunpig.com/martin/images/2012/07-viewport-android-device-width-small.jpg" /></a>

<p>This doesn't actually help me as a web developer, though, because I can't force a user to change their browser settings.</p>

<p>This is where the <code>target-densitydpi=device-dpi</code> viewport setting comes in. With this setting, you can indicate that you want a specific page to render at the device's native hardware resolution:</p>

<pre class="code"><code data-language="html">&lt;meta name="viewport" content="width=device-width, target-densitydpi=device-dpi"&gt;</code></pre>

<p>If I set all the android browsers back to the default "Medium" zoom, and set the zoom on Opera Mobile back to 150% for the Defy+, then I get the following results when I view a page with the target-densityspi property set:</p>

<a href="http://sunpig.com/martin/images/2012/08-viewport-android-device-dpi-large.jpg"><img src="http://sunpig.com/martin/images/2012/08-viewport-android-device-dpi-small.jpg" /></a>
<a href="http://sunpig.com/martin/images/2012/09-viewport-opera-device-dpi-large.jpg"><img src="http://sunpig.com/martin/images/2012/09-viewport-opera-device-dpi-small.jpg" /></a>

<p>Looking back at all these photos, you can see that the test pages show a second value, pixel ratio, which comes from <code>window.devicePixelRatio</code>. This <em>should</em> (I think) tell you how many <em>device</em> pixels go into a <em>CSS</em> pixel. For example, if the screen width is 320px, and <code>window.devicePixelRatio</code> reports 1.5, then the device is actually using 480 hardware pixels to render the 320px-wide layout. This means you're working with a high-resolution display, so text will be crisper, and you can use high-resolution versions of images.</p>

<p>But although this works as expected in Opera Mobile, the Android browser seems to always report the default value for <code>window.devicePixelRatio</code> no matter what the actual value is on the page, as specified either by the user's zoom setting, or forced by the <code>target-densitydpi=device-dpi</code> property in the viewport meta tag. Android browser on the Defy+ keeps reporting a value of 1.5 even when it is using a 1:1 pixel mapping, and the Galaxy Y keeps reporting 0.75. Likewise, <code>min-device-pixel-ratio</code> media queries are triggered from these default values, not from the active pixel ratios. This might be a problem when it comes to loading different versions of image assets.</p>

<p>I don't recommend using this <code>target-densitydpi</code> viewport setting in real life. It may be tempting to force a 1:1 pixel mapping so that you can deliver wider layouts to high-resolution devices, but a typical 480px-wide layout looks uncomfortably small on a 4.5cm-wide screen. The point of high-resolution screens on mobile devices is to make the content look <em>sharper</em> at the same physical dimensions, not to keep squeezing more and more content into that space. I'm pretty sure that's why Mobile Safari on iOS does not support this property in the viewport meta tag at all.</p>

<p>At the other end of the scale, there are plenty of <em>low-resolution</em> devices out there that use a devicePixelRatio of less than 1 to make their small viewports appear wider. The inexpensive Samsung Galaxy Y is a great example. It has a screen width of 240px, but pretends to be 320px wide by rendering 4 CSS pixels are across every 3 hardware pixels. This makes 320px-wide layouts look a bit blurry, but that's better than breaking; many sites consider 320px as their mobile baseline (hello, iPhone), and ignore smaller viewports.</p>

<p>(Aside: "Nobody <em>really</em> uses a 240x320 screen" is the 2012 version of "nobody <em>really</em> browses the web on their phone." Actually, <em>yes they do</em>. But because of this pixel scale factor, you might not notice them in your analytics.)</p>

<p>Basically, don't set <code>target-densitydpi</code> unless you really know what you're doing, and are prepared to consider the <em>actual physical dimensions</em> of your CSS pixels, which means testing on a lot of devices. Otherwise, trust the mobile browser to render those CSS pixels at a size that is comfortable for most users. If the user wants more control, the browser zoom setting is just a couple of taps away.</p>

<h3>Test pages</h3>
<ul>
	<li><a href="http://sunpig.com/martin/code/2012/androidzoom/devicewidth.html">No viewport meta tag</a></li>
	<li><a href="http://sunpig.com/martin/code/2012/androidzoom/devicewidth.html">width=device-width</a></li>
	<li><a href="http://sunpig.com/martin/code/2012/androidzoom/devicewidth.html">target-densityDpi=device-dpi</a></li>
</ul>

<h3>Further reading</h3>
<ul>
	<li>Dan Fabulich: <a href="http://darkforge.blogspot.com/2010/05/customize-android-browser-scaling-with.html">Customize Android Browser Scaling with target-densityDpi</a></li>
	<li>MDN: <a href="https://developer.mozilla.org/en/Mobile/Viewport_meta_tag">Using the viewport meta tag to control layout on mobile browsers</a></li>
	<li>Jozef Kutej: <a href="http://blog.kutej.net/2011/02/meta-nameviewport.html">&lt;meta name="viewport"&gt;</a></li>
	<li>Peter-Paul Koch: <a href="http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html">A pixel is not a pixel is not a pixel</a></li>
	<li><a href="http://dev.w3.org/csswg/css-device-adapt/">W3C CSS Device Adaptation (Editor's Draft)</a></li>
</ul>
]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Devices, devices, devices</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/12/devices-devices-devices.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2306</id>
    
	<published>2012-03-12T13:30:36Z</published>
	<updated>2012-03-29T08:11:22Z</updated>
    
	<summary>Before I start on my own thing, let me first point you to what Brad Frost and Stephanie Rieger have already written on the subject of building a device library: Stephanie Rieger - Strategies for choosing test devices Brad Frost - Test on Real Mobile Devices without Breaking the Bank...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>Before I start on my own thing, let me first point you to what Brad Frost and Stephanie Rieger have already written on the subject of building a device library:</p>

<ul>
<li>Stephanie Rieger - <a href="http://stephanierieger.com/strategies-for-choosing-test-devices/">Strategies for choosing test devices</a></li>
<li>Brad Frost - <a href="http://bradfrostweb.com/blog/mobile/test-on-real-mobile-devices-without-breaking-the-bank/">Test on Real Mobile Devices without Breaking the Bank</a></li>
</ul>

<p>Without wanting to get into the debate over <a href="http://tripleodeon.com/2011/09/of-sites-and-apps/">"sites" and "apps"</a>, I think the distinction has some bearing on how you choose to spend your money in building a device library. Here's how:</p>

<ul>
<li>Site-like, or document-oriented web projects generally align with a <strong>100% compatibility strategy</strong>: you want your <strong>content</strong> to render acceptably and be at least minimally usable on <em>any</em> web browser.</li>
<li>App-like web projects generally align with a <strong>partial compatibility strategy</strong>: your focus is on providing a set of <strong>features</strong> to browsers that meet a set of minimum requirements. (Although if your requirement is simply "webkit", I may have to come and hurt you.)</li>
</ul>

<p>Other markets are different, but <a href="http://gs.statcounter.com/#mobile_os-eu-monthly-201202-201202-bar">StatCounter's mobile figures for Europe in February 2012</a> show that 73% of mobile browsing comes from iOS and Android devices. (Some Android and iOS users may be using Opera Mobile or Mini, but that percentage is small.) Throw in a smattering of BlackBerry 6 and 7 devices, some high-end Nokias, and a few Windows Phones, and you could take this to mean that about 80% of mobile web users are working with a touch-screen device running a relatively modern browser.</p>

<p>If you go with the partial compatibility strategy, your device library should cover this 80%. Testing a feature-heavy site on BlackBerry 5 or Nokia S60 browser is going to drive you mad, and isn't going to serve your core customer base. Because you're concentrating on the medium-to-high end of the market you'll spend more money per device, but you can get away with relatively few of them. I'd suggest a handful of Android and iOS devices, a BlackBerry 7, and a Windows Phone Mango. Make sure that the devices you get cover a variety of screen resolutions (small smartphone, large smartphone, tablet).</p>

<p>If you're aiming for 100% compatibility, you need to focus your attention on the other 20%, because that's where you're going to spending the vast majority of your time debugging and fixing crazy bugs. Buy as many cheap, old, low-spec, oddball devices as you can lay your hands on. Any time someone says "WTF - you're browsing the web on that thing?" award yourself special bonus points. Low-spec is good because if your site works well on a slow device, it's only going to do better on a faster one. Because the 20% represents the long tail, you will need more devices, but they will be cheaper ones, so you'll probably end up spending just the same amount of money.</p>

<p>Building a device library is not a one-off thing. It's not like a developer workstation that you can get away with upgrading every 2-3 years. New devices and new OS upgrades are being delivered at a rapid pace. If you can afford it, you should be looking to add new devices to your library at least every six months. Again, if you can afford it, don't upgrade the OS on old devices. Over time, they will become your legacy devices.</p>

<p>Finally, I consider it important to actually <em>use</em> the devices. Having a spectrum of devices sitting on a shelf in the office while you walk around with an iPhone 4S in your pocket will not get you exposed to the strengths and weaknesses of the different platforms and form factors. For example, if all you use is a touchscreen, you won't understand what it's like to browse with just a keyboard. (Try unplugging the mouse from your desktop machine, and see how that works out.)</p>

<p>For reference, here's the stack of devices I have on hand for testing:</p>

<ul>
<li><a href="http://en.wikipedia.org/wiki/Nokia_N95">Nokia N95</a>. 240x320 screen, S60 browser. The first phone I used for doing mobile web work. Released in 2007; an impressive piece of kit at the time. Unfortunately it has lost the ability to connect to my wifi, so testing with it is a bit of a pain now.</li>

<li><a href="http://en.wikipedia.org/wiki/Nokia_C3-00">Nokia C3-00</a>. 320x240, keyboard, no touch screen. Uses the Nokia Ovi browser by default, but also has Opera Mini built in. Cute little phone.</li>

<li><a href="http://en.wikipedia.org/wiki/Nokia_C5-03">Nokia C5-03</a>. 360x640 <em>resistive</em> touch screen with haptic feedback - it buzzes when you press the screen hard enough for it to register a touch/tap. The screen is small, but high resolution, and looks great. I used to think that it was a bit crap for web use because it only had a numeric keypad, but that was before I figured out that the qwerty keypad only shows up when you hold the phone in landscape mode on its <em>left</em> side, not on its <em>right</em>. Way to go, Nokia. Also, the "Create WLAN connection in offline mode" prompt should have died 5 years ago.</li>

<li><a href="http://www.engadget.com/2010/06/03/motorola-flipout-preview/">Motorola FlipOut</a>. Android 2.1, 320x240 touch screen, <em>and</em> a keyboard. The keyboard doesn't slide out, <a href="http://www.youtube.com/watch?v=0fgv9Vu-m80">it <em>rotates</em> out from behind a corner</a>. When it's closed, this looks more like a pager than a phone. It's cute and small, and I really like it.</li>

<li><a href="http://en.wikipedia.org/wiki/Samsung_Galaxy_Ace">Samsung Galaxy Ace</a>. Android 2.2, 320x480 touch screen. Relatively cheap and versatile, because it can be upgraded to run 2.3 as well. (Buy two while they're still selling them with 2.2!).</li>

<li><a href="http://en.wikipedia.org/wiki/Samsung_Galaxy_Y">Samsung Galaxy Y</a>. Android 2.3, 240x320 touch screen that pretends it's 320x480. Cheap. Nice-looking little phone, but the touch screen is dreadfully inaccurate.</li>

<li><a href="">Acer Iconia Tab A100</a>. Android 3.2, 1024x600. Piece. Of. Crap. Poor screen, slow, a capacitative "home" button that makes an accidental touch target no matter which way you hold it, and the battery won't hold a charge in standby mode for more than 48 hours. The only thing it has going for it is its price. (That, and the fact that it fills the Android 3.x hole in my line-up.)</li>

<li><a href="http://en.wikipedia.org/wiki/IPhone_3G">iPhone 3G</a>. iOS 4.2, 320x480. The first iPhone in our household; I inherited it from Abi when she upgraded to a 4 in 2010. Useful as a legacy iOS4 device.</li>

<li><a href="http://en.wikipedia.org/wiki/IPod_Touch">iPod touch 4th generation</a>. iOS 4.3, 320x480 (retina). Gorgeous little device. This is my stand-in for an iPhone 4, because it has the same A4 chip and retina display resolution (although the screen is slightly lower-quality than the actual iPhone 4). I'm currently trying to figure out if I want to upgrade it to iOS5 to match the distribution of hardware in the wild, or keep it on iOS4 as a legacy device. It's a cost consideration.</li>

<li><a href="http://en.wikipedia.org/wiki/IPad">iPad (original)</a>. iOS 5, 1024x768. Still great.</li>

<li><a href="http://en.wikipedia.org/wiki/BlackBerry_Curve">BlackBerry Curve 8900</a>. BlackBerry OS 5, 480x360 screen, keyboard. BlackBerry 5 is the OS That Will Not Die. BB5 devices are still being sold in volume because they're cheap, have great keyboards, and people like using them for texting and messaging.</li>

<li><a href="http://en.wikipedia.org/wiki/LG_Optimus_7">LG Optimus 7</a>. Windows Phone 7 Mango, 480x800 touch screen. This was my first Windows Phone, but I don't think it'll be my last. I like WP7 as an OS. I like the sleek design, and the live tiles on the home screen. As a phone, the Optimus 7 is just okay. It's big, heavy, the screen brightness is harsh, and the camera is only so-so. But I still found myself carrying it around a lot as my day-to-day phone.</li>

<li><a href="">Nintendo 3DS</a>. This is what I mean by "oddball". It has two screens, one on top of the other. The top screen has an effective resolution of 400x240 (landscape) and the bottom one is 320x240 (landscape). When you load up a page, the page loads into the bottom screen, but you can scroll it upwards. Only half the page is touch-capable (the bottom screen). The browser is a custom webkit build, made by Netfront. It scores 125 on <a href="http://html5test.com">html5test.com</a>. It's cheaper than most of the other devices in my library, and it plays Zelda? Come on, how can you not love this? The big disappointment is that you can't embed 3d images in a web page. The top screen has to switch into a separate 3d-mode to show 3d images and video.</li>

</ul>

<p>And here's what's on my shopping list for the next round of upgrades:</p>

<ul>
<li><del>An Android 2.3 device with a larger screen. Android 2.3 currently holds the largest installed base, and a lone 320x240 device just isn't sufficiently representative</del> 13 March 2012: target acquired. <a href="http://www.motorola.com/Consumers/XW-EN/Consumer-Products-and-Services/Mobile-Phones/MOTOROLA-DEFY-PLUS-XW-EN">Motorola Defy+</a></li>
<li><del>The new iPad with retina display. These are going to sell by the ton, and people will be using them to browse the web <em>all the time</em>. Apart from wanting one for myself, I can easily see the new iPad on its own accounting for more than 10% of all mobile browsing by the end of the year.</del> 23 March 2012: target acquired. This thing is awesome.</li>
<li>A BlackBerry 7. A touchscreen-only or keyboard-only device would be cheaper; a touch+keyboard device would cover both categories, but it much more expensive. Also, not a huge market share. Not sure about this.</li>
<li>An Android 4. There aren't enough Android 4 devices on the market <em>yet</em> to give it a significant amount of market share, and therefore to worry about it as a target for testing with. I'm trusting that it's going to be <em>mostly</em> like Android 3.x, but faster. I might check out the Samsung Galaxy Tab 2 7" when it appears. Otherwise, I'll just wait for cheaper devices.</li>
</ul>

<h3>Further reading</h3>
<ul>
<li><a href="http://mobiletestingfordummies.tumblr.com/post/20056227958/testing">Device testing for the BBC responsive news site</a></li>
<li><a href="http://pxldot.com/post/18754186750/ios-ebb-and-flow">"iOS Ebb and Flow" by Chris Suave</a> (iOS platform statistics).</li>
<li><a href="http://developer.android.com/resources/dashboard/platform-versions.html">Android platform statistics</a>.</li>
<li><a href="http://us.blackberry.com/developers/choosingtargetos.jsp">BlackBerry platform statistics</a>.</li>
<li><a href="http://tinnedfruit.com/2012/01/11/your-mobile-mileage-may-vary.html">Jim Newbery - Your mobile mileage may vary</a></li>
</ul>

]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Website traffic patterns in the presence of native apps</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/11/website-traffic-patterns-in-the-presence-of-native-apps.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2305</id>
    
	<published>2012-03-11T16:33:43Z</published>
	<updated>2012-03-11T17:31:26Z</updated>
    
	<summary>A serious question for anyone running a website that has a matching native app to go with it: looking at the platform on which the app is available, is the share of website traffic from this platform going up or down (or staying static)? My suspicion is that the share...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>A serious question for anyone running a website that has a matching native app to go with it: looking at the platform on which the app is available, is the share of <em>website</em> traffic from this platform going <em>up</em> or <em>down</em> (or staying static)?</p>

<p>My suspicion is that the share of mobile web traffic for most platforms is still going up, even in cases where a native app alternative is available.</p>

<p>Please comment, or contact me if you have any data to share!</p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>A rich client tipping point</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/05/a-rich-client-tipping-point.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2304</id>
    
	<published>2012-03-05T09:27:21Z</published>
	<updated>2012-03-08T08:20:03Z</updated>
    
	<summary>Francis Hwang talks about reaching a tipping point in web application development: If you are writing a new web application, you should make it a rich-client application from the start. Your servers should not generate any HTML. You should do all that work in the browser with a Javascript framework...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p><a href="http://fhwang.net/2012/03/05/Should-your-web-application-be-rich-client-from-day-one">Francis Hwang talks about reaching a tipping point in web application development</a>:</p>

<blockquote>
<p>If you are writing a new web application, you should make it a rich-client application from the start. Your servers should not generate any HTML. You should do all that work in the browser with a Javascript framework such as <a href="http://backbonejs.org/">Backbone.js</a> or <a href="http://emberjs.com/">Ember.js</a>, and the server should only talk to the browser via a REST API.</p>
</blockquote>

<p>I'm <em>very close</em> to agreeing with this, but I have my own set of caveats.</p>

<p>First of all: mobile. If you're using an iPhone 4(S), you might not realize that a lot of web browsers on mobile devices are <em>abominably slow</em>. In terms of getting the first page of your app/site up and running on a mobile browser, an HTML page rendered on the server is going to beat a client-side JS application hands down in at least 90% of cases.</p>

<p>After that first page has rendered, the comparison is different. A server-rendered site/app with full-page reloads is (probably) going to have to do more round-tripping, re-parsing and rendering, whereas a client-side app that has bootstrapped itself might only need to load up small chunks of data and refresh parts of the page. But remember that mobile devices are often tight on working memory, and even switching between tabs (let alone switching between apps) can be enough to kick your app out of memory, so that it has to bootstrap again when you switch back.</p>

<p>With IE6 and 7 effectively dead, the desktop doesn't really have this problem any more. Desktop browsers are now sufficiently fast and capable that the bootstrapping cost is tiny, and from an architectural point of view separating the front-end from the back-end API is the service-oriented way of doing things, which is to say the <em><a href="http://news.ycombinator.com/item?id=3101876">right</a></em> way.</p>

<p>(Then we still have to make our client-side apps <em>internally</em> resilient and service-oriented, so that one poorly performing component on the page doesn't crash the whole app. But. Baby steps.)</p>

<p>It irks me that mobile web development, which in many ways was running <em>ahead</em> of classic desktop web development (advanced CSS3 capabilities, lack of IE6, et al.) is now going to fall behind in this architectural shift. Instead of incapable legacy browsers (IE6,7), we're stuck with at least a couple of generations of poorly performing devices. The platform that is most suited to "app-like" web content is the one least capable of running the damn things.</p>

<p>Having said that, it's important to know your audience. In Western Europe, at least, turnover of mobile devices is high, and the shift away from Blackberries and Nokias towards iPhones and Androids is massive. As usual, "it depends."

<p>Secondly, there's the small matter of linkability and history management. If there is any part of your application that you want people to jump to directly, either as a bookmark for their own benefit, or as a link to hand out to others, it has to be have a URL. Using hash fragments for navigation may be a well-established pattern, but it's still a hack. So long as you're using hash fragments, that URL can <em>only</em> be run on the client. <code>pushState()</code> and <code>replaceState()</code> can fix this, but we're still a little while away from these methods being universally available (IE10).</li>

<li>And then, if I've been clicking around in the application, what happens when I press the back button? Does it take me to a previous state within the application, or does it take me out of the application altogether? I don't think that the field of front-end development has answered this question with a consistent set of patterns to meet (and reset) user expectations yet. Far too often I still hear, "er...don't use the back button because that'll break everything".</p>

<p>The back button doesn't reign as supreme as it used to, though; multi-tab browsers have seen to that. Running an app in a dedicated browser tab, and closing it when you're finished is a common option now. Adding a web app to your phone's home screen so that it can run without browser chrome is less common, but on the rise. Still, the back button is likely to still be in play in the vast majority of cases. If you're going to build an app, make sure that you have a plan to deal with it.</p>

<p>Of course, none of this applies to <em>document-oriented</em> web content. But the distinction between apps and documents is an entirely different discussion.</p>]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>Apple TV, Airplay, and the future of video</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/03/apple-tv-airplay-and-the-future-of-video.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2303</id>
    
	<published>2012-03-03T15:50:52Z</published>
	<updated>2012-04-15T18:11:23Z</updated>
    
	<summary>I didn&apos;t get the Apple TV for a long time; neither in the sense of &quot;buy&quot; nor &quot;understand&quot;. Certainly here in the Netherlands, where Apple didn&apos;t start selling video content through the iTunes Store until last year, it seemed entirely pointless. Even now in 2012 the selection of films on...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>I didn't <em>get</em> the Apple TV for a long time; neither in the sense of "buy" nor "understand". Certainly here in the Netherlands, where Apple didn't start selling video content through the iTunes Store until last year, it seemed entirely pointless. Even now in 2012 the selection of films on offer in the Dutch iTunes store is still anemic at best, and the Apple TV is a dubious proposition &mdash; <em>if</em> you think of it as the equivalent of the DVD player that sits below your TV.</p>

<p>But that's not what it's for.</p>

<p>My first glimpse of understanding came in November last year, when the keynote at <a href="http://www.minecraftwiki.net/wiki/MineCon">Minecon</a> was being streamed live across the internets. <a href="http://www.minecraft.net/">Minecraft</a> 1.0 was finally going to be released, and Alex and Fiona were super excited about it. We plugged my old laptop into our big-screen living room TV, and let the kids stay up late so we could all watch the big moment together. But while we were waiting, we watched a couple of videos on YouTube. And afterwards, we left the laptop plugged in for a few days, and the kids watched some more videos.</p>

<p>Turns out there is a place in our life for watching YouTube on the living room TV instead of just on our computer screens. But also: it reminded me of a long-dormant desire to rip all of my DVDs to hard disk and have them available through some kind of media centre interface. I had played around with using a Mac Mini as a media centre before, but there's something a bit naff about having a computer with a big whopping external hard disk plugged into your TV. Sure, it <em>works</em>, and it gives you all of the <em>power!</em> of a general purpose computer (web browser! games!); but it also gives you all of the downsides (software updates! manual configuration!). A <a href="http://www.codinghorror.com/blog/2008/04/building-your-own-home-theater-pc.html">home-built HTPC</a> may be a source of massive geek cred, but in the end it's just a hack.</p>

<p>That's where the Apple TV came in. It's a perfectly silent, tiny device that plugs into an HDMI socket, and provides a lovely interface for streaming video. It has a built-in YouTube "app"; no web browser required. I can rent and watch movies directly from the iTunes store. And best of all, I can use it to stream videos from a computer acting as a media centre &mdash; which means that the bulky <a href="http://en.wikipedia.org/wiki/Network-attached_storage">NAS</a> can be conveniently tucked away out of sight in my office. So I bought an Apple TV in December, and it's great. Mark Boulton gives a good overview of a similar setup (including his backup options) in his post <a href="http://www.markboulton.co.uk/journal/comments/backups-networks-and-a-digital-home">Backups, Networks and a Digital Home</a>. I haven't installed <a href="http://firecore.com/atvflash-black">aTV Flash</a> on ours, but I might in the future.</p>

<p>But although this setup is groovy, it's <em>still</em> not what the Apple TV is for.</p>

<p>All of these features are about <em>pulling</em> content to your TV. It assumes that the <em>TV</em> is the important thing, and everything else is a peripheral designed to serve it. It assumes that the living room is where you have your TV, and that's where you settle in for the evening to watch your shows. This is the paradigm that other consumer-level devices operate in: DVD players, cable TV set-top boxes, game consoles. They are all static boxes designed to complement your TV, and to maintain its supremacy as the core of your home entertainment setup.</p>

<p>The Apple TV <em>looks</em> like just another content box, but that's <em>camouflage</em>. It's actually is a secret weapon in disguise. Its purpose is to stand that home entertainment model on its head: to place <em>content</em> at the heart instead of the <em>screen</em>. This is where <em><a href="http://www.apple.com/itunes/airplay/">Airplay</a></em> comes in. Airplay is all about <em>pushing</em> your content (music, video) to a device (speakers, screen) from wherever you are and whatever you are using, rather than assuming that you are tied to a delivery mechanism (your hifi speakers, your living room TV) and want to pull content towards you.</p>

<p>The "aha!" moment for me came when my parents were visiting us a few weeks ago. We were talking about our trip to see the magician <a href="http://en.wikipedia.org/wiki/Hans_Klok">Hans Klok</a> in Carré last summer, and about magic in general. My dad pointed out that Hans Klok's wine bottles trick is a variation of <a href="http://www.youtube.com/watch?v=jaJTTkpq50g&amp;feature=player_detailpage#t=310s">Tommy Cooper's classic "bottle, glass" routine</a>. Of course, we fired up the Apple TV and went straight to YouTube to find a clip of it. Cool. My iPad was around as well, and while we were watching clips on the TV, we were also browsing YouTube on the iPad and looking up our other favourite acts. And then, rather than pulling up the next clip on the Apple TV, I used Airplay to <em>push</em> the video from my iPad up onto the TV.</p>

<p>This was the lighbulb moment.</p>

<p>The iPad is the device I'm using. It could just as easily be an iPhone, or my laptop. The TV happens to be nearby. The TV becomes a temporary extension of the device.</p>

<p>Another example: I have a friend round to visit. They want to show me their holiday photos, or a funny video of their cat. They could show me on the screen of their iPhone, or they could just <em>push</em> it up onto the big screen.</p>

<p>Or: I go round to a friend's house. I have a bunch of music on my iPhone. They have an Airport Express plugged into their hifi, and &mdash; boom &mdash; I can <em>push</em> my favourite song through their speakers rather than having to plug my phone in to the stereo. If they have an Apple TV box attached to their TV, we can watch any movie I have with me, without futzing about with HDMI cables and adapters, or cursing myself for forgetting to bring the DVD.</p>

<p>As more music and video gets stored in the cloud, this becomes an even more low-friction scenario. I won't even have to worry about putting music or video onto my iPad to take with me wherever I go, because it'll be accessible from anywhere with a wireless signal. As <a href="http://www.flexible-display.net/">flexible screen</a> technology develops, more and more ordinary <em>surfaces</em> will be transformed into displays. Maybe I'll be able to walk into a café with my iPod, and play a movie onto my table. Maybe I'll be able to play funny pictures onto your T-shirt.</p>

<p>You know, in the future, when Captain Jean-Luc Picard says "<a href="http://screen.ytmnd.com/">On screen!</a>", and some random ensign pushes the video from their console up onto the main viewing screen? <a href="http://www.apple.com/ipad/features/airplay.html">Airplay</a>.</p>

<p>This is also why I think Apple is <em>not</em> about to produce an actual consumer TV. (Although I may be proved wrong on this very soon.) With Airplay, they have relegated the TV to the status of a peripheral. A very expensive peripheral to be sure, but as Fred Wilson has pointed out, <a href="http://www.avc.com/a_vc/2011/12/cheap-willl-be-smart-expensive-will-be-dumb.html">cheap things will be smart, while expensive things will be dumb.</a> Apple likes smart things that you will upgrade every couple of years. A small, cheap Apple TV device that makes <em>any</em> big screen TV smart fits in that category; a 42-inch "smart" TV that will be obsolete in two years, but is too expensive to replace in that timeframe, doesn't. And any kind of Apple-branded TV definitely <em>would</em> be a high-end, premium, and expensive device.</p>

<p>Apple used to make speakers: remember the <a href="http://en.wikipedia.org/wiki/IPod_Hi-Fi">iPod Hi-Fi</a>? But they got out of that business. TVs and speakers don't matter any more. They're just surfaces through which we push our media. Smart, highly personal devices that <em>control</em> the TVs and speakers &mdash; that's where the real value lies.</p>
]]>
        
	
	
	
    </content>
</entry>

<entry>
	<title>How to turn off keyboard sounds on Android 3.2</title>
	<link rel="alternate" type="text/html" href="http://sunpig.com/martin/archives/2012/03/02/how-to-turn-off-keyboard-sounds-on-android-32.html" />	
	
	<id>tag:sunpig.com,2012:/martin//2.2302</id>
    
	<published>2012-03-02T08:34:25Z</published>
	<updated>2012-03-02T08:43:59Z</updated>
    
	<summary>It&apos;s not under Settings → Sound. Oh no. That would be far too easy. Go to Settings → Language &amp; Input → Configure input methods → Settings, and uncheck the Sound on keypress checkbox. Someone was thinking: &quot;You paid for these sounds. Why on earth would you want to turn...</summary>
	
	
    <author>
        <name>Martin</name>
        <uri>http://www.sunpig.com/martin/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://sunpig.com/martin/">
	
        <![CDATA[<p>It's not under <b>Settings</b> → <b>Sound</b>. Oh no. That would be far too easy.</p>

<p>Go to <b>Settings</b> → <b>Language & Input</b> → <b>Configure input methods</b> → <b>Settings</b>, and uncheck the <b>Sound on keypress</b> checkbox.</p>

<p>Someone was thinking: "You paid for these sounds. Why on earth would you want to turn them off?"</p>]]>
        
	
	
	
    </content>
</entry>

</feed>
