Martin Beeby, a developer evangelist over at Microsoft, posted
a blog about how responsive web design is the solution to
developing rich web experiences across a multitude of platforms,
and how designers are probably thinking about "just" desktop
(browser) and mobile (cellphone), and need to think more in terms
of other devices - iPads, interactive TVs, and so on.
He mentions three staples that Ethan Marcotte (the guy who
coined the term "responsive design") wrote
about in his book, coincidentally titled "Responsive Web
Design" (ingenuitive, huh?). Of those three, one is media queries -
the @media directive that's
been around in CSS2, but has only now been started to touted as
"CSS3" in recent years, with improved browser support for window
Now, I find @media queries useful and great when you're building
CSS to target multiple devices - it allows you to set out base
styles that enforce brand consistency across your design, and then
simply adjust positioning for various devices - I get the concept,
and I think it's a great idea. However, there's a big caveat about
@media queries which gives me a particularly large cause for
I run a business which deals with a lot of small customers - and
having patched Umbraco to work in cheap hosting, I recognise the
commercial aspects of people being on a very tight
budget - I was there, after all, it's what prompted my
However, throughout the design and build process of a website,
there needs to be consideration for this very simple fact -
bandwidth is fast becoming expensive and a limited
I recently quit Vodafone because they removed my 5GB data
bolt-on without telling me, and then all they offered as a
replacement was a 2GB one (3GB if you have an iPad). Most domestic
broadband providers cap usage, or have a "fair use" policy which
constrains to an average of 40GB - when I Google'd, only four
companies had truly "unlimited" packages (and some
of these are also documented to use traffic filtering at peak
periods - Virgin's XXL Package, for example).
The average page size of Alexa's top 500, as of May '11, is fast
approaching 700kb, and the one bit that people who tout @media
as the answer to everything don't tell you is: your entire
stylesheet, with resources, images, the works - for
all viewports - is loaded, before the @media
stuff is parsed by the browser.
Yes, you read correctly - everything gets loaded,
regardless of the device you're looking at a page on, prior to
@media being parsed by the browser. This means if you're on a
mobile device which should be served up maybe 50kb of page and
image, you'll get all 700kb of the desktop page too. Conversely, if
you're on a desktop, you'll get 50kb of unnecessary mobile stuff
downloaded for no good reason. Let's quickly work out how this
These figures don't take into account caching, which the link
above notes cuts back on average response sizes of the top 500 home
pages from >500kb to <100kb - an 80+% saving. However,
cellphone and portable devices, whilst improving, are notorious for
having pretty crappy memory capabilities, and caching takes time to
implement in a robust policy (since I build on Umbraco, I of course am biased
to recommend using the included ClientDependency
library, originally built by Aaron Powell at Redify and Shannon Deminick at Umbraco HQ,
both formerly of TheFARM Digital in
The main issue here is that on your mobile, if you're browsing a
site that uses responsive desgn to handle multiple devices, you're
wasting in excess of 80%, maybe even 90% of your visitor's
bandwidth just for them to view your site. For desktop
viewers, it's more like 10% - but still nothing short of bad
practice. Bandwidth is money - both for your customer, and for
whoever's hosting the site.
I personally built the new Kingsmill Bread website
before Christmas for CMW London, with two sites - one for full desktop and iPads,
and one specifically for
cellphones (if you're on a cellphone, tough luck, we do
user-agent checking to redirect you to the mobile one
automatically. Sorry!). If they want to expand that out in
future to support TVs, tablets and netbooks specifically, great -
we know that the site is fully performance-optimised for each
platform already to save them and their visitors money on
Responsive design has a place, but it's by no means a
one-size-fits-all solution. Remember that in an
ever-increasingly-connected world, bytes are money, and it's your
responsibility to save them to deliver value-for-money in your
XSLT is fantastic for simple data structure queries - like WHERE
and ORDER BY clauses. But what about the XSLT equivalent of
Fortunately, there's a great answer to that - <xsl:key
Why would you want to use it? Well, I've been working on
Blog4Umbraco a lot lately, and I've implemented custom
datefoldering strategies. Now, that's great for flexibility on SEO
and human-readable URLs, but if I don't have date folders set up,
then the Blog Archive and Full Archive macros break, cause they
rely on the unique nature of datefoldering to work - by iterating
over the year folder in yyyy format, then month in mm format, then
date in dd format, then the posts themselves - four levels of
I would be using the Exslt.ExsltSets:distinct function to retrieve
all postDate values of all grandchildren, were it not broken with a
nice YSOD stacktrace in Umbraco 4.5.2.
So the question is: how do we retrieve every post, and then tell
XSLT only to iterate over the *unique* values, without resorting to
.NET? Answer: <xsl:key />.
The <xsl:key /> element is designed to generate unique IDs
in-memory for matching nodes based on their properties.
In this instance I used:
(P.S. main reason for using (@isDoc or name()='node') is
compatibility between Umbraco < 4.0 and 4.5+ schemas - it'll
work with both!)
So now I have a key called "ym", which will be created for every
Umbraco content node, where the key's value for that node will be
calculated from the use attribute.
This now means that I can do:
This does a few things:
If it matches, great, we render results.
Hope this is useful!
As a lot of you know, I've been busy refactoring
Blog4Umbraco over the last few weeks and
months, trying to drastically improve it's fortunes to support lots
of new features.
One of the things that has bugged me is that Akismet, the included comment spam
protection service, is only licensed for non-commercial usage, and
if you want to run a "commercial" blog (however you want to define
that), then you have to pay them some money. Now, that's all well
and good, but as a true Socialist (I vote
Lib Dem, for anyone who wants to know) I believe that certain
basics in life should either be free or be at substantially reduced
cost - healthcare, education, anti-virus
CMS software... OK mostly software. I think spam-fighting kit,
with 87% of the Internet's traffic being made up of spam in one
form or another, is now a basic essential, and the right of every
good Internet citizen to possess at the very least basic security
to guard against it.
Anyway, I've found Akismet's "commercial" clause a little wooly in
the past, as a site that isn't e-commerce, nor has adverts, may
still be run by a company (hey, we're putting a blog on the new
Code Gecko site), and therefore is techncially "commercial" in
nature. Where does one draw the line? Answer: by making it free -
as in both free speech and free beer.
So on this note, I decided to hunt out some free blog comment
spam systems that would gladly allow commercial use, and found two
of particular note:
Now, both of these are lovely, but there's no .NET wrappers for
either of them. And as Scott
Hanselman and Linus
Torvalds say, "talk is cheap, show me the code".
Akismet wrapper for TypePad AntiSpam
The BlogSpam.net API wrapper is MIT-licensed, as is pretty much all my
Joel.Net's Akismet wrapper is 3-clause-BSD-licensed, so I can't
take credit for anything except one line of code which changes the API URL from api.akismet.com to
api.antispam.typepad.com - look Ma, no hands.
I gladly released this on March 14th - aka International Pi Day
(3/14... *groan*), and the birthday of Albert
Einstein (14/3/1879, 132nd anniversary), Quincy Jones Jr. and Sir
Michael Caine (both 14/3/1933, aged 78), Jerry Greenfield of Ben
& Jerry's (14/3/1951, aged 60), and yours truly (14/3/1987,
Happy birthday to me, and enjoy!
Sometimes the best answers are the simplest.
Umbraco has two really useful little fields - "Publish at" and
"Unpublish at" - that are properties for every node. They're used
for automatically pushing content into (or out of, respectively)
Umbraco's XML cache, in /App_Data/umbraco.config.
However, these properties, unlike a node's created and
last-updated dates (/<node>/@createDate and
/<node>/@updateDate with XSLT), are not stored in the XML
cache itself. So if you want to leverage it with XSLT, you have to
resort to writing two very simple helper methods like so:
The publish and unpublish dates will
automatically clear themselves after the publish/unpublish event is
raised accordingly. So this could be useful for a countdown, say,
"x days until competition opens/closes" or whatever, but not
advised for general usage.
Hope it helps!
It's been a while since I've blogged so I've drafted out about 5
posts to put up over the next two weeks which cover everything I've
been doing for the last month - it's a lot, trust me.
First - I picked up a new domain, benjaminhowarth.co.uk (which
is just a redirect to here). Many thanks to the staff at Nominet
for helping me to rightfully obtain my domain from
an unscrupulous entity which shall remain nameless.
Second - once I obtained this domain name, I wanted to use my
own control panel to manage the domain's DNS, and not the
horrendous mix of CPs that I am forced to use as a result of
picking a cheap hosting provider. Sometimes I do think Rackspace
are worth the money for support (no, I'm not with them... but at
this rate, I might be very soon!).
So I started using this CP and looking at how it manages the
DNS, and I thought I could probably do a better job - I mean, how
hard can it be to write a CP that will manage hosting and disk
allocation, along with plugging directly into IIS to set up various
websites and binding them to host headers which have DNS settings
stored in Microsoft DNS?
How naive I can be sometimes.
But during this long and arduous thought process, I did discover
this little gem over at MSDN, which covers all the basics of
how to query and manipulate DNS via WMI (using the dnsapi.dll
library on Windows servers from 2000 and onwards). So I'm currently
building (along with a massive myriad of side projects) a control
Next week, I'll post up my first PHP site - done in Wordpress as
part of the firm I work for, for a reputable financial consultancy.
The site was done in Wordpress due to external restrictions on
hosting (of course, I would've done it in DNN... although I have
started looking at Umbraco more, due to it's XSLT-based templating
system), and is due to go live next week with any luck. It's
reminded me of the good-ol'-days of classic ASP and interpreted
languages... the joys...
I'll also talk about a few .NET class library problems I've had
- we have a library with a hand-written data access layer and
extending the functionality is... interesting... to say the least!
(It took me two months to add new methods and add properties which
were then successfully populated from the underling database, due
to the fact that the class library has a bunch of interdependent
interfaces for every object in the product
framework.) I've since discovered SubSonic, what looks to be a
great code-generation tool for building data access layers
on-the-fly. I was reviewing IronSpeed Designer but because it deals
with data-driven apps (think bespoke CRM/ERP systems) I figured I
would just look for DAL-generation and roll-my-own interfaces,
rather than roll-my-own DALs and pray to God that everything
Further updates on client work - I have 3 new DNN sites going
live before the end of February which will all end up on my
I will also be re-skinning this site at some stage - I love the
skin but I have better uses for it and need to make some aesthetic
tweaks before I move it to a new site, which might just be my first
delve into Umbraco.
© 2010 Benjamin Howarth, Code Gecko. All rights reserved.
Powered by the friendliest CMS in the world, Umbraco, and Umbraco lizards at Code Gecko