January 2007

Our new rule about icons

So, Webmin is a very icon-heavy product. There are several hundred icons in the default Webmin theme, and the first iteration of a Virtualmin theme. We had loads of new icons drawn by David Vignoni in the style of his Nuvola icon set, and I’m happy to recommend his work to anyone and everyone. He’s among the best icon guys working today. But we’re done with icons in Virtualmin. Mostly.

The problem with icons, as I intuitively knew, but had explicitly pointed out to me by Evan, the designer on the SocialMoth team, is that they introduce a new language to your application. When the elements are well-known icons, or mild derivations, it’s not a problem and might even enhance the users comprehension. But when everything has an icon and the icon takes the focus away from much clearer language, it’s just confusing. So the last several iterations of our Virtualmin themes have been moving away from introducing new iconography for every element of the interface, and we’ve also been spending some time on testing and clarifying the text to be more clear and concise.

Just in case you’ve never seen the old Webmin icon model, here’s a shot:

Whoah! Too many icons!

Crazy, huh? Sure, part of the problem is the uglitude of the art-work. Jamie’s never been accused of being a great graphic artist. So, my focus for many years was replacing the icons and the colors with something nicer. I believe it even looked pretty good by the time of the Nuvola versions of my themes. But it didn’t solve the problem caused by so many icons…new language that the user had to learn while using the product. Sure, everything with an icon also had a text description…but it’s clear that many users also took time to make sense of the icons.

So, the rule in our new design is “icons only when they represent well-understood concepts in well-understood ways, and maybe when they don’t get in the way and make things look nicer”. This is the only place, so far, where I’m convinced that icons aren’t doing harm, and its even one of the few spots we didn’t have icons in the previous theme:

A few icons, tastefully placed.

So, we’ve got a “home” icon, well-recognizable as such, to send users to the default first page which shows lots of stats about the system. Then we have an edit button…looks like all edit buttons ever, for editing the selected domain; a mail and FTP users icon that looks like users; a databases icon that looks like the database icon in several products on Windows, Mac and Linux; and finally, the Install Scripts link has an icon showing a page with code brackets (this one might be a slight stretch, since we can install scripts other than PHP scripts…and only PHP uses <> in a manner similar to HTML, but it’ll have to do, since nothing else is generic enough to encompass all languagses). I don’t believe it will slow folks down, and will probably help a bit, but if user testing proves otherwise, it’ll be gone before you know it.

Development

Comments (0)

Permalink

Information organization for users, not developers

As mentioned in the past two posts, we’re overhauling the interface of Virtualmin to make it easier, faster, more intuitive, and better looking. Recently I’ve been moving things around on the page and putting them into human comprehensible categories. Historically, the items in our left-hand menu, for example, were laid out in a way that was easy to code–alphabetically sorted, and pulled automatically from various Webmin modules. foreach is such a powerful construct that it’s tempting to write everything such that we can use it to build everything in the UI. But it’s not so intuitive for users…so, we’re in the midst of writing more code to accommodate a more user-centric layout (of course, we’re not looking to suffer, so we’ve figured out a way to make the modules give us back the information we need in our foreach loop).

So, without further ado, here’s where we were yesterday:

Menu midway through categorization

As you can see, if you’ve been following along, we’ve added sections to the left-hand menu to make it clear which menu items apply to the selected virtual server, and which apply to the whole system. This was the very low-hanging fruit. Very little code, very little effort, but quite an improvement–many users had a hard time grasping which sections applied to what part of the system, and I believe this will relieve much of that trouble. The added white space also makes it easier to read.

But, now, we need to address that Virtual Services and Logs menu. It’s a hodge podge of unrelated items, that show up in the same place merely because the software knows about them in the same way (these are auto-discovered at runtime based on user privileges and the enabled features of the selected virtual server). To fix this problem, we need more data than is current available, so we had to modify the Virtualmin module, as well as the theme code.

In Virtualmin, we’ve added a ‘cat’ field to the associative array that define various module actions:

push(@ot, { 'mod' => $1,
    'page' => 'index.cgi',
    'desc' => $minfo{'desc'},
    'cat' => 'webmin',
    'other' => 1 });
}

Now our theme can discover the category for any given action at the same time it pulls all of the other information. The same bit kind of category data has been added to all of the Virtualmin plugin modules, like this feature_links function in the DAV module:

# feature_links(&dom)
# Returns a link to the DAV module for this domain
sub feature_links
{
local ($dom) = @_;
return { 'mod' => $module_name,
   'page' => "index.cgi?dom=$dom->{'id'}",
   'desc' => $text{'index_desc'},
   'cat' => 'services',
       };
}

Hmmm…It’s probably worth writing a whole post just about the menu management and writing a “discoverable” plugin for Virtualmin…but we’re on the UI today, so let’s keep moving. So, now that we can categorize all of our links automatically, let’s add those smarts to our theme.pl.

Originally, in the screenshot shown above, we had this code:

  # Feature and plugin links
  @links = &virtual_server::feature_links($d);
  @flinks = grep { !$_->{'plugin'} && !$_->{'other'} } @links;
  @plinks = grep { $_->{'plugin'} } @links;
  @olinks = grep { $_->{'other'} } @links;
  &print_category_opener("vservlog", \@flinks,
    $text{'left_virtualservicesandlogs'});
  foreach $lt (\@flinks, \@plinks, \@olinks) {
    @notlt = grep { !$donelink{$_->{'mod'}} } @$lt;
    if (@notlt) {
      foreach $l (sort { $a->{'desc'} cmp $b->{'desc'} }
           @notlt) {
        &print_category_link("$l->{'mod'}/$l->{'page'}", $l->{'desc'});
        $donelink{$l->{'mod'}}++;
        }
      }
    }

Which iterates over each item in three different arrays. You might think, looking at this, that we could categorize based on the arrays that contain them. And that was what I was tempted to do at first…but those arrays are organized by the underlying code. So plinks and flinks and olinks can contain related items. One could be a core Webmin function to edit the Apache virtual domains owned by the virtual server account, while another could be the same kind of link to a Webmin module but for viewing logs. Since we believe users would make the most sense out of a “Logs and Analysis” category and a “Services” category, we’re gonna have to split those up. Thus the Webmin module links that view logs will be in the logs category, while the services such as BIND and Apache will be under the Services category. The neat bit is that every new plugin can automatically put itself into the right place just by filling in one extra field in the feature_links hash.

Post categorization

So that’s what it looks like once converted…and here’s the code:

  @links = &virtual_server::feature_links($d);
  my @cats = &unique(map { $_->{'cat'} } @links);
  foreach my $c (@cats) {
    my @incat = grep { $_->{'cat'} eq $c } @links;
    &print_category_opener("cat_$c", \@cats,
      $virtual_server::text{'cat_'.$c});
    foreach my $l (sort { $a->{'desc'} cmp $b->{'desc'} } @incat) {
      &print_category_link("$l->{'mod'}/$l->{'page'}",
               $l->{'desc'}, undef, undef,
               "right");
      }
    &print_category_closer();
    }

Interestingly, it’s a little shorter…Jamie seems to have refactored a few bits when he converted the code to supply categories.

Development

Comments (0)

Permalink

A little usability goes a long way

As mentioned in yesterday’s post, I’m overhauling Virtualmin’s UI in a major way. It’s not just visually boring, it’s also got a few usability problems. While our product requires fewer (sometimes a lot fewer) clicks and forms to accomplish almost everything available in any of our competitors, we sometimes find folks struggling to make the connection between what our product is capable of and what they want to do. So usability improvements are going to be a core part of what this conversion is all about. Since I’m already writing a lot of code and replacing a lot of functions, I might as well get right with Usability Jesus in the process.

First up is a very simple change, recommended by this study. In short, our labels are left aligned and the fields are way over in the next table data element, and so we need to get the label right on top of the field. This should make scanning the forms faster.

Here’s the before:

Screenshot before the realignment of field and label

And here’s the after:

Screenshot after the realignment of field and label

Subtle difference, but I do believe it scans quite a bit faster. It probably needs a little bit of cleaning up to make it look less crowded…you get a lot of “free” whitespace with the table element aligned layout that disappears when the table data sections go away.

There’s still more to be done with our forms, based on data from this study alone, as it seems our forms follow all of the “worst case” choices covered. But, this one has been a sore spot for me for some time, so it comes first. I’ll cover the rest of the transition in another post.

Development

Comments (0)

Permalink

