API First

Recently, we were faced with the task of writing an API-first web application in order to support future mobile platform development. Here’s a summary of the project from the point of view of one of the developers.

Agile API

For the first couple of iterations, we had problems demonstrating the project progress to the customer at the end of iteration meetings. The customer on this project was extremely understanding and reasonably tech-savvy but despite that, he remained uninterested in the progress of the API and became quite concerned by the lack of UI progress. Although we were busy writing and testing the API code sitting just beneath the surface, letting the customer watch our test suite run would have achieved nothing. It was frustrating to find that, when there was nothing for the customer to click around on, we couldn’t get the level of engagement and collaboration we would typically achieve. In the end, we had to rely on the wireframes from the design process which the customer had signed off on to inform our technical decisions and, to allay the customer’s fears, we ended up throwing together some user interfaces which lacked any functionality purely to give the illusion of progress.

On the plus side, once we had written enough of our API to know that it was fit for purpose, development on the front-end began and progressed very rapidly; most of the back-end validation was already in place, end-points were well defined, and the comprehensive integration tests we’d written served as a decent how-to-use manual for our API.

Extra Work

Developing the application API-first took more work and more lines of code than it would have required if implemented as a typical post-back website.

Each interface had to be judged by its general usefulness rather than by its suitability for one particular bit of functionality alluded to by our wireframes or specification. Any view that called upon a complex or esoteric query had to instead be implemented using querystring filters or a peculiar non-generic endpoint.

In a typical postback project with private, application-specific endpoints, we’d be able to pick and choose the HTTP verbs relevant to the template we’re implementing however our generic API required considerably more thought. For each resource and collection, we had to carefully think about the permissions structure for each HTTP method, and the various circumstances in which the endpoint might be used.

We wrote around 4000 lines of integration test code just to pin down the huge combination of HTTP methods and user permissions however I sincerely doubt that all of those combinations are required by the web application. Had we not put in the extra effort however, we’d have risked making our API too restrictive to future potential consumers.

In terms of future maintainability, I’d say that each new generic endpoint will require a comparable amount of otherwise-unnecessary consideration and testing of permissions and HTTP methods.

Decoupling

Having such an explicitly documented split between the front and back end was actually very beneficial. The front end and back-end were developed and tested based on the API we’d designed and documented. For over a month, I worked solely on the back-end and my colleague worked solely on the front and we found this division of labour was an incredibly efficient way to work. By adhering to the HTTP 1.1 specification, using the full range of available HTTP verbs and response codes, and to our endpoint specification, we required far less interpersonal coordination than would typically be the case.

Beyond CRUD

The two major issues we found with generic CRUD endpoints were (1) when we needed to perform a complex data query, and (2) update multiple resources in a single transaction.

To a certain extent we managed to solve the first problem using querystrings, with keys representing fields on the resource. For all other cases, and also to solve the second problem, we used an underused yet still perfectly valid REST resource archetype: the controller, used to model a procedural concept.

We used controller endpoints on a number of occasions to accommodate things like /invitations/3/accept (“accept” represents the controller) which would update the invitation instance and other related user instances, as well as sending email notifications.

Where we needed to support searching, we added procedures to collections, of the form /applicants/search, to which we returned members of the collection (in this example “applicants”) which passed a case-insensitive containment test based on the given key.

Conclusion

API-first required extra implementation effort and a carefully-considered design. We found it was far easier and more efficient to implement as a generic, decoupled back-end component than in the typical creation process (model -> unit test -> url -> view -> template -> integration test), with the front-end being created completely independently.

In the end, we wrote more lines of code and far more lines of integration tests. The need to stringently adhere to the HTTP specification for our public API really drove home the benefits to using methods and status codes.

In case you’re curious, we used Marionette to build the front-end, and Django REST Framework to build the back end.

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

Hold the hamburger

Hamburger iconI’ve noticed a worrying trend in web navigation lately. More and more websites are hiding their navigation – at desktop resolutions – under a single button, often the 3-bar “hamburger” icon.

They are doing this because it makes the website look “clean” – simple and uncluttered. Who wouldn’t want that? Or perhaps they are following the lead of some powerful role models, such as Google, or Medium. Or they are influenced by design for mobile devices, where small screens often require navigation to be hidden initially, and the hamburger icon has become ubiquitous. But they are usually wrong.

