Tag: kranthi

The Font Wars: A Story On Rivalry Between Type Foundries


  

I had thought terms like “intellectual property� and “intellectual theft� were of fairly recent provenance, so my eye was caught by the latter’s use in a headline of a 1930 edition of the US trade journal The American Printer.

The article it headed proved to be equally intriguing, a response by the president of American Type Founders (ATF) to a June 1929 article in the German journal Gebrauchsgraphik by the designer Rudolf Koch, calling the ATF a “highway robber of German intellectual property.� At issue was a typeface marketed by the ATF earlier in 1929 called Rivoli.

Koch and the German type foundry Klingspor asserted that Rivoli was no more than a copy of Koch’s 1922 design of Koch Antiqua, also later known as Locarno and released in the US as Eve. Klingspor had already taken legal action for piracy against the Viennese foundry Karl Brendler und Sohne for its lookalike Radio Antiqua but with no success.

Part of the sample of Wyss’ script offered by the ATF to back its claim that Koch Antiqua was not its designer’s intellectual property
Part of the sample of Wyss’ script offered by the ATF to back its claim that Koch Antiqua was not its designer’s intellectual property. Neither of the two styles of “g� resemble Koch’s, however, to take just one example.

Koch Antiqua, and uppercase letters of the italic.
Koch Antiqua, and uppercase letters of the italic.

Klingspor lost that case, the ATF argued, because far from Koch Antiqua being Koch’s or German intellectual property, both it and the Austrian face were based on the Lombardic penmanship of the Swiss calligrapher Urbanus Wyss, in particular from his 1549 book Libellus Valde Doctus. Klingspor could not claim theft of a design that was not its to begin with.

Whatever the truth of this, the most striking part of the ATF’s broadside was its free admission that the similarity between Rivoli and Koch Antiqua/Eve, far from being accidental, was quite deliberate, Rivoli having been created and released both as a spoiler for the popular Eve and as a “reprisal� face. Klingspor was partially owned by Stempel, whose 1925 catalogue contained what the ATF claimed were “confessedly� fourteen type series of US origin, including what they deemed pirated versions of their own designs.

ATF’s comparison of the faces that accompanied its article.
The ATF’s comparison of the faces that accompanied its article, but not the truth, says David Pankow. What was purported to be Wyss’ script was, in fact, Brendler and Sohne’s Radio Antiqua, printed heavily on soft paper.

The ATF-Koch-Stempel face-off was part of a savage turf war fought by a company to defend its commercial position, with—arguably, only a decade after a World War—some national antagonism thrown in. (For the full story, see David Pankow’s “A Face by Any Other Name Is Still My Face: A Tale of Type Piracyâ€� in Printing History New York, 1998, page 37.) The ATF remained relatively conservative in its designs, whereas on its own doorstep the New York-based Continental Typefounders’ Association was importing type in which was enshrined the latest European stylistic developments. The acerbity of the language on both sides was unrestrained, and it was exacerbated by the ATF’s suspicions that Continental was involved, too, stoking the fires of the argument.

Type design is a business that has long been bedevilled by piracy and plagiarism (conscious or not), licensing issues and scant or no legal protection for intellectual property. Some of the problems stem from the nature of the craft itself. Although, in theory, the number of ways you can position the points of, say, the capital “A� are myriad, the demands of legibility, style and fashion radically reduce the options, and alphabet designs all use the same raw material.

As designer Dave Farey described himself, facetiously but with an undercurrent of truth, “Nothing I have done is original. It’s all based on the 26 letters of the alphabet and the Arabic numerals.� Add to this the revivals and redrawings of classic faces, and the similarities are unavoidable. Type design is an art that is constantly echoing and alluding. Most people who work in the graphic arts are, in a big part of their design psyche, fans. We were probably inspired to get started in the first place by seeing other people’s work that we absolutely love. It’s unavoidable that some of that DNA will crop up or be used consciously in our own work. In the case of type revivals, you can at least credit your source in the type’s name; as designer Nick Shinn says on Typophile, “plagiarism means copying without recognition of the source.�

In today’s digital environment, do any of the attitudes and practices that marked the ATF quarrel persist? I asked Phil Garnham of London’s Fontsmith if he regards other font companies as rivals:

“I think there is definitely a healthy and friendly rivalry between today’s independent digital foundries. Over the past few years, as designers have become more aware of the power of type in branding, particularly the possibilities of bespoke type and with the boom in type design education at Reading University and Type Media at the Hague, fresh competition is popping up on a monthly basis, which is a great thing for type design. It keeps us all on our toes and looking for new possibilities within our beloved alphabets.”

And spoilers? Phil feels the tactic might still be out there, but for his own part, like musicians who consciously don’t listen to other people’s music when writing and recording, he tries not to look too much at other work: “I think that it keeps me detached from other people’s ideas, and allows me to pursue mine, free from any subconscious involvement.�

But even then, you can find that what you’ve done looks like something else. “Arguably, I think there are many designers tripping up in this way, even with the best intentions. I’ve been in this awkward position myself. You have to explore new proportions and alternative letterforms so you can bring something new to the market.�

Horatio: Square leg: Horatio with its restyled ‘R’ in the Letraset catalogue, available in three weights.
Square leg: Horatio with its restyled “R� in the Letraset catalogue, available in three weights.

How close have people steered consciously? Dave Farey recalls from his time working for Letraset that among a selection of faces presented to the committee for inclusion in the dry transfer giant’s range was Harry, a design owned by the Visual Graphics Corporation (VGC). The committee loved it, but unfortunately permission hadn’t yet been obtained, and VGC refused. So Letraset produced Horatio. “I think the only thing we changed was the leg of the uppercase R,� Dave recalls, adding candidly, “Ours was worse.�

Heldustry: From the 1983 Compugraphic Type catalogue.
Heldustry, from the 1983 Compugraphic Type catalogue.

Clues could even be gleaned from the font names—or not. Customers requesting Helvetica from photosetting companies of the 1980s that used the Compugraphic type library might have been told, “We don’t have Helvetica, but we do have Heldustry,â€� which looked… well, similar. The catalogue that digital company Bitstream produced at the start of the 1990s was helpful to customers unable to find familiar names: its Staccato 222, for instance, was the “Bitstream version of Mistralâ€�; “Lapidary 333 was the Bitstream version of Perpetuaâ€�; Venetian 301 the “Bitstream version of Centaur.â€�

Staccato: From the Bitstream catalogue, early 1990s.
Staccato, from the Bitstream catalogue, early 1990s.

Some More Face-Offs

Memphis and Stymie

Memphis seen here in extra bold weight, and Stymie Bold. Memphis was designed by Emil Weiss.
Memphis, seen here in extra bold weight, and Stymie Bold. Memphis was designed by Emil Weiss.

1931 saw ATF squaring off with Stempel again, countering its Memphis slab serif with Stymie, the name being golf lingo for blocking your opponent’s line of play. ATF’s prolific Morris Fuller Benton based Stymie on his own Rockwell Antique, which was itself basically a repackaging of Litho Antique, whose owner (the Inland Type Foundry) had been taken over by ATF. According to Patricia Cost in her book The Bentons, Monotype then copied Rockwell Antique and called it, confusingly, Stymie Bold.

Janco and Banco

The Typefaces Banco and Janco
Rather than stealing the design, Excoffon exercised squatter’s rights in the territory… with style (above). The names were nearly identical—probably no coincidence.

French type legend Roger Excoffon’s employers, Fonderie Olive, was such rivals with Parisian foundry Deberny and Peignot that Excoffon examined with a magnifying glass a picture of its designer Marcel Janco at work on his new self-named type. “Then I rapidly made some sketches for a few letters in a commercial type, not identical, but of the same family… The rest is a success story. Banco was used throughout the world… It’s the most shameful thing I ever did in my career.� (You’ll find this story in Roger Excoffon et la Fonderie Olive, by Sandra Chamaret, Julien Gineste and Sébastien Morlighem, Ypsilon Editeur, Paris, 2010.)

Starling Burgess vs. Stanley Morison

