(Not) Obsessing over the iPhone

PPK of Quirksmode-fame it at it again, this time badmouthing iPhone-centric web development. A lot of people seem to take issue with his point of view, but aside from the (typically Dutch?) in-your-face bluntness, I do think he makes some very valid points. The web is about broad accessibility, about allowing as many people as possible to access your information/ application and the same should indeed be the case for mobile web development.
Sexy as a iPhone-UI mimicking webapp (based on e.g. iUI or JQTouch) might seem, it does have a number of important shortcomings:

  • it is sub-optimal for the web, even on iPhones, as the context is very different (e.g. in terms of responsiveness)
  • the iPhone-UI-approach does not make a lot of sense on non-iPhone high-end touch devices
  • it will probably not work on mid- and lower-end phones at all

So yes, web-developers should try to build mobile sites that render on as many devices/ browsers possible, as we do on the non-mobile web. Unless you’re willing to invest in several sites for different handsets, building for one specific device is a bad choice, however good the browser might be (and Safari Mobile indeed is great).
That’s why I decided to switch from the iPhone-centric WPTouch (which I installed only 3 months ago) to “WordPress Mobile Pack” for this blog. WMP offers great mobile functionality out of the box;

It includes a mobile switcher to select themes based on the type of user that is visiting the site, a selection of mobile themes, extra widgets, device adaptation and a mobile administration panel to allow users to edit the site or write new posts when out and about.

When running the MobiReady test to assess how “mobile-ready” my blog is, I get a great score of 4.35/5 (page size being the main remaining issue). So thanks for ranting PPK!

Enhanced privacy for embedded YouTube

While looking into the possibility to play embedded YouTube clips with html5’s video-element on this blog, I noticed Google added an ‘Enable privacy-enhanced mode‘ flag to the embed-options. This small tweak ensures that visitors who arrive on a page that has YouTube embedded, don’t immediately get tracking cookies stuffed down their throat. Unless they play the video or click through to youtube.com, that is.
Enabling the “enhanced privacy” option just changes the URL in the embed code from youtube.com to youtube-nocookie.com;

<object width="560" height="340"><param name="movie" value="http://www.youtube-nocookie.com/v/FuGJfVAgiTM&hl=en_US&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube-nocookie.com/v/FuGJfVAgiTM&hl=en_US&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>

The change has no impact whatsoever on the user experience, so I immediately tweaked the code of the Smart YouTube WordPress plugin on my server and I asked the developer to add the option to his plugin as well.
Yet another small step in the fight against Google’s omniscience!

AddToAny removed-from-here


Update 02-2015: the information below does not reflect the way AddToAny works now and as such only has historical value, read this comment by the developer for more info.
When looking at my blog’s performance in Google Webmaster Tools I saw Google complained of multiple dns-lookups. I knew about stats.wordpress.com, google-analytics.com (well, yeah …) and gravatar.com, but one domain in the list didn’t make sense to me at all; media6degrees.com, so I started to investigate a bit. Grepping the wordpress-, theme- and plugin-code on my server didn’t reveal anything, so I went into Firebug to see what was happening in javascript.
Apparently the AddToAny WordPress-plugin was initiating the call:
  1. add-to-any requests http://static.addtoany.com/menu/page.js (which is rather big but gzipped & cache-able)
  2. page.js in turn contains tracking (near the end of the file), by requesting an 1X1 pixel image at http://map.media6degrees.com/orbserv/hbpix?pixId=2869&curl=<encoded URL of page>
  3. media6degrees then sends the pixel and … sets multiple cookies in the process

And what’s media6degrees business you ask? Maybe they’re just providing the add-to-any author with statistics? Well, not exactly. This is what media6degrees writes on their website: “We deliver scalable custom audiences to major marketers by utilizing the online connections of their consumers.” So by using AddToAny, you’re providing media6degrees with data about your site’s visitors, which they can use to sell targeted communication to their customers.
If visitors of small-time blogs like mine would be the only ones affected by this, the damage would be limited. But AddToAny is also implemented on large local news-outlets such as deredactie.be or De Standaard Online and no doubt on some big international sites as well. Somehow I doubt those organizations know they’re feeding their visitors to media6degrees and I bet some of them would even strongly disagree.
I’m not happy about this, that much is clear. AddToAny offers great functionality, but:

  • it adds unneeded requests to my page, causing the page to finish loading later (dns-request + http-request)
  • it enrolls my site visitors in a targeted communication platform without anyone knowing (or agreeing)
  • none of this is communicated on the AddToAny website or on the AddToAny WordPress plugin page

