Archive for tag: umbraco

Responsive web design: a response

Earlier today, 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 size detection.

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 concern.

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 patches.
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 resource.

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 breaks down:

  1. Mobile with 2GB data bolt-on - means you can browse approximately 2000 ~700kb pages before you cap out at your limit. That's less than ten a day for a month. Add in the fact that if you own a Smartphone, you can kiss goodbye to several MB a day if you have Twitter, Facebook, Foursquare, etc. all hooked up and running in the background.
  2. Home broadband package with 40GB allowance (which is the top end of most broadband companies, with exceptions already noted): you can browse ~60,000 pages a month, or ~200 a day. It is a drastic improvement by 20-fold, but homes now normally have more than one PC, and if your kids are Youtubing, or you're using something like BBC iPlayer/ITV Player/4OD, then you're going to cut into that limit pretty quickly.

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 Oz).

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 bandwidth.

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 solutions.

The <xsl:key /> element (and why it rocks)

XSLT is fantastic for simple data structure queries - like WHERE and ORDER BY clauses. But what about the XSLT equivalent of DISTINCT?

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 nested for-each's.
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:

XML, using GeSHi 1.0.8.8
<xsl:key name="ym"
match="*[(@isDoc or name()='node') and BlogLibrary:IsType('BlogPost', @id)]"
use="umbraco.library:FormatDateTime(./postDate, 'MMMM yyyy')" />
Parsed in 0.001 seconds at 219.43 KB/s

(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:

XML, using GeSHi 1.0.8.8
<xsl:if test="generate-id()=generate-id(key('ym',umbraco.library:FormatDateTime(./postDate, 'MMMM yyyy')))">
...
</xsl:if>
Parsed in 0.001 seconds at 145.70 KB/s

This does a few things:

  1. Calls generate-id() for the given node, which creates an ID;
  2. Calls generate-id() for any node where the "ym" key matches the given expression - in this case, passing in the current node's postDate for evaluation;
  3. Returns true if the two IDs match.

If it matches, great, we render results.

Hope this is useful!

Happy birthday to me... bye-bye spam

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 software, operating systems, 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:

  • BlogSpam.net - a nice open-source option, with a hosted service for those who don't want to run their own service, written by Steve Kemp. I reckon this'd be ideal for high-traffic sites, cause it gives you the option of running your own, which you can then performance-tweak as and when you want.
    • Pros - no API keys;
    • Cons - few .NET wrappers (see below).
  • TypePad AntiSpam by the guys from Six Apart. These are the same guys that introduced the concept of TrackBacks, letting bloggers "ping" each other instead of just pinging blog aggregate services - an implementation of this is coming in Blog4Umbraco v3. Their implementation is great cause it's the identical API to Akismet, but with the "commercial use allowed" clause - great.
    • Pros - Can use Joel.Net's Akismet API library with a simple modification;
    • Cons - said library requires recompilation, it's a hosted service, and requires API keys.

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".

BlogSpam.net API wrapper

Joel.Net's Akismet wrapper for TypePad AntiSpam

The BlogSpam.net API wrapper is MIT-licensed, as is pretty much all my open-source stuff.
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, aged 24).

Happy birthday to me, and enjoy!

Publish and unpublish dates in Umbraco

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:

C#, using GeSHi 1.0.8.8
public static string ReleaseDate(int nodeId) {
Document d = new Document(nodeId);
return d.ReleaseDate.ToString ();
}
public static string ExpireDate(int nodeId) {
Document d = new Document(nodeId);
return d.ExpireDate.ToString ();
}
Parsed in 0.009 seconds at 26.45 KB/s

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!

Domains and programming

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 panel!

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 works!

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 portfolio page.
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.