A comparison of Starling Burgess’ design (Lanston no.54) and Stanley Morison and Victor Lardent’s work on Times.
A comparison of Starling Burgess’ design (Lanston no.54) and Stanley Morison and Victor Lardent’s work on Times, as it appeared in “Printing History 31/32� (1994).

According to a 1994 article by Mike Parker that appeared in Printing History, Times New Roman was an extremely close reproduction of a typeface designed years earlier by genius boat and car designer and maverick Starling Burgess, which lay unpaid for and abandoned at Lanston Monotype until the design of the new face for The Times newspaper became problematic. Although Morison had a reputation among some for being a slippery operator, the story as presented seems hard to credit: Font Bureau offers a Mike Parker design called Starling.

Futura and Twentieth Century

Twentieth Century (above), Lanston Monotype’s response to Futura (below).
Close but no cigar: Twentieth Century (above), and Lanston Monotype’s response to Futura (below).

Buffalo, New York-based foundry P22 has in its Lanston Type Company collection Twentieth Century, “Monotype’s answer to Futura.� It describes Sol Hess’ redrawing as “close�; as an attractive optional extra, it has included digital recreations of some of Paul Renner’s original experimental characters for Futura.

Comic Sans and Chalkboard

Comic and Chalkboard.
Comic and Chalkboard: both ideal for warning notices.

Apple’s OS X doesn’t supply you with the world’s favorite, Comic Sans, but you do get Chalkboard, which inhabits pretty much the same terrain.

Helvetica and Arial

Arial and Helvetica.
Hard to fully love perhaps, but Arial has certainly been well used, if only because it is the default setting.

Arial, designed in 1982 by Robin Nicholas and Patricia Saunders, seems to attract its share of ill will in “font hate� blogs these days on the grounds of it being Microsoft’s Helvetica lookalike.

Does It Really Matter?

For the user, does any of this matter? If you like a font and it fits your purpose, then its provenance is irrelevant. And if it’s a new or recent design, then it comes with little or no back story. In terms of design rationale, investigating the background of your choice is always useful. Who designed it? When and for whom—for a particular project or for a company? If for a project, would those associations jar with how you’re planning to use it now, and does that matter? If it was originally designed for Monotype, is the font you’re planning to buy from Monotype or from another foundry? What does Monotype offer as its version, and how does it compare? Stempel Garamond versus Simoncini Garamond, or Garamont?

Koch Rivoli.
Koch Rivoli: channelling the spirit of Rudolf Koch and Willard T. Sniffin.

And how has history served those original battling typefaces? Sebastian Carter in Twentieth Century Type Designers describes Koch Antiqua as “one of the most successful advertising faces of the inter-war period, still often used to suggest the vanishing luxury of ocean liners.� Although some of that usage might have been in reality Rivoli, Koch’s reputation as a type designer endures.

As does the name Rivoli, although its creator or draughtsman, the magnificently named Willard T. Sniffin, is less remembered. But UrbanFonts.com for one offers as a free font Koch Rivoli (a pairing of names that would have the German designer spinning in his grave), an uppercase-only design that takes inspiration from the thick-thin double stroke of Koch’s italic uppercase—and Rivoli’s.

Note: A big thank you to our fabulous Typography editor, Alexander Charchar, for preparing this article.


© Simon Loxley for Smashing Magazine, 2012.


Taming The Wild Mind


  

Myths have developed around and researchers have studied how the human brain juggles creativity and organization. Popular theory tells us that the left brain is structured and logical, while the right brain is artistic and imaginative, and that all human beings use predominantly one side of the other.

Working in a creative field means challenging that theory, or else challenging the schedules and deadlines that managers impose on writers, designers and other creatives. As a project manager in a UX design agency, as well as a writer, I believe it is necessary to challenge both the assumptions about schedules and the belief that creativity implies disorganization.

Can Creativity Be Scheduled?

There’s a quick and easy answer to this question. Yes!

You’re shaking your head now. You’re thinking about how much you hate deadlines and how your designs suffer from the 9:00 to 5:00 schedule imposed by your manager. You’re remembering the sketches or creative writing you did in college at 3:00 in the morning. Sathish Manohar expresses it well in his article “Why 9 to 5�:

“Knowledge work solely depends on creativity of the workers. But, still some how, knowledge work-places got modeled around factories. Employees had to work 9-5, be creative between 9-5, and go home… This is a problem, We cannot schedule the brain to be creative at any given time.”

Yet I’ve spent years trying to merge my creative-writing personality with my project-management skill set and day job. Recently I realized that writing by the light of the moon results in over-caffeinated mornings and sloppy grammar, and still I continued—after all, isn’t that what creativity is all about? I’ve always been able to empathize with my designers, who want nothing more than free reign to be creative when the mood hits. But as a project manager, I also strive to create a working environment where designers and content strategists can be productive and efficient—and where we can deliver mockups on a deadline.

The solution turned out to be easier than you might expect. Spontaneous creativity is not the only way. In fact, as a content strategist, designer or even developer, you are paid for your ability to turn on the creative faucet. So, what goes into creating on command?

1. Create A Routine

“Be regular and orderly in your life so that you may be violent and original in your work.”

– Gustave Flaubert, author

Flaubert did not write on a deadline, and yet he found that following an orderly routine improved his ability to be creative. This holds true for most people. Being able to “do your best work� at 3:00 am is no coincidence: you are training your brain to get those creative juices flowing when the moon is high and the workday is long over. This is fantastic if you don’t have anywhere to be in the morning; but for many of us, 3:00 am is not a great time to be inspired.

Instead, develop a routine that trains your creative juices to kick in at more convenient times. This could mean setting the alarm for 8:00 am, making breakfast and then sitting down with a journal to begin sketching as you eat. It could mean emailing yourself a to-do list before bed, with inspirational quotes to greet you the moment you open your email. Maybe you need a lunchtime scrum every day to energize and focus. Within two weeks, these mini-kickoffs will begin to signal to your brain, “Now is when we begin the creative work of the day.�

2. Take Your Time

“A single meeting can blow a whole afternoon, by breaking it into two pieces each too small to do anything.”

– Paul Graham, essayist and programmer

Distractions are a powerful creativity-blocker. Even the best routine can be waylaid by mandatory meetings, important phone calls and constant emails. If you are a freelancer in charge of your own schedule, try to relegate meetings to the very beginning or end of the day. If a manager schedules your client meetings and internal reviews, talk to them about the benefits of opening up large blocks of time for creative work.

At Above the Fold, we make a point of scheduling around the “maker’s schedule.� Paul Graham sums up the maker’s schedule in his essay, “Maker’s Schedule, Manager’s Schedule�:

“When you’re operating on the maker’s schedule, meetings are a disaster. A single meeting can blow a whole afternoon, by breaking it into two pieces each too small to do anything hard in. Plus you have to remember to go to the meeting. That’s no problem for someone on the manager’s schedule. There’s always something coming on the next hour; the only question is what. But when someone on the maker’s schedule has a meeting, they have to think about it…. I find one meeting can sometimes affect a whole day. A meeting commonly blows at least half a day, by breaking up a morning or afternoon.”

Therefore, at Above the Fold, we hold internal reviews at 5:00 pm, check-in meetings at lunchtime, and client calls first thing in the morning. This gives our creative team the time they crave to get engrossed in projects, without interruption.

This doesn’t solve the issue of interruption via email, of course. Try scheduling specific “Check emailâ€� times into your day—again, first thing in the morning, just before your lunch break or at the end of the day works well. Make sure your team is aware that you will not be responding to emails immediately, and suggest they call you or come find you if something is urgent and relevant to the current project. Team members can be surprisingly understanding and can quickly grasp the difference between imperative and interesting.

3. Use Your Team

“Separate brainstorming (idea generation) from synthesis (putting it all into a flowing post).”

– Tim Ferriss, author

Having large blocks of time available and scheduling them into your day sounds well and good, but how do you convince your brain that the time has come to get in the zone and ignore distractions?

Taking a page out of the Agile development book, try starting with a variation on pair programming. Pair programming is designed to help developers break down complex tangles of code with the simple rationale that two heads are better than one. The same is true for kicking off any other sort of creative block of time. Instead of working together all day, kick off the day with a 10-minute group brainstorming session. Nothing focuses the creative mind faster than talking through project details, and 10 minutes can lead to a far more productive three hours of synthesis.

