1.5 String Practice

Structural Obstacles That Impede UX Designers Working with Drupal

In my last article I described how all words you see on the computer screen come from internal data structures called ‘strings’ – i.e. “sequences of letters within quotes.”

Many of these strings form the main thread of the User Narrative which is the story we tell to users to help them understand how to use an application. These are ‘UI Strings’.

In this article I want to show how UX Designers are prevented from gaining proper control of these critical, user facing words and phrases, and as a result the user experience suffers a tremendous blow.

Although this problem is not limited to the Drupal development platform, I’m referring to Drupal to illustrate my points. I love Drupal and use it daily to build web applications. If discussion around these issues can help improve the strength and capabilities of the platform then I would be very happy.

In the last article I described the difference between external ‘presentation strings’ and internal code strings that I decided to call ‘nails’. Presentation strings are flexible and can support the art of wordsmithing to targeted audiences. Code nails on the other hand are rigid and are used to bind logical elements together in a strong structure.

I also said that I would describe a way to make better nails in this article. Before I get into that let me present a little quiz. Here is a typical segment of code that shows the internal ‘nails’ on the left and the external presentation strings on the right. It’s a simple assignment of two presentation strings to their respective storage places so the program can retrieve them when they are needed.

'#title' => 'Please enter your name:',
'#description' => 'Enter your username for this account.',

Can you see anything wrong with these two string assignments?

Well, the problem is that the presentation strings on the right are actually nails. Why? Because they are embedded directly in the code. Any string that is embedded into code is by definition fixed and immutable – like a nail.

This is a UX design nightmare. How would a designer modify these strings? She’d typically have to ask the developer who is responsible for this piece of code. That may or may not involve a protracted argument if the developer finds some reason not to change it. Unfortunately the interests of developers and UX designers are not always in clear alignment. Underneath I think they typically are aligned but it’s not always easy to see how, especially if time and energy and reputation and code stability are involved.

The Drupal community has come up with a way to deal with this. It is called the t() function. In Drupal those 2 lines of code would look like this:

'#title' => t('Please enter your name:'),
'#description' => t('Enter your username for this account.'),

The t() function will capture the presentation strings and store them in a database table. If the UX designer wants to change a string, they just have to find the entry in the database and modify it.

But there is still a problem with this code. Can you see it?

The presentation strings are still nails. They are embedded into the code and the rule still holds:

All embedded strings are nails!

Yes, a copy of them can be found, with some effort, in the database. But the story of how, or even if, that kind of string modification takes place is, in my opinion, not conducive with systematic UX planning and design. The current technique of string modification in Drupal involves a tremendous amount of effort and can only support a limited degree of success.

The cost of modifying strings in Drupal is relatively high because it’s more of a fishing expedition than a systematic design process. Only exceptionally inappropriate strings are likely to be adjusted. The energy of UX improvement might easily be shunted elsewhere into documentation and tutorials that attempt to help users make sense of a confusing user interface.

The ideal user interface needs no documentation. Let’s not lose track of that Holy Grail.

So what’s really wrong with the t() function as far as UX design and control is concerned? Well, here’s my list:

Problem 1. No Usage Context Associated With Strings

There are no indicators of the usage context for a given string. If we do manage to dig a string out of the database are we sure it’s the right string? Do we have any hints as to how the string was used semantically? Do we know the form of its usage? Is it a menu item? A main prompt? A subordinate hint? An option in a selector? A checkbox?  Could it be that it is used in multiple places and in some cases the wording is fine but not in other cases? These are the kinds of questions that arise whenever I am facing the task of overriding a string via the database. Admittedly, it’s a task I would rarely attempt to do because I refuse to waste time trying to perform string management in this non-systematic way. I think there is a better way. Keep reading…

Problem 2. PO Files Have Sharp Teeth

There is a way to pull t() strings out of the database and put them into a file. This is done for translating strings into different languages.

These are called ‘PO files’. I would prefer to call them string resource files because that’s how I look at them. They are resources that the application/system can draw from.

Here’s a sample from a PO file that supplies some string translation into German:

#: modules/content_copy/content_copy.module:103
msgid "Types"
msgstr "Typen"

#: modules/content_copy/content_copy.module:107
msgid "Select the content type to export."
msgstr "Wählen Sie einen Inhaltstyp für den Export."

#: modules/content_copy/content_copy.module:171
msgid "Export data"
msgstr "Daten exportieren"