Hyperisland, Xoxo festival and Squarespace all hide their navigation under an icon even at desktop resolutions.

Hyperisland, XOXO festival and Squarespace are just 3 examples of sites that hide their navigation under an icon even at desktop resolutions.

Just a quick recap of the purposes1 of navigation menus on websites:

  1. It tells you what’s here and what you can do
  2. It gets you to where you want to go
  3. It tells you where you are

Hiding the navigation under an icon does a slightly worse job at no.2 (one extra click), but a terrible job at nos.1 and 3. And a clean-looking design does not compensate for this loss, for most websites at least.

So when is it OK to hide the navigation under an icon?

Well, I’ve already mentioned devices with small screens, where there simply is no room to spare for a menu. Responsive web design (RWD) is often used to transform the navigation menu into an icon at small screen sizes, like the popular Bootstrap framework. This is an ergonomic, not aesthetic decision.

The other case where hiding the navigation is understandable is on sites where random browsing is the dominant navigation pattern. This can describe journalism sites such as Medium, Upworthy, blogs in general, or social networks like Google+, Pinterest, Instagram, etc. These are sites where you typically don’t start at the homepage, and you typically navigate via related content. They may have navigation behind the scenes (such as content categories or account tools) but these are not needed in the vast majority of user journeys.

For most other websites and web applications, where users need to be guided to the information or tool they need with as little fuss as possible, visible navigation menus or toolbars are necessary2.

Yes, it’s easier for a designer to make a site without navigation menus look attractive, at first glance. But as any UX expert knows, visual simplicity does not necessarily equal ease of use. The best website designs are those that look beautiful while also providing the information and tools most users need. You do not solve a design problem by sweeping it under the carpet.

Hold the mystery meat, too

Which brings me to another form of the same problem – sweeping “surplus” navigation underneath a cryptic icon like the hamburger or “…” Software developers have known for decades that menu labels like “Other”, “Misc” or “More” are design failures – yet somehow giving them a trendy icon has given this form of mystery meat navigation new respectability. Google is a prime offender. Submenus are OK when the label clearly suggests what’s inside, such as the now-ubiquitous Account menu (or just avatar) at the top right. If not, it may as well be labeled “Stuff”.

Google has become an arch-offender in making invisible navigation seem respectable again. Even on wide screens with plenty of real estate, Gmail hides commonly-used functions under cryptic menus. (1) I curse every time I have to click here to go to Contacts. Without looking, I challenge you to guess what's in the "More" menu. (3) What would you find in here? (4) Or here?

Google has become a chief offender in making invisible navigation seem respectable again. Even on wide screens with plenty of real estate, Gmail hides commonly-used functions under cryptic menus. (1) I curse every time I have to click here to go to Contacts. (2) Without looking, I challenge you to guess what’s in the “More” menu. (3) What would you find in here? (4) Or here?

Flickr’s May 2013 redesign swept most of the user-related navigation under the obscure ellipsis icon, which may seem neater to anyone who doesn’t actually use the site, but is a major, on-going frustration to regular users.

Flickr’s May 2013 redesign (bottom) swept most of the user-related navigation under the obscure ellipsis icon, which may seem neater to anyone who doesn’t actually use the site, but is a major, on-going frustration to regular users.