Don’t have a team to kick around ideas with? Hit up a few colleagues on Twitter or Skype. We have found that many in the content and design worlds are happy to help, and you can offer to help in return.

4. Warm Up Your Muscles

“Major league players aren’t the only professionals that regularly practice. We’ve met musicians, firemen, pilots, and surgeons, all of who regularly practice their skills.”

– Jared M. Spool, founding principal of User Interface Engineering

Athletes warm up their muscles before starting their real work, and so should creative thinkers. A good warm-up helps you practice basic skills, focus your mind and improve the work to come. In addition, taking 10 minutes to warm up allows you to separate your ideas from the plethora of ideas surrounding you.

A few hundred years ago, visual stimulation was hard to come by, and artists were influenced primarily by their surroundings. Now, our surroundings contain hundreds of representations of our surroundings and of other people’s interpretations of their surroundings. Finding your own voice can be difficult amid the clutter.

The following quick warm-ups can bring you back to basics and isolate what makes your creative voice unique. Some of these suggestions even include using someone else’s work as a starting point—but making it your own.

  1. Write your thoughts down in a journal.
  2. Doodle for 10 minutes in a sketchpad.
  3. Copy the first sentence of a book, and then write a one-page story that begins with that sentence.
  4. Create three variations of a landing page based on different mood themes (happy, scary, sad, etc.).

None of these warm-ups should take more than 10 minutes, and each offers a different way to reconnect you to your creative spirit. From here, you might find it easier to begin thinking about new and different ideas, and even jumpstarting a project that has felt stale.

5. Save The Best For Last

“Laziness in a white collar job has nothing to do with avoiding hard physical labor. “Who wants to help me move this box!â€� Instead, it has to do with avoiding difficult (and apparently risky) intellectual labor.”

– Seth Godin, entrepreneur, author and speaker

Most creative jobs come with a catch, such as having to respond to client emails, send invoices or email writing samples. It’s not uncommon for these boring, “uncreativeâ€� tasks to turn into a means of procrastination. You feel as though you can’t set a task aside because it must be done; but because you don’t want to do it, you procrastinate—effectively avoiding both your creative work and your busywork.

Invoices and emails and bills are quick tasks, so we don’t feel as though delaying them by an hour or two costs much. But the hour you spend avoiding a five-minute task eats away at your creative time. What’s more frightening is the possibility that you’re actively using these tasks to avoid your creative work. As Seth Godin explains, this is due to “lizard brain�:

“The [lizard brain, or resistance,] is the voice in the back of our head telling us to back off, be careful, go slow, compromise. The resistance is writer’s block and putting jitters and every project that ever shipped late because people couldn’t stay on the same page long enough to get something out the door.”

We’ve all dealt with lizard brain, and many of the suggestions in this article can help combat it. But how do you remove the procrastinations that are genuine work, the busywork that must be done but just gets in the way?

Try setting aside one morning a week (Monday is a good day) to devote to the boring tasks. Relegate email reminders of the busywork to a “Mondayâ€� folder. Keep all physical folders and to-do lists for that work away from your desk. Of course, you don’t want to wake up one day and realize you forgot to pay the bills, but you won’t forget housekeeping chores like that if you assign them to a specific time slot—and not that generic “tomorrow.â€�

One more tip: don’t sit in your creative spot to do the busywork. The area for busywork will quickly get cluttered with to-do notes that have nothing to do with the creative work that you need to accomplish. Do the necessary evils somewhere else to avoid distracting yourself the next time you begin your “real� work.

Untamed Creativity

Saying that a wild creative mind can’t be tamed sounds romantic, but romanticism will serve you better in your actual products than in your schedule. The advice above will help you schedule your mind, enhance your creativity and use team members, time constraints and even deadlines to your advantage. Give your creative mind the structure and security it needs to run wild.

Other Resources

Here are some more resources on creative productivity:

What other tips and tools help you to be creatively productive?

(al) (il)


© Marli Mesibov for Smashing Magazine, 2012.


Interaction Design In The Cloud


  

Interaction designers create wireframes in tools such as Adobe Illustrator, OmniGraffle and Microsoft Visio. Originally, these wireframes were primitive shapes drawn to represent various UI elements. Many of us cannot imagine life without them.

There are, however, reasons to consider moving to the cloud to do interaction design. In short, today’s cloud-based tools are:

  • Optimized for collaboration,
  • Editable anywhere,
  • Interactive,
  • Published in real time,
  • Self-maintaing (the user doesn’t need to update software),
  • Payable monthly,

Emailing your old static designs will feel old fashioned once you see what these tools can do. Going a step further, there are tools for the user review process, too. Just upload your ideas, from simple mockups to final layouts, link them together, and share them for comment.

iPad Wireframe
(Image credit: baldiri)

This article walks you through the current selection of cloud-based tools and provides some recommendations. The number of offerings and amount of functionality are pretty vast. For the sake of brevity, we’ll address two functions: prototyping and wireframing. But if you’re intrigued, you might want to explore cloud-based image editing, mind-mapping tools and other UX activities. These tools are already out there, and surprisingly good.

Prototyping

For our purposes, prototyping involves uploading images (screens) and linking them together via hotspots. Once these are set up, the prototype is published and available to reviewers for usability testing, commenting or both.

Review criteria
Here are the fundamentals that a product should support in order to compete in this space:

  • Quick uploading process,
  • Support for several source image file formats,
  • Easy linking between pages,
  • Support for feedback from end users.

Some items aren’t available as of this writing:

  • The ability to nudge images in line without having to recreate them;
  • The ability to create interactive objects and layer them (such as a menu bar that appears on every page).

InVision

What it does
Create your screens in your favorite tool and upload them to InVision. Then add hotspots; a hotspot links to another page. This is great if you live and die by the comp (Photoshop file). For example:

  1. Create a new project. Think of a project as a collection of previously generated comps that you are going to tie together as a prototype via InVision.
  2. Upload your files to this new project (the images in this article are PNGs).
  3. In “Buildâ€� mode, create the hotspots. Basically, you are linking together the prototype. If you have all of the collateral that you need, this will go quite fast — exactly as you’d want it to work.
  4. Smashing Magazine Example

Observations
The application works as advertised. It enables the user to quickly wire up prebuilt comps, wireframes and sketches. The tutorials also explain useful actions, such as creating hotspots that will be the same on multiple pages (these are called “templates� in InVision).

Speaking of templates, they expose both a major advantage and a major disadvantage of this tool: if the uploaded images are not placed perfectly, then the templates will not line up properly. One would want the ability to adjust the x and y coordinates of any image so that they line up perfectly without having to change the source files. On the upside, if you’ve done the prep work right or you’ve made your hotspots large enough, you can fudge this a bit, and the templates really accelerate the build process.

A number of usability issues have made me scratch my head. For example, the first time I tried adding a hotspot to the search input field, the “Link to…� modal dialog was off to the left side of the browser, which made it impossible to save or cancel the dialog. I then tapped the “Update screen� at the bottom of app to refresh the screen. It turns out that in InVision speak, “Update� = “Replace.� I was afraid to refresh the browser because there is no indication of whether the application saves automatically. So, in the end, I switched to “Preview� and then back to “Build.�

Once you’re familiar with the quirks, however, the application is useful. If you’re a designer or want to work offline to generate wireframes, then give this app a hard look.

  • Upload process
    Drag and drop, or browse the file system
  • Supported file formats
    JPG, PNG and GIF
  • Linking pages
    Easier than the others tested because of templates
  • User feedback
    Easy, nested
  • Marquee clients
    eBay, Google, Intuit, Whole Foods and many others. Very impressive.

FieldTest

In spirit, FieldTest (in private beta) serves the same space as InVision. The designer uploads prebuilt comps, wireframes and the like to FieldTest, ties them together, and then publishes them for review. One advantage is that FieldTest leverages device gestures. In short, you can “play� FieldTest prototypes on your iOS, Android or Windows Phone 7 device and have it respond to gestures. Combined with the built-in screen transitions, this is a powerful function for mobile app designers.