#: modules/content_copy/content_copy.module:176
msgid "Copy the export text and paste it into another content type using the import function."
msgstr "Kopieren Sie den exportierten Text und fügen Sie ihn mit der Importfunktion in einen anderen Inhaltstyp ein."

If I was a translator and this came across my desk, I’d cry.

Once again, there are no cues as to the usage context for these strings. It is frankly entirely unimportant, in the context of language translation, that a given string was embedded in line x of module y. What is this string used for? Who is it intended for? How will users see this string? These are relevant questions.

Without a systematic approach to string translation and management, people brave enough to tackle this job are, in my opinion, the web application equivalent to lion tamers.

Problem 3. The t() Function and PO Files Have Limited Value

Translation from language A to language B is of course a critical feature and one of the strengths of Drupal. But, as my previous articles about User Narratives indicate, this is not the same as idiomatic translation.

Drupal is an amazingly flexible and well thought out platform. Its greatest strength is no doubt its ability to be extended and adapted to specific kinds of applications. The billions of contributed modules testify to that fact.

But this kind of fine tuning and extension of functionality strongly suggests the need to target particular groups of users, businesses or communities. And that speaks loudly and clearly about the need for idiomatic string management.

Idioms and terminologies that are specific to certain user groups, are the real sweet spot for reaching targeted communities or business verticals. People simply don’t always use the same words to mean the same things - so if you can speak in someone's own terms, you can make a powerful connection with them. Within the context of a user interface, this translates into a system that is easy for them to understand.

As far as I can tell, there is simply no way to support idiomatic string design in Drupal using either the t() function or PO files. That’s a shame because I hear a lot about concerns for improving ‘out of the box’ user experiences - for Drupal in general and for targeted subgroups. That cannot really happen unless the application speaks in terms that are meaningful to each targeted group.

Problem 4. Strings Embedded in the t() Function Have the Wrong Authors

There are countless factors that determine the effectiveness of words on a screen. Age, lifestyle, business type, community values, skill level, frequency of usage, etc, etc.

This is why User Narrative design is an art. An effective User Narrative is one that has been carefully crafted for a well defined target audience. Period.

Contrast this ideal method of UX design with the reality of how applications get built. When the strings are embedded in the code itself, guess who gets to be the author? Of course it is generally the developer – typically the last people to be involved with end users or usability requirements analysis.

This is not to blame developers. They do what they do – they write code. But writing code is not the same task, by any stretch of the imagination, as writing user facing, presentation strings.

So why make them do it? As a developer I would appreciate not having to break out of my analytical frame of mind and suddenly try to imagine who might be using this software and what should I say to them. It’s a royal pain to switch gears like that.

It could rightly be argued that, in some cases, the developers are the only people qualified to explain how a particular area of functionality works. This is often the basis for authoring onscreen text cues. But, no matter how knowledgeable a developer may be about his or her own area of functionality, user facing strings should not be authored at the same time that the code is being written. It’s the wrong state of mind to do this task.

As UX designer, concerned about the creation of a strong User Narrative, I’d take a break from coding before trying to craft artful strings. I’d take the dogs for a walk or have lunch, or maybe even wait until tomorrow, before I tried to pen an appropriate message for my target users.

The task of string authorship and management seriously needs decoupling from the task of software development. UX designers need full control of these strings and developers need to be allowed to focus on developing, free from the responsibility of talking to users.

Towards a Solution - Building Better Nails

In the Drupal world, the fact is that developers are deeply tied to the creation of user facing strings and UX designers can’t get proper control over that critical structural content. This generally means a degraded User Experience.

Of course, I couldn’t bear to build applications everyday in Drupal without exploring at least some solutions for this vexing problem. Let me tell you about a method for string definition and management that is commonly used in the commercial software industry.

Let’s rewrite the code sample that I showed you earlier. This time I want to introduce the concept of semantic keys as a way to decouple presentation strings from the code.

'#title' => get_string('LOGIN_FORM_USERNAME_PROMPT'),
'#description' => get_string('LOGIN_FORM_USERNAME_HELP'),