[Update 10 Feb: Killing Off the Global Navigation: One Trend to Avoid by the Nielsen Norman Group makes much the same argument, but provides more background, examples and suggestions. Their article correctly targets any single menu item hiding the global navigation inside a drop-down menu, rather than hiding it under an icon as I focused on. They point to online retailers starting the trend, possibly copying Amazon. They suggest using click tracking, observation and analytics to decide whether it makes sense to hide your global navigation, and what impact it's having.]


(1) Those who’ve read Steve Krug’s 2001 classic Don’t Make Me Think may recall his slightly different list of the purposes of navigation:

  • It gives us something to hold on to.
  • It tells us what’s here.
  • It tells us how to use the site.
  • It gives us confidence in the people who build it.

(2) Search can help, but most usability studies show that Search is typically only used after navigation has already failed and should not be considered a replacement for navigation. Search on the vast majority of websites falls far, far short of Google’s magic.

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

Backbone history and IE9

This bit me the other day, so I thought I’d share the pain.

IE9 doesn’t support pushState as you probably know which meant everything was routing to root (as it were).

The following snippet checks and resorts to hash based routing if it can’t cut the mustard:

app.on('initialize:after', function() {
    if(Backbone.history && !Backbone.History.started) {
        if(!(window.history && history.pushState)) {
            Backbone.history.start({ pushState: false, silent: true });
            var fragment = window.location.pathname.substr(
                Backbone.history.options.root.length);
            Backbone.history.navigate(fragment, { trigger: true });
        }
        else {
            Backbone.history.start({ pushState: true });
        }
    }
});

Add it wherever you would initialize Backbone history – often the entry point of the app. Mine for instance has an app.js that is initialised by main.js

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

Content types and Django CMS

Screenshot of the new ENB website

The new ENB website

One of our latest projects to go live is a new website for the English National Ballet. Part of a major rebrand, we completely replaced their old PHP site with a new content-managed site powered by Django CMS.

Django CMS is very flexible, largely due to its minimalistic approach. It provides no page templates out of the box, so you can construct your HTML from the ground up. This is great if you want to make a CMS with a really strong design, because there is very little interference from the framework. However, its minimalistic approach also means that you sometimes have to write extra code to tie all the content together.

A good example of this is content types. In Django CMS, there is only one content type: Page. It has certain fields associated with it e.g. title, slug, published. Any other information that appears on a page comes courtesy of plugins. The default Django CMS plugins give you everything you need to add arbitrary text, images and video to a page. But what if you want more fields for your page? Let’s say, for example, you are representing a ballet production and you want category, thumbnail and summary text fields, which don’t appear on the page itself but are needed for listings elsewhere on the site?

We decided to create a special “metadata” plugin to be added to the production pages, that would only be visible to content editors and not end users. This was seen as the best solution that achieved our goal while maintaining a decent user experience for the editors.

The plugin model looks something like this:

1
2
3
4
class ProductionDetails(CMSPlugin):
    summary = models.CharField(max_length=200) # Short summary, shown in listings
    image = FilerImageField() # Thumbnail image, shown in listings
    audiences = models.ManyToManyField(Audience) # Categorisation

Note the use of django-filer for the image field. This is simply the best add-on I have encountered for dealing with image uploads and the inevitable cropping and resizing of said images. You can also use cmsplugin-filer (by the same author) to replace the standard image plugin that comes with Django CMS.

Now querying the database for, say, the first 10 productions for a family audience (audience id 3) is as simple as:

ProductionDetails.objects.filter(audiences=3, placeholder__page__published=True)[:10]

So now we have a plugin model that we can query, and we don’t need a template as we don’t want it to appear on the actual page, right? Wrong. We still want to provide a good user experience for the editors, and this includes looking at a page in edit mode and being able to tell whether the page already has the plugin or not. So we use request.toolbar.edit_mode in the template to decide whether to render the plugin:

1
2
3
4
5
6
7
8
9
{% load thumbnail %}
 
{% if request.toolbar.edit_mode %}
<div id="production-details">
 <img src="{% thumbnail instance.image 100x100 crop upscale subject_location=instance.image.subject_location %}" />
 <p>Summary: {{ instance.summary }}</p>
 <p>Audiences: {{ instance.audiences.all|join:', ' }}</p>
</div>
{% endif %}

Now this information will only appear if an editor has activated the inline editing mode while looking at the page. If they look at the page and the information is missing, they know they need to add the plugin!

This solution works quite well for us, although it is still fairly easy to create a page and forget to give it any metadata. Ideally it would be mandatory to add a metadata plugin. Perhaps the subject of a future blog post!

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

Polite user interfaces know when to wait a little

Web page elements that appear or disappear on hover should almost always do so with a slight delay. Why?

  • To prevent distracting elements leaping out at you while your mouse is simply traversing the page.
  • To prevent you from accidentally clicking something that popped into view just as you were moving your cursor towards the target.
  • To prevent elements such as menus from unexpectedly disappearing when you just stray a pixel off, forcing you to re-invoke them.

Building in a small delay (say, 100ms) before elements appear or disappear is a hallmark of polite user interfaces, but is woefully rare. If you do a Google search for JavaScript plugins for menus, dropdowns, etc., you’ll find almost none that do this. This is also the biggest problem I have with using CSS :hover to show or hide elements (and why I think pure CSS dropdown menus are useless.)

On pretty much all projects with interactive JavaScript elements I’ve worked on in the past, I’ve specified this behaviour, which added considerable complexity for the developer. In most cases, they developed their solution from scratch.

So I was very happy to discover Brian Cherne’s hoverIntent jQuery plugin, a lightweight (4KB unminified) script which makes this effortless to do:

HoverIntent is similar to jQuery’s hover. However, instead of calling onMouseOver and onMouseOut functions immediately, this plugin tracks the user’s mouse onMouseOver and waits until it slows down before calling the onMouseOver function… and it will only call the onMouseOut function after an onMouseOver is called.

Please consider using it on your next project!

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

Running a Django (or any other) dev instance over HTTPS

Being able to run your dev instance over HTTPS is really useful: you might spot some weird bug that would have bitten you in production, and if you do find one, you can debug it much more easily. Googling for this subject resulted in several different tutorials using stunnel, but all of them broke in some way on my machine running Ubuntu Maverick. So here is how I got stunnel working – perhaps it will help someone else too:

sudo aptitude install stunnel
sudo su -
cd /etc
mkdir stunnel
cd stunnel
openssl req -new -x509 -days 365 -nodes -out stunnel.pem -keyout stunnel.pem
openssl gendh 2048 >> stunnel.pem
chmod 600 stunnel.pem
logout
cd

Now create a file called dev_https with the following text:

pid=
foreground=yes
debug = 7

[https]
accept=8443
connect=8000
TIMEOUTclose=1

Note: this assumes your web server is running on port 8000. If it’s not, change the value of “connect” to the appropriate port.

Finally, run:

sudo stunnel4 dev_https

Now if you go to https://localhost:8443/, you should see your HTTPS-enabled dev instance!

Note: To properly simulate a HTTPS connection in Django, you should also set an environment variable HTTPS=on. Without this, request.is_secure() will return False. You could set it at the same time as starting your dev instance e.g:

HTTPS=on python manage.py runserver

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

Photoshop guidelines for web designers

We often work with external design agencies. Sometimes they work with wireframes we produce, and sometimes not. These are my standard guidelines (or wishlist, if you will) that I try to send to designers before they start. I don’t think I’ve ever received any that meets all these criteria, but it’s always good to aim for. Perhaps it’ll be a useful checklist for other designers out there.

  1. Final deliverables are layered Photoshop files (.psd), with flat file snapshots of each.
  2. When providing flat files (incl. work-in-progress snapshots), use 24-bit PNG format (not JPG).
  3. Use separate files for each distinct layout template.
  4. Photoshop Layers should be given meaningful names. Multiple identically-named layers are unnacceptable. As far as possible, remove obsolete layers. Use layer groups to organise layers
  5. Photoshop Guides should be used, matching the page layout grid. Remove obsolete guides. Guides should be snapped to pixel edges Photoshop lets you position guides at sub-pixel level, which causes confusion when working with pixel-level artwork for screen-based media. To snap guides to pixel edges, first create a marquee selection in the right place, and then snap the guide against the marquee edge..
  6. Consistency between Photoshop files is required, regarding measurements, fonts and colours.
  7. Use a meaningful and consistent file naming policy. Related files should be named in such a way that they are alphabetically adjacent (e.g. content-normal.psd, content-wide.psd
  8. Versioning: for updated versions of files, use a consistent and sensible versioning system in the file names. E.g. homepage-v01.psd. Files with version numbers should stay in order when sorted A-Z. Avoid file name suffixes like -final.psd, -updated.psd, -new.psd etc.
  9. Bear in mind CSS capabilities and work with them wherever possible. For example, horizontal and vertical lines should follow pixel edges exactly (not anti-aliased) in order to be implemented as CSS borders.
  10. When drawing vector shapes, remember to check the “Snap to Pixels” box in the shape options.
  11. Remember to specify hover (mouseover) and active (on click) states for links and buttons.
  12. Accessibility: Minimum font size is 11px. Body text should ideally be 12px or 13px.
  13. Accessibility: Test for adequate colour contrast and colour blindness
  14. Text in Photoshop should be sized in px units (not pt), and in integer sizes (not fractions)
  15. Specify the actual leading in the Character palette, and, for multi-paragraph text areas, spaces above and below paragraphs in the Paragraph palette, that should be implemented using CSS. Do not use double linebreaks or font sizing to set paragraph spacing
  16. Use web fonts as far as possible (core web fonts or from a commercial web font service). Only use non-web fonts (e.g. corporate fonts) where absolutely necessary (they’ll be implemented using images). This is extra important for text that will be content-managed or translated.
  17. Embedded images such as logos should be production quality, as the Photoshop file will be used to cut out final images. (Tip: embed logos as ‘smart objects’, or avoid resizing them multiple times.)
  18. If working from wireframes, try to avoid a “wireframe aesthetic” (monochrome, everything in boxes). If a wireframe puts something in a box, it just means that information should visually stick together. Use gestalt principles to group information visually.
    Edit 3 Mar 2014: Good series on gestalt by Andy Rutledge: 1, 2, 3, 4, and 5.

Edit Feb 2014: Here are 2 excellent resources for designers producing website mockups in Photoshop:

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

HTML5 input type=number and decimals/floats in Chrome

As you may already know, HTML5 has introduced a number of new input types, one of which is the “number” type. As you might expect, this is a form field which accepts numeric input. So what happens in Chrome with the following HTML when we try to enter a decimal (floating point) number and submit the form?

<input type="number" />

Answer: Chrome pops up a validation error:

Decimal number failing validation

So what’s going on here? Is it a bug? It doesn’t fail in Firefox.

Well actually it’s not a bug; the form field is behaving as defined by the W3C. Numeric input fields can take additional attributes “min” and “step”, which constrain the range of values allowed in your input. The “min” attribute is fairly obvious: it’s the minimum value your number can be. The “step” attribute is less intuitive: by playing with different values, you would most likely work out that it controls the increase/decrease when clicking the up/down buttons on the field. If you input the number 1 and click the up arrow, it will increase to 2. This is because the default step is 1. So far, so obvious. However, the step attribute also determines which values are valid, so a step of 1 means you can enter 1, 2, 3 etc. and a step of 2 means you can enter 2, 4, 6 etc, and when you click the up/down buttons the number will increase/decrease by 2 each time, but entering 3 or 5 in the box will cause a validation error. You can also use a decimal value: for example, a step of 0.3 will allow values such as 0.3, 0.6, 0.9 etc, but not 1 or 2.

But what if you want all the numbers to be valid, integers and decimals alike? In this case, set step to “any”:

<input type="number" step="any" />

Now you don’t get a validation error. Yay! Also note that if you only want to accept positive numbers, you’ll want to add min=”0″.

So the lesson here is that the “step” attribute is linked to both the up/down buttons and the range of values allowed in the field. When step=”any”, the up/down buttons will increase/decrease the number by 1. As far as I can tell, there is no way to have step=”any” and an increase/decrease of more (or less) than 1 when clicking the up/down buttons. Feel free to enlighten me in the comments though!

About us: Isotoma is a bespoke software development company based in York and London specialising in web apps, mobile apps and product design. If you’d like to know more you can review our work or get in touch.

Content Strategy Forum writeup

On 5-6 September my colleague Stephen and I attended the second CS Forum in London.

“Content strategy” is the latest buzz-phrase gaining traction in our industry, joining usability, information architecture, interaction design, user experience, accessibility and the like. As with the others, there is a great deal of overlap, but it’s a term I think will endure, as it gets to the nub of the biggest unsolved problem in web projects.

Put simply, it’s that content remains the weak link in most projects. Online content sucks much of the time. There’s too much uninteresting content, not enough useful content, and responsibility for creating and improving it is diffuse. Poor content often exposes the most convincing information architecture and wireframes as a fantasy of wishful thinking.

Content strategy brings out the pessimist in me. There are many reasons why it’s such a hard problem:

  • Getting good quality content out of organisations that do not see themselves as publishers is like getting blood out of a stone.
  • Most content strategy problems are human – political, organisational – on the client side; those you (as external agency/consultant) are least equipped to solve, often going beyond your remit.
  • It’s always easier to make content strategy the client’s problem – you don’t want to accept responsibility for something that is so likely to go wrong.
  • Well-structured content is a Good Thing, but the better structured your data (both information architecture and content types), the worse problems you face when the structure is no longer fit for purpose, and editors try to get around the structure you’ve imposed.

Conference themes

The following themes occurred repeatedly during the conference:

  • We forget to consider the user experience of the content creators (usually in a CMS), in focusing on only the site users
  • Fragmented organisational structures, e.g. lack of communication between developers, designers, copywriters and client
  • Not knowing the CMS well enough, or choosing a CMS without consulting content creators
  • Not learning the lessons of separating content from presentation – content should be produced from a “create once, publish anywhere” approach
  • Lorem ipsum is a problem – it’s always better to design from the content out

The following are not so much summaries of all the talks I attended, as the most interesting things I took away from them. Some writeups are therefore much longer than others.

Gerry McGovern – Manage the tasks, not the content

Back in 2003, his books “Content Critical” and “The Web Content Style Guide” had a huge influence on me and helped guide the content strategy on Unilever.com, which I was working on at the time.

He reminded us that people go to website to do specific things on a website; any content that is not related to those essential tasks should be cut. He particularly dislikes marketing content. “Support is the new marketing”, he says, meaning that the “customer service” content should be the main focus of a site, rather than marketing content.

Avoid unhelpful navigational labels like “Articles” or “FAQs”, and link text should be written to make the keywords clear. (All principles familiar from information architecture best practices.)

Finally, Gerry made a plea for measuring content success, with the emphasis on useful metrics. Figures like visitor numbers, time on page, eye-tracking “fixation time” are all relatively useless – why do we assume that more = better? A/B testing yields more credible insights.

Melissa Rach – Content strategy methodology: a DIY project

Melissa talked about methodology – what strategists do – such as

  • Create clarity
  • Facilitate smart decisions
  • Align stakeholders
  • Help operationalize change

These steps have both content components and people components. But like many talks, it mainly deals with the what (none surprising), but not the how, which is where the the problems lie in my experience.

Margo Bloomstein – First things first: message matters

This talk recommended establishing a “message architecture” as a first step. Via card-sorting, help the client establish

  • Who we are
  • Who we’re not
  • Who we’d like to be

…and tell the story of those aspirations. The message architecture drives the copywriting, the user experience and design, and becomes the benchmark by which to evaluate success later.

This is valid advice, but not always within my remit, and also not really where the worst problems originate.

Karen McGrane – The way forward: what’s next for content strategy

This gets my vote for the best talk of the conference, as it homes in on all the biggest problem areas. You can watch it on Vimeo

Problems usually don’t lie in technology, but in company structure. She describes her role as “corporate therapy”. Companies suffer from fragmentation:

  • fragmented content management
  • fragmented organisation structures
  • fragmented devices and platforms

Content strategy – part of UX – should function as the bridge between marketing and technology. Content strategy is often about organisational change management.

Karen acknowledged to me in conversation afterwards that solutions to these problems are often out of your grasp and if she could do certain projects over again, she wouldn’t necessarily be able to prevent them.

The CMS – “the enterprise software that UX forgot” – is another major problem area. Why do we care more about the conversion funnel than the CMS workflow? Why do we care about the user experience of site visitors, but not editors? We need to work with the developers implementing the CMS from the beginning. And even before that, CMS procurement should be on the basis of usability – workflow that matches editors’ mental model – rather than feature checklists. A better CMS fosters better content.

As for the developing content for a fragmented landscape of devices and platforms, Karen compared the approaches of Condé Nast and NPR. Condé Nast’s strategy, by creating iPad apps for their magazines like Wired, is unsustainable. Ethan Marcotte: “Fragmenting content across ‘device-optimised’ experiences is a losing proposition” . By contrast, NPR pursued a “Create Once, Publish Anywhere” approach, by building an API that enables their content to be deployed in a multitude of contexts. This is why we need flexible, structured content, and why Ethan Resnick claimed “Metadata is the new art direction”.

These are all familiar principles to information architects, but as Karen said, Mobile is a great wedge to bring the argument up again.

Lisa Welchman – On All the Different “Web Governances” in the Universe

Governance refers to a policy and standards. Some key points:

  • A policy that no-one knows exists, or reads, doesn’t exist
  • Policy that you don’t have the authority to implement doesn’t make sense
  • Don’t be a barrier to organisational change that needs to take place (I suspect this is aimed more at insiders than consultants)

Lisa then introduced the recently-formed Web Governance Journal.

Eric Reiss – Content strategists: the men and women of a new renaissance

Eric summed up the big problem I have with content strategy: “Strategy is easy. The rest is tactics.” We often know what needs to be done, but making it happen is where the problems lie.

Erin Kissane – Making sense of the (new) new content landscape

Erin invoked the old IA favourite, Christopher Alexander, who in his treatises on architecture described enduring patterns such as balance, interconnection and stability, and fundamental user needs that products are useful, accessible, findable, searchable, portable and usable in many ways.

We need to preserve the life of our strategic decisions to enhance the life of our visitors.

Des Traynor – The language of software: the role of content strategy in software development

Des talked about websites (or web applications) with strong social elements or user-generated content. In such cases, there may not be much content to begin with, but what we do control, is

  • The user interface
  • The blank slate (what users start with)
  • The content definition

Thus “you get the content you deserve”.

  1. User interface: “Language influences behaviour”. Consider the ramifications of labeling decisions like “tweet” (not share, update, set, publish, post…) or “like” (not love, or appreciate…) E.g you can “+1” something where “like” isn’t appropriate. The Zune’s coolest feature, instant sharing via wifi, was arguably killed at birth by the term “squirt”.
  2. Blank slate: Consider the different quality of user-generated content on YouTube, Yahoo Answers, Quora, Get Satisfaction. By subtle elements in how they let you compose, the results can be idiotic or serious, disrespectful or civil. Google Wave undermined itself with unconvincing sample/seed content.
  3. Content definition: Compare the quality of TripAdvisor reviews with those on the Apple app store (where ratings don’t differentiate between e.g. technical problems or product suitability.)

Des showed an example of a “microcopy framework” for an application. This is a spreadsheet containing all messages in the application, and their aims and expected tone of voice.

Content is “always an opportunity to delight your user”. +1

Richard Ingram – How did we all get here?

Richard revealed the results of several surveys on professionals who consider themselves content strategists, in the form of gratuitous infographics :) which you can view here.

His blog’s title is a veiled entreatment to abandon Lorem Ipsum.

Martin Belam (guardian.co.uk) @currybet – Content strategy for people who think they already have one

As expected, another stand-out talk, but probably one of the least applicable to me. Journalistic organisations tend not to have the CS problems I find most intractable (they actually have qualified writers and editors), although they have different problems relating to the business model – extracting the greatest value from content – and publishing across a ever-fragmenting landscape.

The Guardian is also an ideal organisation in many respects – doing their development in-house with good collaboration between editors (a fascinating story of “domain driven design” in itself), IAs and developers, and using a custom-built CMS that dispenses with a lot of complex workflow in favour of trust. Having a controlled taxonomy of keywords with a single manager is also something that on most projects I can but dream of.

In keeping with one of the main themes of the conference, Martin stressed the benefits of an API approach to deal with platform fragmentation – create once, publish anywhere.

I liked Martin’s advice to teach using a “portfolio of errors” – showing the mistakes others have made before, rather than criticising your colleagues’ efforts.

Martin ended with a healthy reminder for all “content strategists” not to forget their Information Architecture, and the decade-plus of prior art. (The vast majority of the conference would have sat comfortably under an IA banner.)

Sophie Dennis @sophiedennis – How web designers can stop worrying and learn to love content strategy

I enjoyed Sophie’s talk, which grappled with the all-too-familiar problem their own agency website, which no-one likes but never gets fixed. 

Sophie pointed out that “lorem ipsum” dummy text is specifically intended not to be read, hence it results in designs that are simply not reader-friendly, where the text is the least important component of the design.

When we start designing with real content, we become better designers. However, this is usually not realistic. The pressure to design first typically comes from clients – “I’ll know what to write when I see it”.

In response, Sophie proposed an agile approach, where neither comes first. For their own agency site redesign, she turned off CSS on the existing site and, working with the HTML rather than wireframes, started rewriting – this made it easy for everyone to focus on the content. Then, it became easy to start adding style and “grow the brand out from there”.

Sophie is also a fan of spreadsheets instead of tree-diagram sitemaps, as they are much better at communicating scope. Sitemaps can give a misleading mental model of the amount of content on a site. Spreadsheets are also more accessible and collaborative.

Kate Kenyon @kate_kenyon – Content strategy and CMSs

Valuable reminders never to ignore the CMS. As the content strategist, you need to own it, and understand the publishing process. Find out where it fits in the technical ecosystem. Ideally, the CMS should be procured from the user requirements of the editors.

Good reminders for me. For a long time I intentionally ignored the CMS, believing that it was my duty to focus on the user experience and not be “captured” by the tech constituent.

Cleve Gibbons @cleveg – Strategist and executioner

We’re used to doing “customer journeys”, Cleve said, but we hardly ever do “author journeys”. Optimise the author journey, focus on making authors proficient and productive.

More exhortations to bring technologists to the table when content management is discussed. Developers shouldn’t just “take the ticket and implement” something; they should ask “Why?” more often – what’s the aim of the requirement?

(I agree, from painful experience – many well-intentioned features I designed turned out, after implementation, to result in such editor overhead in the CMS that the features went unused.)

Lisa Moore @writebyteuk – Agile and Content Strategy

Lisa espoused Agile principles such as “putting deliverables on a diet” – keeping documentation to a minimum (I agree), developing early, and testing often.

The team structure she described had separate content strategists and copywriters – she recommends that these people should be involved in all meetings with IAs and developers. However, in most of my projects these don’t exist as separate roles.

Lisa also recommended using real content as far as possible in wireframes – besides benefiting design, another advantage is that it’s likely to be included in user tests.

Noz Urbina @nozurbina – B2B content strategy

Noz made a compelling case for replacing the traditional marketing content with customer service content – i.e. the stuff you usually got after the sale is then driving the sale (echoing Gerry McGovern from earlier.)

B2B (as opposed to B2C) compels you to focus on customer retention rather than acquisition.

Noz saw our role as “consultant within the enterprise” – that if everyone just stuck to the org chart, eventually it’ll be the customer who suffers.

Two accessibility gotchas

A few weeks ago I watched a live web conference in which the open source Plone content management system was put through its paces by a blind person using a screen reader (JAWS). Two important issues stuck with me, since they affect most websites, are quite serious, but do not seem to be very widely known.

Popups are usually inaccessible

(Ticket 12123) Popups (by which I mean dynamic overlays rather than popup browser windows) are usually inaccessible. For example, in Plone the login button invoked a login form inside an overlay. Popups are also commonly used for modal dialogs. It is common practice to put popup DIVs at the end of the HTML body, but this means screen reader users are usually not aware of their appearance, nor have any way to get to their contents. (Especially if they do not contain forms; forms in popups are still accessible via JAWS “forms mode”.)

There are two alternative solutions:

  • The trigger element should have an anchor link to the popup contents.
  • The popup should be inserted in the markup immediately after the trigger element.

Both have some associated problems, but I prefer the first solution and will try to implement it in future.

Form field help should be part of the label

(Ticket 7212) In the commonly-used “forms mode” in JAWS, the screen reader reads only labels, legends, input fields, select fields and textarea fields, but no other elements in the form, such as paragraphs, DIVs, etc. That means any help text (usually positioned below or alongside the field) is ignored. This also applies to validation error messages.

The recommendation is to include the help text inside the LABEL element, and use CSS positioning to put it in the right place in the layout. (I can see how this can cause problems where the text should appear above or below fields.)

Update: Here’s an example (see also the ARIA enhancements, not quite reliable cross-platform according to the associated Alistapart article)

Update 19/10/2011: This article recommends the use of aria-describedby for both help text and validation message. It advocates telling users of non-ARIA supporting screen readers to upgrade (but claims that JAWS has supported it since version 10 in 2008)

It was good to see a content management system take accessibility so seriously. Here are some more tickets.