As with InVision, screens are grouped into “prototypes� (projects). Including them in a project means that they can be linked to and from other screens. The process is the same, too: create the prototype collateral, link it together via hotspots, and publish it for review. For comparison’s sake, here are the hotspot configurations for the two apps.


This demonstrates the differences in approach. On the top is FieldTest. It allows a user to choose between gestures (the prototype I built was an iPhone app). The gestures are tap, long tap, swipe, swipe left and swipe right. Multiple gestures can be active for the same hotspot, which is particularly cool and gives a realistic experience of various actions. On the bottom is InVision, whose ace is templates. The author can create a template for several controls that appear together, and they can reuse that template on several screens.

Observations
If I were to choose between these prototyping tools, FieldTest would be my choice, largely because I build mobile applications. Having listeners for multiple gesture types makes for a more realistic prototype. If the app were Web-based, then InVision is more mature.

FieldTest still has work to do, though. In the beta, gestures such as up and down are missing. Templating as InVision does is really useful. It streamlines the addition of hotspots. Another area for improvement is in comments, and allowing a prototype’s end user to provide feedback.

There are other usability nits. For example, FieldTest includes a status bar at the top of each screen. I have yet to figure out why someone would want this, and it’s not optional. So, if you take a screenshot on an iPhone, you’ll have to edit it to remove this status bar, only for FieldTest to put it back.

Try it out for yourself on the prototype built for this review. Please note, there is no down gesture, so if you want to try that, gesture from right to left (like when advancing through pictures in iPhoto).

  • Upload process
    Browse the file system
  • Supported file formats
    JPG, PNG and GIF
  • Linking pages
    Fairly easy
  • User feedback
    Enables gestures on the device, which is great.
  • Marquee clients
    In private beta

ClickDummy

ClickDummy is another competitor in this space and has the same process as the others. The user uploads materials and then links them together through hotspots. The link function is a “tool� contained in a drawer (i.e. a UI element that slides in and out from one side of the screen).

Observations
This drawer seems innocent enough, but it creates unnecessary hurdles for the user. In an attempt to simplify the problem, it has added confusion and multiple steps to an easy process. How? The user has to toggle between this tool drawer and the page-picker drawer a lot. The page picker also has to be overloaded in order to provide both functions (selecting a page, as in navigation, and selecting a page, as in a hotspot target).

A second issue: the website says that the user can drag and drop images onto the pages drawer. This doesn’t work in my (Chrome) browser. It instead replaces the current page with the image. After a panicked “Backspace,� the user is restored to their project but has lost their location and has to start over.

Another point: this all-important drawer is closed when the app launches. It took about five minutes to determine that the app was working, and this after weeks of looking at apps in this space.

Lastly, unlike both of the apps reviewed above, this one has no compelling feature that makes the additional effort worth the time. In future, hopefully, the addition of some product differentiation, combined with a rework of the primary use case, would make this application worth another look.

You can see the output from this exploration for yourself.

  • Upload process
    Drag and drop, or browse the file system.
  • Supported file formats
    JPG, PNG and GIF
  • Linking pages
    Most difficult of those tested
  • User feedback
    Easy to test, but comments require registration
  • Marquee clients
    Not provided

Wireframes

Think of a wireframe as a black and white low-fidelity screen mockup. The mockups I create also include call-outs to give the development team additional context.

In the process, the user will create an account, create a project, and then land on a blank screen. The user then drag and drops UI controls (radio buttons, text input fields and so forth) onto the page.

Once the project is saved, a permalink can be given out for people to see your work. If you change a screen, it will auto-magically show your updates the next time that URL is opened (or refreshed) by a team member. This last point is what the cloud is all about: everyone always has the same (i.e. current) version of your work. Changes are instantaneously available whenever the wireframe is saved.

Compared to most offline tools, the library of available objects is focused on low-fidelity UX. Don’t expect to create gradients or to use a pencil tool.

Review criteria
Here are some basics that are fairly universal in my experience:

  • Robust set of standard UI controls
    If the tool doesn’t have off-the-shelf drop-downs, toggles, cover flows and the rest, then creating those controls will require additional work.
  • Good as a documentation medium
    Plan on your development team using your wireframes to dictate the logic and layout of the application.
  • Good for making wireframe clones, templates or whatever you want to call them
    Not surprisingly, all of the iPhone wireframes I create have the app’s name at the top. I want to do this on the first wireframe and not have to do it again.
  • Responsive
    It all takes place in a Web browser. If the application is slower than a locally running application, then your productivity will suffer. Case in point: a year or two ago, I created about 50 wireframes for a project. Each page took a minute to load. To see my changes reflected, another minute. Trust me, this gets old quickly.
  • Not written in Flash
    “Dear development teams who write these tools: I love Flash, Flex and the rest. Not as much as I love my iPad, however. I want to edit my work across form factors. It’s all drag and drop, right?�

Here’s what you won’t see right away from the tools out there:

  • An extensive stencil library or the ability to easily create and reuse stencils
    OmniGraffle excels at this. Don’t expect Yahoo to create a stencil library for Mockingbird anytime soon.
  • A wide user base
    Momentum is building, and there are believers. This is still a minority position and will be for some time. I would say customer support is great, but the more people use these tools, the better the tools will become.
  • Font selection
    I won’t dwell on this, but you can tell there is still some lively debate about what a wireframe should and should not communicate just by looking at what features are included in any given product.

Balsamiq

As with the prototyping tools, wireframes — or “mockupsâ€� in Balsamiq-speak — are organized into projects. From there, things change. Tools like InVision and FieldTest assume that you have created your pages or screens in another tool. In Balsamiq (and Mockingbird, discussed next), the tool is designed for wireframe creation, with extremely limited functionality for prototyping.

  1. Create a new mockup.
  2. Drag and drop an off-the-shelf UI control from the ones available.
  3. Balsamiq controls

  4. Configure the control to your needs. This is noteworthy, because Balsamiq provides a number of important options. For example, there is one toggle to put the iPhone in landscape orientation instead of portrait.
  5. Toggle

  6. Add the rest of your UI controls; document for the development team; and publish.

Observations
Having worked with some other tools, I’ve become a fan of Balsamiq. A great UI control library and easy object configuration are two areas where this tool excels. There are some areas for improvement, though. First, and I’m sure the development team is tired of hearing it, the sketching style is fine for those who understand low-fidelity mockups, but you probably wouldn’t want to show the mockups to your CEO.

A second gripe is that the editing tool is built in Flash, so work is limited to platforms that support it.

On the upside, a few non-obvious pros:

  • The icon set is great. I’ve noticed that only one icon is not in the box: Bluetooth. Anything else I’ve needed has been available.
  • In addition to drag and drop, there’s a great quick-add feature. After typing in a few characters of the name of a UI control, a filtered list appears, allowing you to add controls quickly.
  • Balsamiq has an odd markup language that, once mastered, allows the user to add common things. For example, + Add and sub-menu, > translates to:

And here’s the rundown:

  • UI controls
    More than 70, including iPhone-specific
  • Good for documentation?
    Call-outs are one of the controls; drag and drop them onto the canvas.
  • Good at duplicating screens?
    Yes.
  • Responsive?
    Yes. You will forget you are working in the cloud.
  • Written in Flash?
    Yes.

Mockingbird

Mockingbird is also a wireframing tool, and a good one at that. In some ways, it compares favorably to Balsamiq: Mockingbird’s editor isn’t Flash-based; it uses an unobtrusive font; and adding UI controls is (almost) comparable to Balsamiq.

The process is similar, too. Here’s the outcome:

Mockingbird Wireframe

Observations
More professional, right? On the surface, it is more polished, but there are some subtle shortcomings. For example, one cannot left-justify text in an input field. Also, I couldn’t get the icons to all be exactly the same size (36 pixels). And so forth.