Getting that AJAX religion with YUI and yui-ext

I was demoing our product for a couple of pretty smart guys last week. One of them pointed out that it would be greatly improved by having better web design. I believe the phrase was something along the lines of “technologists aren’t necessarily the best designers”. So, when I went home, I took another look at things with fresh perspective. And I didn’t like what I saw. The problem is that I’ve been incrementally improving the appearance of Webmin for seven years or so, via icon replacement and mild CSS theming. Another round of that resulted in the current version of the theme, which has some reasonably functional improvements: a left-hand menu with JavaScript expansion, great icons by David Vignoni, and a lot of CSS styling to make it all seem less clunky and old-fashioned. Jamie was so enthusiastic about some of the changes that Webmin now has a version of it as the default theme (this doesn’t happen very often, as Jamie is relatively slow to adopt new client-side technologies in Webmin because they can prevent folks from using it).

Here’s a picture of the current version:

Screenshot of the pre-YUI Virtualmin

Pretty stark and white, huh? Not really much to get excited about. But so much better than the old standard Webmin themes that it always seemed pretty good. It’s all about perspective…I just had to look around at other web-based interfaces to see that I had been shooting for the wrong target, “better than it is now”. Instead, the only sane thing to do is shoot for “as good as the best on the web”.

To do that we’ll need AJAX, obviously. New stylesheets. And a lot of grunt work to transform Webmin’s table-based layouts into a pretty, clean, and style-able form.

AJAX

In the past, when we needed some dynamic elements on the page, I wrote it myself. Since I didn’t speak JavaScript very well, this meant almost no JavaScript was used. We had collapsing menus and elements, and Jamie wrote a few form validation elements. But mostly, we were living in an AJAX-free zone. No more.

I’ve looked at JavaScript libraries in the past, and marveled at how far the little language has come, but as of this past weekend, I’ve drunk the Kool-aid. I’ve added the Yahoo! UI library and the yui-ext libraries by Jack Slocum to our pages. Every element on every page is getting a makeover. No page, no UI component, no input field, no database display, no address box, nothing in our UI will be left unturned. First step was to convert the front page to make use of Jack’s layout functions in yui-ext.

Here’s the code for the layout:

   Layout = function(){
          return {
              init : function(){
                 var layout = new YAHOO.ext.BorderLayout(document.body, {
                      north: {
                          split:false,
                          initialSize: 35
                      },
                      west: {
                          split:true,
                          initialSize: 200,
                          titlebar: true,
                          collapsible: true,
                          minSize: 100,
                          maxSize: 400,
                          tabPosition: top
                      },
                      center: {
                          autoScroll: true
                      },
                      south: {
                          split:false,
                          initialSize: 24
                      } 
                  });
                  layout.beginUpdate();
                  layout.add('north', new YAHOO.ext.ContentPanel('header', {fitToFrame:true}));
                  layout.add('west', new YAHOO.ext.ContentPanel('wmnav', {title: 'Webmin', fitToFrame:true, closable:false, autoScroll:true}));
                  layout.add('west', new YAHOO.ext.ContentPanel('vmnav', {title: 'Virtualmin', fitToFrame:true, closable:false, autoScroll:true}));
                  layout.add('south', new YAHOO.ext.ContentPanel('statusBar', {fitToFrame:true}));
                  center = layout.getRegion('center');
                  center.add(new YAHOO.ext.ContentPanel('right', {fitToFrame:true}));
                  layout.endUpdate();
             }
       }
 
  }();

And here’s what it looks like:

Virtualmin theme built on a yui-ext layout

Pretty slick, huh? Of course, there’s also a big bundle of style sheet changes in the right hand content pane, and you’re also seeing a conversion of the menu in the left hand pane to a yui-ext tree (which needs new images), but the layout alone is a miraculous change in the feel of the app.

Over the next week or two I’ll be covering each of the steps I make in transforming our rather large application from a traditional CGI web app to a wholly AJAX-ified, interactive, rich user interface…stay tuned.

BTW-If you’re learning JavaScript, I found the videos by Douglas Crockford at the YUI Theater absolutely priceless. In about four or five hours, I learned enough about JavaScript to begin writing my own extensions to yui-ext. I’m a JavaScript slinger extraordinaire now, all thanks to Doug’s videos.

Development

Comments (5)

Permalink