I mailed the author about this earlier this week (when i didn’t even know about media6degrees tracking cookies yet), but got no feedback up until now and I logged an issue on the wordpress.org support forum as well. And I decided to pull the plug on AddToAny off course, replacing it with sociable, making my blog render yet another millisecond faster, while at the same time protecting my visitors from this sneaky behavioral tracking by AddToAny and media6degrees.

blog.futtta.be going mobile with WPtouch

blog.futtta.be goes mobileAfter reading how wordpress.com implemented not one but two mobile versions for all of their 4.5 million hosted blogs, I decided to install the same WPtouch-plugin on this very blog as well.
Installation and activation of a new plugin is very straightforward from within the wordpress admin-screens. In the case of WPtouch (and every other plugin that produces alternatives views of the same content on the same URL) however, there is a conflict with the WP super cache plugin which needs to be resolved by basically telling the cache-plugin to not handle request from browsers with “mobile” useragent-strings.
After that WP super cache config hack, your blog has a mobile section which you can tailor to your needs in the WPtouch config screen. These are some of the settings I changed:
  • removed categories and tags from the header (didn’t seem to work anyhow)
  • added most of my pages to the dropdown menu in the header
  • excluded my lifestream-digest posts from being displayed
  • removed author from and added excerpt to individual posts

If anyone visits this site with their mobile browser and stuff doesn’t work, your feedback is welcome!

HTML5 offline webapps vs Google Gears Localserver

Google Gears is a fantastic browser plugin; it allows a developer to create applications that run while offline, syncing with a server when online. Two great examples of the power of that mechanism are Gmail (both the “desktop browser” and the mobile Android-version) and Mindmeister (only while in trial, for paying Mindmeister-accounts after that period). The problem with Gears however is that it’s a plugin and not a lot of people have it installed: only Chrome-users have it by default. And that’s where HTML5 comes in; one of the areas where the new spec offers vast improvements over html4/xhtml is the ability to take webapps offline by allowing a developer to store files for offline usage and to write data to a local, browser-embedded database. Both Safari 4 and Firefox 3.5 support these features, so maybe HTML5 makes Gears already redundant in those browsers with more to come?
I haven’t gotten around to experimenting with offline databases yet, but I did already look into offline files. At first sight, Gears Localserver and HTML5 Offline Webapps indeed seem very similar; your html-page points to a manifest-file which contains a list of assets (pages, images, css, js, …) that the browser has to store for offline usage. Easy enough, no?
To get a better feel of how offlining in HTML5 works, I decided to try to write a simple WordPress plugin to replace its ‘Gears Turbo’-option. Turbo (which you can find in the Options-menu) essentially stores 1Mb of files locally, to speed up delivery of the WP-admin pages. To make a long story short; my plugin didn’t work. For starters, by default requests for non-local data are blocked, but it’s easy enough to unblock network access by adding “NETWORK:*” (with a newline before the wildcard) to the manifest. But more fundamentally; HTML5 Offline Webapps not only stores the files specified in the manifest-file, but also every html-page which points to the manifest (see my test here). There’s no way you can exclude those “master entries” from being stored. So if pages are stored, that means they have to be static and that all dynamic parts should be handled by javascript (fetching data using ajax and updating your page with it). And that, my friends, is clearly not a use-case that is applicable to WordPress admin-pages.
So HTML5 Offline Webapps is no drop-in solution to speed up delivery of dynamic pages, you’ll still need Gears to take care of that (or rely on old-fashioned carefully configured expiry- and cache-headers). But, as Google proves with the iPhone-version of Gmail, Offline Webapps combined with a HTML5 offline database can work miracles if you use it the correct way.

http://blog.futtta.be/2007/04/06/cache-header-magic-or-how-i-learned-to-love-http-response-headers/