There are some logistical hurdles as well. Many of the controls are primitive. To add a call-out, like ones in yellow above, you actually have to add two objects: the yellow circle and the black text. And when a control is added via the quick-add function, the filtering text is not cleared, so after every addition, one has to clear the previous query. Put practically, this mockup took about four times as long to create as the Balsamiq version.

  • UI controls
    Fewer than Balsamiq, and no mobile-specific controls.
  • Good for documentation?
    Call-outs are created with circles and overlaid text.
  • Good at duplicating screens?
    Yes.
  • Responsive?
    Mostly — don’t use Chrome.
  • Written in Flash?
    No.

Mockup Builder

Another entry in the wireframing space is Mockup Builder. Functionally, it lies somewhere between Mockingbird and Balsamiq. It has a fairly good library of controls — in fact, it’s the only cloud-based solution with native Android controls (Ha!). Moreover, I find its aesthetic better than that of competitors.

Like the others, Mockup Builder starts with a blank canvas, and the user drag and drops controls onto the canvas for configuration.

Here’s the mockup created for this review:

Mockingbird Wireframe 2

Again, the mockup is fairly clean, but there are some issues: the icons use some funny clipping, and they do not scale properly. The user cannot toggle the various defaults for the iPhone, such as the gray bars at the top and bottom of the screen.

Observations
This tool is a little too buggy for everyday use. For example, the notes to accompany illustrations are in Lorem Ipsum text. Also, when copying text from the Web and pasting into a multi-line text area, the text does not wrap to the control’s width — meaning that the text shows exactly one line, and the user has to use the control’s handles to wrap it. I also wanted to show two paragraphs of text but could not figure out how to insert a “Returnâ€� in the text.

Another grievance: the tool could use more polish. For example, the screen surface on the iPhone control is narrower than the keyboard, so the user has to resize the keyboard by hand. When that’s done, the “e� is missing in the button. I understand that these are minor, but one would expect these t’s to be crossed off before moving away from a beloved tool like OmniGraffle.

  • UI controls
    More than the others, including iPhone- and Android-specific ones
  • Good for documentation?
    Call-outs are one of the controls; drag and drop them onto the canvas.
  • Good at duplicating screens?
    Yes.
  • Responsive?
    Yes.
  • Written in Flash?
    No.

Conclusion

Cloud-based tools are now available and well designed for UX work. Many of the features in the offerings above are not available in software running locally on your machine. While this space is still growing, I’ve been working in the cloud for the past two years and cannot imagine going back.

Collaboration is instantaneous, and the tools are optimized for the right activities: wireframing and testing with users. In fact, these apps have several unexpected and delightful features, and you might find yourself walking away from your favorites, too.

Of course, there are valid reasons to avoid working in the cloud. Stay with your old standbys if any of the following apply:

  • Your IT department disapproves.
    This is a hot-button issue. All of these tools protect your information, but this is still worth considering.
  • You expect the polish of offline tools.
    These tools are for early adopters. Still, they are Web applications, so they will evolve. That’s what happens on the Web. You’ll just wake up one morning to find some annoyance removed or a key feature added.
  • Your project is big.
    If you plan on a 200-screen flow, you will feel a steady degradation in performance. That said, I’ve just completed a 70-pager with one of these tools and was just starting to notice some minor falloff.
  • You think in terms of “deliverables,â€� with a complete set of create-once mockups.
    Many of these tools have coauthoring functionality (if the roles are set up that way). In my experience, however, no one has actually changed anything, even if I wanted them to.
  • Your Internet connection is a problem.
    But that’s not to say that you’ll lose data whenever the network is interrupted.

These could be a deal-breaker for some. But these tools are free to try, and some are so simple that you might get hooked in five minutes (as I did a few years ago). Almost all of the research for this article was done with free trials. Given the ease with which you can try these out, you have every reason to go out and see whether one or more is right for you.

If you have another favorite, we’d love to learn about it. The space is ever changing!

(al)


© Erik Perotti for Smashing Magazine, 2012.


iOS orientation change and automatic text resizing

Most web developers who have viewed their work in an iOS device know that Safari for iOS likes to zoom in on the page and do weird things to font size when you change the device’s orientation from portrait to landscape. A too common way to prevent that is to completely disable the user’s ability to zoom, which you really do not want to do.

Luckily there is A Fix for the iOS Orientationchange Zoom Bug, a very clever one too. I’ve been using this in a few projects and have found it to work well. I have however run into a couple of issues (that in hindsight are pretty obvious) that I want to note here as a reminder to my future self.

Read full post

Posted in , , .

Copyright © Roger Johansson



How To Build A Real-Time Commenting System


  

The Web has become increasingly interactive over the years. This trend is set to continue with the next generation of applications driven by the real-time Web. Adding real-time functionality to an application can result in a more interactive and engaging user experience. However, setting up and maintaining the server-side real-time components can be an unwanted distraction. But don’t worry, there is a solution.

Cloud hosted Web services and APIs have come to the rescue of many a developer over the past few years, and real-time functionality is no different. The focus at Pusher, for example, is to let you concentrate on building your real-time Web applications by offering a hosted API which makes it quick and easy to add scalable real-time functionality to Web and mobile apps. In this tutorial, I’ll show how to convert a basic blog commenting system into a real-time engaging experience where you’ll see a comment made in one browser window "magically" appear in a second window.

Why Should We Care About The Real-Time Web?

Although the Real-Time Web is a relatively recent mainstream phrase, real-time Web technologies have been around for over 10 years. They were mainly used by companies building software targeted at the financial services sector or in Web chat applications. These initial solutions were classed as "hacks". In 2006 these solutions were given an umbrella term called Comet, but even with a defined name the solutions were still considered hacks. So, what’s changed?

In my opinion there are a number of factors that have moved real-time Web technologies to the forefront of Web application development.

Social Media Data

Social media, and specifically Twitter, has meant that more and more data is becoming instantly available. Gone are the days where we have to wait an eternity for Google to find our data (blog posts, status updates, images). There are now platforms that not only make our data instantly discoverable but also instantly deliver it to those who have declared an interest. This idea of Publish/Subscribe is core to the real-time Web, especially when building Web applications.

Increased User Expectations

As more users moved to using applications such as Twitter and Facebook, and the user experiences that they deliver, their perception of what can be expected from a Web application changed. Although applications had become more dynamic through the use of JavaScript, the experiences were seldom truly interactive. Facebook, with it’s real-time wall (and later other realtime features) and Twitter with it’s activity stream centric user interface, and focus on conversation, demonstrated how Web applications could be highly engaging.

WebSockets

HTML5 and WebSockets Rock!

Earlier on I stated that previous solutions to let servers instantly push data to Web browsers were considered "hacks". But this didn’t remove the fact that there was a requirement to be able to do this in a cross-browser and standardised way. Our prayers have finally been answered with HTML5 WebSockets. WebSockets represent a stardardized API and protocol that allows realtime server and client (web browser) two way communication over a single connection. Older solutions could only achieve two-way communication using two connections so the fact the WebSockets use a single connection is actually a big deal. It can be a massive resource saving to the server and client, with the latter being particularly important for mobile devices where battery power is extremely valuable.

How are Real-Time Technologies being used?

Real-time Web technologies are making it possible to build all sorts of engaging functionality, leading to improved user experiences. Here are a handful of common use cases:

  • Realtime Stats – The technology was first used in finance to show stock exchange information so it’s no surprise that the technology is now used more than ever. It’s also highly beneficial to sports, betting and analytics.
  • Notifications – when something a user is interested in becomes available or changes.
  • Activity Streams – streams of friend or project activity. This is commonly seen in apps like Twitter, Facebook, Trello, Quora and many more.
  • Chat – the 101 or real-time Web technology but still a very valuable function. It helps delivery instant interaction between friends, work colleagues, customers and customer service etc.
  • Collaboration – Google docs offers this kind of functionality within its docs, spreadsheets and drawing applications and we’re going to see similar use cases in many more applications.
  • Multiplayer Games – The ability to instantly deliver player moves, game state changes and score updates is clearly important to multiplayer gaming.

In the rest of this tutorial I’ll cover building a basic blog commenting system, how to progressively enhance it using jQuery and finally I’ll also progressively enhance it using the real-time Web service I work for, Pusher, which will demonstrate not just how easy it can be to use real-time Web technology, but also the value and increased engagement that a real-time factor can introduce.