The string on the right is no longer an attempt to talk directly to the user. It is a code string, or key, that associates the storage compartments (‘#title’ and ‘#description’) with strings that are defined elsewhere. Where are they defined? In a resource file. Here’s a sample:

$_strings = array(
...
'LOGIN_FORM_USERNAME_PROMPT' => “Please enter your name:”,
'LOGIN_FORM_USERNAME_HELP' => “Enter your username for this account.”,
...
);

Even if you are not a developer, you might be able to guess what is going on here. The keys are shown at the left and the real user facing presentation strings are on the right. Those keys on the left are ways to open the developer’s storage cupboards that we saw earlier. 'LOGIN_FORM_USERNAME_PROMPT' is the key for the ‘#title’ storage cupboard:

'LOGIN_FORM_USERNAME_PROMPT' => “Please enter your name:”,
'#title' => get_string('LOGIN_FORM_USERNAME_PROMPT'),

You could show them together like this to illustrate the full connection:

'#title' => 'LOGIN_FORM_USERNAME_PROMPT' => “Please enter your name:”

The designer can effectively say: use this key ('LOGIN_FORM_USERNAME_PROMPT') to open up the right storage compartment and put this presentation string in it.

Beyond this critical decoupling of the developer’s and designer’s interests, there are further advantages to this technique. Look at the way the key is formed. It actually describes the usage context for the string. By just having the resource file we can see quite readily that this string belongs to the Login Form and it contains a prompt for the user to get them to enter their user name. Such semantics will make the job of any string editor or translator much easier.

Here are some other string definitions, used on TUAG’s Services pages, that will illustrate this point further:

'PROMPT_CONTACT_NO_ITEMS' => "Use the form below to contact us about the items you add here...",
'PROMPT_CONTACT_ONE_ITEM' => "Let's connect to discuss the item of interest you identified above.",
'PROMPT_CONTACT_MANY_ITEMS' => "Drop us an email and we can discuss the items of interest you identified above.",

In these examples you can see that it was easy for me to create and manage strings at a relatively subtle level – that of tuning the words on the screen to correspond to the state of the system. Depending on how many ‘items of interest’ the user has clicked and placed in the contact form, an articulate prompt is offered to the user to help them get to the next stage.

Reaching For Idiomatic Design

As you will have gathered by now, I am very interested in being able to speak to users in an appropriate idiomatic language. Here are some idiomatic strings that were defined for another project, an application that helps students register for Science Fairs:

'FORM_GROUP_TITLE_PERSONAL_INFORMATION' => "Personal Information - tell us who you are",
'FORM_LABEL_PERSONAL_INFO_FIRST_NAME' => "Your first name",
'FORM_LABEL_PERSONAL_INFO_LAST_NAME' => "Your last name",
'FORM_LABEL_PERSONAL_INFO_SEX' => "Are you male or female?",
'FORM_LABEL_PERSONAL_INFO_BIRTHDATE' => "When were you born? Type it like this yyyy-mm-dd
(for example 2001-11-28 for November 28 2001) ",
'FORM_LABEL_PERSONAL_INFO_GRADE' => "What grade are you in?",

In this case the original strings were derived through an API and were written by developers in a faraway place. There was little chance of getting them to change strings as we wanted.

So, with the magic of Drupal’s ‘form API’ combined with our string management techniques, we were able to intercept those strings and tune them to an idiomatic language that would be more appealing to the kids who use the site. It’s not Shakespearean word crafting by any means, but just enough to appeal a bit more to that target audience and to help them get through the task a little more efficiently and reliably. Even small accommodations like this can go a long way in building a better User Experience.

UX Nirvana

I would like to think that someday, developers will look at embedded user facing strings in the same way that they (the good ones at least) regard embedded JavaScript or CSS styles.

Let me put it another way for non-developers: I would like to think that embedded user facing strings will be generally regarded in the same we’ve come to see smoking in public places. It’s not necessary and it causes harm to User Experiences.

The t() function is an entrenched convenience for developers. But it is also a major inconvenience for UX designers. What we need is a systematic means of decoupling presentation strings from the code/database and creating a means of putting the authorship of these strings into the hands of people who actually know what to say to their targeted users.

In other words, create a string management system that is as robust and well defined as the theming layer. Just as the theming layer decouples functional development from graphic design, a proper string management system would allow UX designers to have full control over the shaping of User Narratives.

In my next article I’ll describe my prototypical string manager. It’s a PHP class that allows this decoupling to happen quite easily. It is a prototype and not a complete solution. But I think it is enough to start some worthwhile discussions about proper string management and perhaps edging closer to UX-Nirvana.