WordPress 2.8 loves your proxy

Up until version 2.7.1, running WordPress on an intranet was a real pain in the ass. It connects to the outside world to look for updates, to check comments for spam (using Akismet) or to fetch RSS-feeds for widgets if you configured those on your blog, … But as you typically don’t have direct internet-access on an intranet and as there was no way of letting WordPress know about a proxy, your blog timed out while it was trying to fsockopen those external sites.
chet bakerBut that was yesterday, because the recently released WordPress 2.8 “Baker” (which is chock-full of new features) has support for internet-connections through a proxy, thanks to its great HTTP API. Don’t bother looking for it in the admin-screens, you’ll need to configure the proxy-settings in your wp-config.php.
Here’s what you’ll have to add (values are examples which you’ll have to replace with settings for your environment off course):

define('WP_PROXY_HOST', '192.168.22.1');
define('WP_PROXY_PORT', '9099');

If you need to authenticate to access the proxy you can add your credentials this way:

define('WP_PROXY_USERNAME', 'frank');
define('WP_PROXY_PASSWORD', 's3cr3t');

You can also exclude requests for specific hosts from going through the proxy:

define('WP_PROXY_BYPASS_HOSTS', 'localhost, blog2.corpintranet');

And finally you can block all outgoing requests by default and add domains to a whitelist to only allow those to connect:

define ('WP_HTTP_BLOCK_EXTERNAL', 'true');
define ('WP_ACCESSIBLE_HOSTS', 'api.wordpress.org, akismet.com');

Off course some WordPress-plugins do not use the HTTP API yet (e.g. Lifestream and wp-security-scan rely on Simplepie, which does not use the proxy-aware wp_remote_get-function), so you might have to be careful when installing plugins that need internet-access.

Put your WordPress-categories back in the tagcloud

When blogging, tags and/or categories allow you to classify your posts. The taxonomy you create that way, allows searchbots (and human readers) to better understand what the post is about and to find related posts.
category cloud widget config screenshotEver since the release of WordPress 2.3 (in sept. 2007), you can specify both categories and tags for your posts. More or less following the ideas put forward by Lorelle-on-WordPress, I use categories as the main classification-method (putting posts in a hierarchical, directory-like structure) and add one-off keywords as tags. The only disadvantage: as tags are one-offs, the default tagcloud-widget in WordPress generates a dense put useless heatmap.
If you’re in the same situation, you might benefit from this little WordPress-plugin I wrote (well, …copy/pasted, actually, 80% is code straight from the original WP-tagcloud widget) to solve my tagcloud-woes. Once unzipped in your plugins-folder, “category cloud” will provide you with a widget which can not only generate a “tagcloud” or a “catcloud”, but also a “cat-and-tagcloud”. And because the default “general”-category might skew your catcloud-results or because you might prefer to have that NSFW-tag not show up, you can exclude tags and categories from being shown as well by entering their ID in the appropriate input box.

“Lifestreaming, across my universe”

Lifestreaming is where it’s at, so here I am, aggregating all my stuff (Google Reader shared items, my Youtube clips and favorites, my Facebook status and my blogposts) into one place. I tried sweetcron a couple of weeks ago, but for some reason it didn’t feel “ready” yet (or maybe I didn’t want to invest to heavily in it). I recently installed a simple WordPress plugin which seems to be doing the trick very well. Sweet indeed!
Next up; something to handle multi-language blogging a bit better, but now for something completely different (The Firm, Star Trekkin’ on Youtube);

The Firm - Star Trekkin'

WordPress 2.6 svn-upgrade; ouch!

WordPress 2.6 has been pushed out the door at Automattic and it contains some exiting new goodies as usual. So I fired up my trusty upgrade script, but got an ugly php-error when accessing the database update-pages:

Parse error: syntax error, unexpected T_SL in wp-includes/widgets.php on line 464

Turns out that the wp_widget_search-function in wp-includes/widgets.php included some remnants of an SVN-merge. Don’t know if it was a sync problem at my side or if the faulty code was on the SVN-server (it isn’t now), but I ended up copy/pasting the correct function from a fresh tar-ball I downloaded.