Creating Generic Blog Commenting System

Start from a Template

I want to focus on adding real-time commenting to a blog post so let’s start from a template.

This template re-uses the HTML5 layout defined in the post on Coding An HTML 5 Layout From Scratch and the file structure we’ll start with is as follows (with some additions that we don’t need to worry about at the moment):

  • css (dir)
    • global-forms.css
    • main.css
    • reset.css
  • images (dir)
  • index.php

HTML

The template HTML, found in index.php, has been changed from the HTML5 Layout article to focus on the content being a blog post with comments. You can view the HTML source here.

The main elements to be aware of are:

  • <section id="content"> – the blog post content
  • <section id="comments"> – where the comments are to appear. This is where the majority of our work will be done

Comments

Now that we’ve got the HTML in place for our blog post and for displaying the comments we also need a way for our readers to submit comments, so let’s add a <form> element to collect and submit the comment details to post_comment.php. We’ll add this at the end of the <section id="comments"> section wrapped in a <div id="respond">.

<div id="respond">

	<h3>Leave a Comment</h3>

	<form action="post_comment.php" method="post" id="commentform">

		<label for="comment_author" class="required">Your name</label>
		<input type="text" name="comment_author" id="comment_author" value="" tabindex="1" required="required">

		<label for="email" class="required">Your email;</label>
		<input type="email" name="email" id="email" value="" tabindex="2" required="required">

		<label for="comment" class="required">Your message</label>
		<textarea name="comment" id="comment" rows="10" tabindex="4"	 required="required"></textarea>

		<-- comment_post_ID value hard-coded as 1 -->
		<input type="hidden" name="comment_post_ID" value="1" id="comment_post_ID" />
		<input name="submit" type="submit" value="Submit comment" />

	</form>

</div>

Comment Form CSS

Let’s apply some CSS to make things look a bit nicer by adding the following to main.css:

#respond {
	margin-top: 40px;
}

#respond input[type='text'],
#respond input[type='email'],
#respond textarea {
	margin-bottom: 10px;
	display: block;
	width: 100%;

	border: 1px solid rgba(0, 0, 0, 0.1);
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-o-border-radius: 5px;
	-ms-border-radius: 5px;
	-khtml-border-radius: 5px;
	border-radius: 5px;

	line-height: 1.4em;
}

Once the HTML structure, the comment form and the CSS are in place our blogging system has started to look a bit more presentable.

Screenshot of blog post and commenting system

Handling Comment Submission

The next step is to write the PHP form submission handler which accepts the request and stores the comment, post_comment.php. You should create this file in the root of your application.

As I said earlier I’m keen to focus on the real-time functionality so a class exists within the template that you’ve downloaded which encapsulate some of the standard data checking and persistence functionality. This class is defined in Persistence.php (you can view the source here), is in no way production quality, and handles:

  • Basic validation
  • Basic data sanitization
  • Very simple persistence using a user $_SESSION. This means that a comment saved by one user will not be available to another user.

This also means that we don’t need to spend time setting up a database and all that goes with it and makes post_comment.php very simple an clean. If you wanted to use this functionality in a production environment you would need to re-write the contents of Persistence.php. Here’s the code for post_comment.php.

<?php
require('Persistence.php');

$db = new Persistence();
if( $db->add_comment($_POST) ) {
	header( 'Location: index.php' );
}
else {
	header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
}
?>

The above code does the following:

  1. Includes the Persistence.php class which handles saving and fetching comments.
  2. Creates a new instances of the Persistence object and assigns it to the variable $db.
  3. Tries to add the comment to the $db. If the comment is successfully added it redirects back to the blog post. If it fails the redirection also occurs but some error text is appended to an error query parameter.

Displaying the Comments with the Blog Post

The final thing we need to do to have our Generic Blog Commenting System up and running is to update the blog page, index.php, to fetch and display the comments from the Persistence object.

  • Since this isn’t a real blogging system we’ll hard code the $comment_post_ID value to be 1.
  • Include the Persistence.php class and fetch the comments from it. Comments are associated with a blog post using a unique $comment_post_ID.
<?php
require('Persistence.php');
$comment_post_ID = 1;
$db = new Persistence();
$comments = $db->get_comments($comment_post_ID);
$has_comments = (count($comments) > 0);
?>

Since we now have the $comment_post_ID accessible via PHP we should update the HTML for the comment form to use this value.

<input type="hidden" name="comment_post_ID" value="<?php echo($comment_post_ID); ?>" id="comment_post_ID" />

We now have all the comments related to the blog post referenced by the $comments variable we need to display them on the page. To do this we need to update the PHP in index.php to iterate through them and create the required HTML.

<ol id="posts-list" class="hfeed<?php echo($has_comments?' has-comments':''); ?>">
	<li class="no-comments">Be the first to add a comment.</li>
	<?php
		foreach ($comments as $comment) {
			?>
			<li><article id="comment_<?php echo($comment['id']); ?>" class="hentry">
				<footer class="post-info">
					<abbr class="published" title="<?php echo($comment['date']); ?>">
						<?php echo( date('d F Y', strtotime($comment['date']) ) ); ?>
					</abbr>

					<address class="vcard author">
						By <a class="url fn" href="#"><?php echo($comment['comment_author']); ?></a>
					</address>
				</footer>

				<div class="entry-content">
					<p><?php echo($comment['comment']); ?></p>
				</div>
			</article></li>
			<?php
		}
	?>
</ol>

You’ll notice that if the value of $has_comments is true an additional CSS class is applied to the ordered list called has-comments. This is so we can hide the list item with the "Be the first to add a comment" message when comments are being displayed using CSS:

#posts-list.has-comments li.no-comments {
	display: none;
}

Now that all this is in place we have a functional blog commenting system. If you would like to start writing your code from this basic functioning blog commenting system you can also download the code completed up to here.

Screenshot of the functioning blog commenting system

Progressive Enhancement With jQuery

The first step in making our blog commenting system feel less like a Web page and more like an application is to stop page reloads when a user submits a comment. We can do this by submitting the comments to the server using an AJAX request. Since jQuery is probably the defacto standard for cross browser JavaScript functionality we’ll use it here. Although I’m using jQuery here, I’d also like to highlight that it’s a good idea to not always use jQuery. Instead, analyze your scenario and make a considered decision because there are some cases where you are best not to.

In an attempt to try and keep as much scripting (PHP and JavaScript) from the index.php file we’ll create a new folder for our JavaScript and in there a file for our application JavaScript. The path to this fill should be js/app.js. This file should be included after the jQuery include.

<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="js/app.js"></script>

Capture the Comment Form Submission

When the page is ready bind to the submit event of the form.

$(function() {
	$('#commentform').submit(handleSubmit);
});

When the form is submitted and the handleSubmit function is called the comment data we want to send to the server is extracted from the form. There are more elegant ways of fetching the data from the form but this approach clearly shows where we’re getting the values from and the data object we are creating.

function handleSubmit() {
	var form = $(this);
	var data = {
		"comment_author": form.find('#comment_author').val(),
		"email": form.find('#email').val(),
		"comment": form.find('#comment').val(),
		"comment_post_ID": form.find('#comment_post_ID').val()
	};

	postComment(data);

	return false;
}

function postComment(data) {
	// send the data to the server
}

POST the Comment with AJAX

Within the postComment function make a POST request to the server passing the data that we’ve retrieved from the form. When the request is made an additional HTTP header will be sent to identify the request as being an AJAX request. We want to do this so that we can return a JSON response if it is an AJAX request and maintain our basic functionality if it isn’t (for more information on this see Detected AJAX events on the Server). We also define two handlers; postSuccess for handling the comment being successfully stored and postError to handle any failures.

function postComment(data) {
	$.ajax({
		type: 'POST',
		url: 'post_comment.php',
		data: data,
		headers: {
			'X-Requested-With': 'XMLHttpRequest'
		},
		success: postSuccess,
		error: postError
	});
}

function postSuccess(data, textStatus, jqXHR) {
	// add comment to UI
}

function postError(jqXHR, textStatus, errorThrown) {
	// display error
}

Dynamically Updating the User Interface with the Comment

At this point the comment data is being sent to the server and saved, but the AJAX response isn’t providing any meaningful response. Also, the comments section isn’t being updated to show the newly submitted comment so the user would have to refresh the page to see it. Let’s start by writing the code to update the UI and test that functionality.

If you are thinking "Hang on a minute! We don’t have all the data we need from the Web server to display the comment" then you are correct. However, this doesn’t stop us writing the code to update the UI and also testing that it works. Here’s how:

function postSuccess(data, textStatus, jqXHR) {
	$('#commentform').get(0).reset();
	displayComment(data);
}

function displayComment(data) {
	var commentHtml = createComment(data);
	var commentEl = $(commentHtml);
	commentEl.hide();
	var postsList = $('#posts-list');
	postsList.addClass('has-comments');
	postsList.prepend(commentEl);
	commentEl.slideDown();
}

function createComment(data) {
	var html = '' +
	'<li><article id="' + data.id + '" class="hentry">' +
		'<footer class="post-info">' +
			'<abbr class="published" title="' + data.date + '">' +
				parseDisplayDate(data.date) +
			'</abbr>' +
			'<address class="vcard author">' +
				'By <a class="url fn" href="#">' + data.comment_author + '</a>' +
			'</address>' +
		'</footer>' +
		'<div class="entry-content">' +
			'<p>' + data.comment + '</p>' +
		'</div>' +
	'</article></li>';

	return html;
}

function parseDisplayDate(date) {
	date = (date instanceof Date? date : new Date( Date.parse(date) ) );
	var display = date.getDate() + ' ' +
								['January', 'February', 'March',
								 'April', 'May', 'June', 'July',
								 'August', 'September', 'October',
								 'November', 'December'][date.getMonth()] + ' ' +
								date.getFullYear();
	return display;
}

The code above does the following:

  • Within the postSuccess function we clear the form values and call displayComment.
  • displayComment first calls the createComment function to create the list item (<li>) HTML as a String.
  • We then convert the HTML to a jQuery object using $(commentHtml) and hide the element.
  • The comment list item is then prepended to the comments ordered list (<ol>). The list also has a class called has-comments added to it so we can hide the first list item which contains the "Be the first to comment" statement.
  • Finally, we call commentEl.slideDown() so that the comment is shown in what is becoming the standard "here’s a new item" way.

The functionality is now implemented but we want to test it out. This can be achieved in two ways:

  • The displayComment is a global function so we can call it directly using the JavaScript console of the browser.
  • We can bind to an event on the page that triggers a fake update which calls the displayComment function

Let’s go with the latter and bind to the "u" key being released by binding to the keyup event. When it is, we’ll create a fake data object containing all the information required to create a new comment and pass it to the displayComment function. That comment will then be displayed in the UI.

Hit the "u" key a few times and see the comments appear.

$(function() {

	$(document).keyup(function(e) {
		e = e || window.event;
		if(e.keyCode === 85){
			displayComment({
				"id": "comment_1",
				"comment_post_ID": 1,
				"date":"Tue, 21 Feb 2012 18:33:03 +0000",
				"comment": "The realtime Web rocks!",
				"comment_author": "Phil Leggetter"
			});
		}
	});

});

Great! We now know that our displayComment function works exactly as we expect it to. Remember to remove the test function before you go live or you’ll really confuse your user every time they press "u".

Screenshot of a bunch of fake comments

Detect and Responding to the AJAX request

All that’s left to do is update the post_comment.php file to detect the AJAX call and return information about the newly created comment.

Detecting the AJAX request is done by checking for the X-Requested-With header:

$ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');

Once we know the request is an AJAX request we can update the code to respond with an appropriate status code and the data representing the comment. We also need to ensure that the original functionality is maintained. The post_comment.php code now looks as follows:

<?php
require('Persistence.php');

$ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');

$db = new Persistence();
$added = $db->add_comment($_POST);

if($ajax) {
	sendAjaxResponse($added);
}
else {
	sendStandardResponse($added);
}

function sendAjaxResponse($added) {
	header("Content-Type: application/x-javascript");
	if($added) {
		header( 'Status: 201' );
		echo( json_encode($added) );
	}
	else {
		header( 'Status: 400' );
	}
}

function sendStandardResponse($added) {
	if($added) {
		header( 'Location: index.php' );
	}
	else {
		header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
	}
}
?>

Key points from the above code are:

  • The $db->add_comment($_POST) call returns the data from the added comment which is assigned to the $added variable.
  • By setting the response Content-Type to “application/json” we tell jQuery to convert the returned string into a JavaScript object. For more information on calling JSON Web services see A Beginner’s Guide To jQuery-Based JSON API Clients.
  • The 201 status code indicates a successful call and also that a resource (the comment) was created by the call.

The blog commenting system now works in a much more dynamic way, instantly showing the user that their comment has been posted without refreshing the page. In addition, the way the we’ve added the JavaScript based functionality to the page means that if JavaScript is disabled or a JavaScript file fails to load that the system will fallback to the standard functionality we first implemented.

Getting Real-Time—Finally!

As with any "from scratch" tutorial it can take a bit of time to get to the really interesting part, but we’re finally here. However, all the work we’ve up in has been worth it. Because we’ve built our commenting system up in a progressively enhanced way, plugging Pusher into it is going to be really easy

What is Pusher?

At the start of the tutorial we said that we would use Pusher to add the realtime functionality to the application. But what is Pusher?

Pusher is a hosted service for quickly and easily adding realtime features into Web and mobile applications. It offers a RESTful API that makes it really easy to publish events from any application that can make a HTTP request and a WebSocket API for realtime bi-directional communication. You don’t even need to use the APIs directly as there are server (PHP, Ruby, node.js, ASP.NET, Python and more) and client (JavaScript, iOS, Android, .NET, ActionScript, Arduino and more) libraries available in a host of technologies which means you can add realtime functionality to an app within minutes ‐ I’m confident you’ll be surprised just how easy!

Sign up for Pusher and get your API Credentials

In order to add Pusher-powered real-time functionality to a Web application you first need to sign up for a free Sandbox account. After you have signed up you’ll be taken to the Pusher dashboard where you’ll see that a "Main" application has been created for you. You’ll also see you are in the "API Access" section for that application where you can grab your API credentials.

Screenshot of API Access section in Pusher Dashboard

For ease of access create a pusher_config.php file and define the credentials in there so we can refer to them later:

<?php
define('APP_ID', 'YOUR_APP_ID');
define('APP_KEY', 'YOUR_APP_KEY');
define('APP_SECRET', 'YOUR_APP_SECRET');
?>

In your version of pusher_config.php be sure to replace the values which being ‘YOUR_ with your actual credentials.

You should also require this in your index.php file. We should also make the APP_KEY available to the JavaScript runtime as we are going to need it to connect to Pusher.

<?php
require('pusher_config.php);
?>

<script>
var APP_KEY = '<?php echo(APP_KEY); ?>';
</script>

Real-time JavaScript

The first thing you need to do when adding Pusher to a Web application is include the Pusher JavaScript library and connect to Pusher. To connect you’ll need to use the key which you grabbed from the Pusher dashboard. Below you can see all that is required to hook up the front-end application to Pusher.

Include the Pusher JavaScript library after the app.js include:

<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://js.pusher.com/1.11/pusher.min.js"></script>
<script src="js/app.js"></script>

Add the Pusher functionality to app.js:

var pusher = new Pusher(APP_KEY);
var channel = pusher.subscribe('comments-' + $('#comment_post_ID').val());
channel.bind('new_comment', displayComment);

This probably looks too easy to be true, so here are the details about what the above code does:

  • var pusher = new Pusher(APP_KEY);
    Creates a new instance of a Pusher object and in doing so connects you to Pusher. The application to use is defined by the APP_KEY value that you pass in and that we set up earlier.
  • var channel = pusher.subscribe('comments-' + $('#comment_post_ID').val());
    Channels provide a great way of organizing streams of real-time data. Here we are subscribing to comments for the current blog post, uniquely identified by the value of the comment_post_ID hidden form input element.
  • channel.bind('new_comment', displayComment);
    Events are used to further filter data and are ideal for linking updates to changes in the UI. In this case we want to bind to an event which is triggered whenever a new comment is added and display it. Because we’ve already created the displayComment function we can just pass in a reference to the call to bind.

Sending Real-Time Events using the Event Creator

We can also test out this functionality without writing any server-side code by using the Event Creator for your app which can also be found in the Pusher dashboard. The Event Creator lets you publish events on a channel through a simple user interface. From the code above we can see that we want to publish an event named "new_comment" on the "comments-1" channel. From the earlier test function we also have an example of the test data we can publish.

Screenshot of the Event Creator in Pusher Dashboard

Real-time PHP

Again, we’ve proven that our client-side functionality works without having to write any server-side code. Now lets add the PHP code we need to trigger the new comment event as soon as a comment is posted in our comment system.

Pusher offers a number of server-side libraries which make it easy to publish events in addition to helping with functionality such as private channel authentication and providing user information for presence channels. We just want to use the basic event triggering functionality in the post_comment.php file so we need to download the Pusher PHP library (direct zip file download).

Once you’ve downloaded this zip file, unzip it into the directory along with your other files. Your file structure will now look something like this:

  • index.php
  • css (dir)
  • images (dir)
  • post_comment.php
  • pusher_config.php
  • Persistence.php
  • squeeks-Pusher-PHP (dir)
    • lib (dir)
      • Pusher.php

An event can be triggering in just a few lines of code:

<?php
require('squeeks-Pusher-PHP/lib/Pusher.php');
require('pusher_config.php');

$pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
$pusher->trigger('comments-1', 'new_comment', array(
	"comment_post_ID" => 1,
	"date" => "Tue, 21 Feb 2012 18:33:03 +0000",
	"comment" => "The realtime Web rocks!",
	"comment_author" => "Phil Leggetter"
));
?>

However, we need to apply a some additional logic before we trigger the event:

  • Check that the comment was added.
  • Extract the unique comment identifier from the $added array.
  • Build the text to identify a channel name for the submitted comment.
  • Trigger a new_comment event on the channel with the $added data. Note: The library automatically converts the $added array variable to JSON to be sent through Pusher.

Therefore the full post_comment.php file ends up looking as follows:

<?php
require('Persistence.php');
require('squeeks-Pusher-PHP/lib/Pusher.php');
require('pusher_config.php');

$ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');

$db = new Persistence();
$added = $db->add_comment($_POST);

if($added) {
	$channel_name = 'comments-' . $added['comment_post_ID'];
	$event_name = 'new_comment';

	$pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
	$pusher->trigger($channel_name, $event_name, $added);
}

if($ajax) {
	sendAjaxResponse($added);
}
else {
	sendStandardResponse($added);
}

function sendAjaxResponse($added) {
	header("Content-Type: application/json");
	if($added) {
		header( 'Status: 201' );
		echo( json_encode($added) );
	}
	else {
		header( 'Status: 400' );
	}
}

function sendStandardResponse($added) {
	if($added) {
		header( 'Location: index.php' );
	}
	else {
		header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
	}
}
?>

If you run the app now in two different browser windows you’ll see that as soon as you submit a comment in one window that comment will instantly ("magically") appear in the second window. We now have a real-time commenting system!

But…, we’re not done quite yet. You’ll also see that the comment is shown twice in the window of the user who submitted it. This is because the comment has been added by the AJAX callback, and by the Pusher event. Because this is a very common scenario, especially if you’ve built an application in a progressively enhanced way as we have, the Pusher server libraries expose a way of excluding a connection/user from receiving the event via Pusher.

In order to do this you need to send a unique connection identifier called a socket_id from the client to the server. This identifier can then be used to define who will be excluded.

function handleSubmit() {
	var form = $(this);
	var data = {
		"comment_author": form.find('#comment_author').val(),
		"email": form.find('#email').val(),
		"comment": form.find('#comment').val(),
		"comment_post_ID": form.find('#comment_post_ID').val()
	};

	var socketId = getSocketId();
	if(socketId !== null) {
		data.socket_id = socketId;
	}

	postComment(data);

	return false;
}

function getSocketId() {
	if(pusher && pusher.connection.state === 'connected') {
		return pusher.connection.socket_id;
	}
	return null;
}

The changes we’ve made are:

  • A new function called getSocketId has been added to get the socket_id. It wraps a check to ensure that the pusher variable has been set and also that the client is connected to Pusher.
  • The handleSubmit has been updated to check to see if a socket_id is available. If it is, this information is posted to the server along with the comment data.

On the server we need to use the socket_id parameter if it is present and therefore exclude the connection and user who submitted the comment, or pass in null if it’s not:

$channel_name = 'comments-' . $added['comment_post_ID'];
$event_name = 'new_comment';
$socket_id = (isset($_POST['socket_id'])?$_POST['socket_id']:null);

$pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
$pusher->trigger($channel_name, $event_name, $added, $socket_id);

And as simple as that we have a fully realtime enabled blog commenting system and we only send messages to users who really need to see them. As with the AJAX functionality the realtime functionality has been added in a progressively enhancing way, to ensure it doesn’t impact on any other functionality. You can find the a demo running here and the completed solution in the realtime commenting repository in github.

Good Real-Time App Development Practices

Real-time application development shares common good development practices with general Web development. However, I thought I would share a couple of tips that can come in particularly handy.

Use Browser Developer Tools

When you start doing a lot of JavaScript development the browser developer tools becomes your best friend. It’s the same when adding realtime functionality to your Web app, not only because you are using JavaScript, but also because the JavaScript library you are using is likely to be doing some reasonably complex things internally. So, the best way of understanding what is going on and if your code is using it as expect is to enable logging which usually goes to the developer console. All major browser vendors now offer good developer tools which include a console:

The Pusher JavaScript library provides a way to hook into the logging functionality. All you need to do is assign a function to the Pusher.log static property. This function will then receive all log messages. You can do what you like within the function but best practice is to log the messages to the developer console. You can do this as follow, ensuring the code it executed after the Pusher JavaScript library include:

Pusher.log = function(msg) {
	if(window.console && window.console.log) {
		window.console.log(new Date().getTime() + ': ' + msg);
	}
};

The code above checks to make sure the console and log function is available – it’s not in older browsers – and then logs the messages along with a timestamp to the JavaScript console. This can be incredibly handy in tracking down problems.

Screenshot of Pusher logging in the Chrome Developer Tools Console

Check Connectivity

Any good real-time technology will maintain a persistent connection between the client (web browser) and the Web server or service. Sometimes the client will lose connectivity and when the client isn’t connected to the Internet the real-time functionality won’t work. This can happen a lot with applications running on mobile devices which rely on mobile networks. So, if your application relies on that connectivity and functionality then it’s important to deal with scenarios where the client isn’t connected. This might be by displaying a message to tell the user they are offline or you might want to implement some alternative functionality.

The Pusher JavaScript library exposes connectivity state via the pusher.connection object, which we briefly saw earlier when fetching the socket_id. Binding to state changes and implementing your required functionality is quite simple as it follows the same mechanism as binding to events on channels:

var pusher = new Pusher(APP_KEY);

pusher.connection.bind('state_change', function(states) {
	Pusher.log('Connection state changed from: ' + states.previous + ' to ' + states.current);
});

Conclusion

We’re seeing real-time functionality appearing in a large number of high profile applications: some have it at the core of what they offer whilst others use it sparingly. No matter how it is used the end goal is generally the same; to enhance the user experience and keep users engaged with an application. By converting a basic blog commenting system into a more engaging communication platform I hope I’ve demonstrated that the functionality and experience can easily be layered on existing application.

The ease of access to this technology is a relatively new thing and we’ve only just touched the potential uses for the technology. Real-time stats, instant news updates, activity streams, social interaction, collaboration and gaming are just a few common uses but as more developers become aware of, and comfortable with, the technology I’m confident that we’re going to see some truly amazing innovation. An "Internet of Real-Time Things?"?


© Phil Leggetter for Smashing Magazine, 2012.


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress