Monday, February 27, 2012

The Power of Semantics

Last month, I wrote about our attempts to build a semi-formal anatomy of Orion's common page elements. This anatomy seemed more important than focusing too strongly on a particular visual look or layouts. I also (somewhat optimistically) asserted that by the time we finish 0.4 you wouldn't have to think about this anatomy, but instead would simply think, "wow, these guys always get those links and buttons in just the place I expect them to be!"

So, how'd we do? Release 0.4 is done for all practical purposes. The M2 new and noteworthy gives a taste of what we've been up to lately, and the summary of all the 0.4 new and noteworthy should be out in a couple of days. I think it's important, though, to spend time thinking about some of our new features in terms of both "syntax" and "semantics."

In the web world, we all know about separation of styling (CSS) from the structure and content (HTML elements) on a page. But I'm talking about a distinction that goes beyond styling vs. structure. In the context of what's on a web page, I think of the styling and structure (layout, colors, fonts, buttons, graphics, words) as our syntax. The semantics are really the meaning behind that structure. Why do the various parts of the page appear where they do? How did we end up with those elements? Describing an additional level of semantics can help us not only design better pages, but provide function in ways we hadn't imagined before.

So I'd like to look at a few new Orion features in 0.4. For every screenshot of something new, I'd like to discuss not only the feature, but where we've made strides in the semantics behind it, and how this can help Orion get even better.

"New look" in the Orion page header

In Orion 0.4, you'll notice a new look. The header is divided into a skinnier common banner at the top and a taller page heading below.

Syntax

From a presentation point of view, there are many things to notice. Some are simply stylistic changes, some represent a little more thought about the user tasks and workflows.

  • It's lighter and brighter than the previous gray, more contrast at the top.
  • Different fonts and colors than before.
  • The static part (logo, navigation links, user profile) is separated visually from the dynamic part (page title, breadcrumb, etc.)
  • The static part makes the header feel skinnier, while the dynamic part leaves more room for potentially lengthy content, such as a very long path name.

Semantics

The items in the header are powered by a page anatomy. The idea here is that if a page can say a few things about itself to the common header code, the header can figure out how to present it in terms of a title, a breadcrumb, and a location. There is still work to do on the API side, but I think focusing on the structure of a page and how it influences the heading is laying the groundwork for future improvement. A page that can describe itself semantically can inherit interesting common function that goes beyond the presentation. For example, let's consider another feature in Orion 0.4 that is powered by the same idea.

"Related pages" menu

One of the usability goals for Orion 0.4 was to make it easier to move around within Orion. We wanted to identify the common workflows and make sure it's easy to move within or between pages to accomplish a task. So we've added a "Related pages" menu that gives you a handful of choices for other pages you might be interested in, based on what you are working with on the current page.

Syntax

One reaction to this feature could be, "it's about time." What's so hard about adding a link on the editor page to "Git Status" when the file I'm editing is in a git repository? I suppose we could add features like this a little faster if we just added them rather than think about them in a generic sense. But if we know that from any Orion page, there is a handful of pages that the user will likely want to go to, isn't it nice that we can put them all in place? It's useful to think about the general case when designing a specific usability improvement. But even so, that's definitely in the "syntax" realm.

Semantics

The semantics behind "Related pages" gets more interesting. It's one thing for a page to be able to list the links to pages of interest. However, Orion is an extensible system, and we don't want every page to have to consider what other pages might be around. So some semantics that allow a page to say what it is showing, and what other things it might care about, rather than just itemizing links of related pages, can let us build more interesting relationships between pages. For example, consider this "Related pages" menu from the Orion git repository page:

Here, the user is working in Orion with a git repository that is hosted at GitHub. So we figure out that one place the user might want to go is to that repository's GitHub page. This relationship can be determined because of some built-in semantics.

  • The page is able to call some common code that basically says, "hey, I'm a page that deals with repositories. Here's the URL I'm showing."
  • Another part of the code says, "I'd like to parse URLs and look for GitHub pages."
  • Finally, a related pages extension is used to establish that the "GitHub URL" command should be consulted when building the "Related pages" menu.
The way of expressing these relationships with API still needs work, but we have some pretty cool ideas of how we can make "Related pages" even more useful:
  • We could use the link scanner extension point so that any links built by the scanner in the Orion page content could also become candidates for "Related pages." For example, imagine a Bugzilla link showing up in the "Related pages" menu because you referred to a bug in your code.
  • We could develop a URL translating syntax so that plugins can more easily contribute mappings from page content to external links

Get Plugins

One of my favorite new features in Orion is the workflow for getting new plugins. Our community is growing, and more folks are writing interesting plugins. We currently don't have an "official" plugin catalog or store, but my teammate Mark MacDonald has been hosting a plugin listing on a page in his GitHub repository. We wanted to make this catalog more noticeable and reduce the steps needed to install a plug-in.

Syntax

The link appears in the banner because the orion.page.link extension is used to specify a URL that should appear in the Orion banner. The links can refer to pages inside or outside of Orion. In this particular case, the link takes the user to Mark's catalog.

Nothing earth-shattering here, but suppose we click on one of these Install links. The link takes us back to Orion, ready to install the plugin we clicked.

If you aren't paying close attention while you click these links, you might simply think that our plugin catalog didn't catch up to the new look for Orion. But the reality is that this workflow took the user out of Orion to a third-party plugin catalog, and links from that catalog were able to bring the user back into Orion at the correct page, with the correct information filled in for installing a plugin. The reason this is one of my favorite new features in Orion is that we were able to add this at the end of the 0.4 release cycle without inventing any new generic constructs.

Semantics

The semantics that allow this scenario to work have been covered in my previous blog posts, but it's kind of cool to review how they all play together in this workflow.

  • Our simple orion.page.link extension adds a link to the catalog. This extension has not been very interesting in the past because using it to link outside of Orion doesn't really enhance Orion's workflows, it just lets the user go somewhere else of interest. Kind of an "in-banner" bookmark.
  • We now provide a way for commands to describe the parameters they need so that common code can gather the information from the user. So the command for installing a plugin can now declare that it needs a URL from the user, rather than collecting it itself.
  • We now allow pages to define URL bindings. These bindings let a page establish a relationship between a token appearing in the page URL and a parameter needed by a command. That means the URL needed by the command that installs plugins can now be specified in the install page URL. So a catalog can link back to the Orion plugins page and fill in the URL that the user selected in the catalog.

Where do we go from here?

We are already talking about our goals for Orion 0.5. While there will be many priorities and features to plan, I can imagine a lot of workflow improvements we can make by continuing to focus on the semantic definition of a page.

  • We can make it simpler for a page to describe itself to the common code.
  • We can add more detail about the resource a page is manipulating. This includes defining resource dimensions that will give further control to the user for populating the page content.
  • A flexible URL translation syntax could let plugins easily describe mappings between a page's resource metadata and links to other places.
  • If we package the common header code to be more consumable, it's possible that a page like Mark's plugin catalog could consume the common header and thus more easily link back to Orion from the header and "Related pages" rather than have to know specifically how to get back to Orion.
I won't make bold predictions this early for Orion 0.5. But in my continuing pursuit of thinking about semantics so that you don't have to...I predict that our work in formalizing page semantics will pay off in workflows that let users cross in and out of Orion without even realizing it.

Thursday, January 5, 2012

Anatomy of an Orion Page

When we first started building Orion, the site had two pages, a navigator and an editor. Over the course of our release 0.2 development, we grew quite a few pages as we added function. As part of this effort, we worked on the visual design for the pages, with most of that focus being on the overall visual style of Orion and the layout of the header.

Are we anatomically correct?

For our current release, we want to put a "fresh coat of paint" on the pages, but as I've looked at some of our most problematic pages, I've come to realize that we first need to stop talking about things like "headers" and "footers" and start talking about the common, semantic elements that appear on all Orion pages. I'm not talking about HTML elements per se. If we can define and agree on the list of building blocks, then we can talk about how to represent them in the DOM and arrange them visually. The work in progress is documented on the Orion wiki. In this article, I'll describe some insights I've had while working on this anatomy.

In an extensible system like Orion, it's important to think about anatomy vs. layout because we want to allow plug-ins to contribute functionality to existing Orion pages, as well as provide links to pages from another site. When I get a bug report that says, "how can I put a link in the Orion header" or "how can I put a command on the navigator toolbar," I like to ask what the link is for and what is the user workflow, because perhaps that link belongs somewhere else on the page. Hence the focus on anatomy vs. visual layout boxes.

The current list of body parts (no pun intended) is something like this. (The wiki page will be kept up to date with our thinking and explanations of each.)

  • Branding
  • Legalese (the fine print)
  • Discovery links
  • Expected links
  • User Info
  • Notifications
  • Search
  • Task (static page title)
  • Resource
    • Dimensions
    • Hierarchical Location
    • Name
  • Related Task Links
  • Task+Resource (Page) Level Commands
  • Resource View Controls
  • Resource Content

Here's a picture of how these elements might be organized on a page. (Note this is an anatomical picture, I'm not proposing that the Orion header adopt ice cream colors.) Most (all?) sites put the branding on the top left corner and legalese at the bottom, but of course if we stick with semantic definitions when structuring a page, this doesn't have to be true.

Some insights

The body parts that might need some explaining are the ones where I've learned something about our page anatomy and have attempted to use terminology to further qualify an element.

A link is a link is a link?

With links, I find it helpful to differentiate links by thinking about their scope and purpose.

  • Discovery links are there so the user discovers pages that are helpful in the overall site workflows. If you are coding js in Orion, perhaps you'd like to know about "site xyz." (Hmmm....as I type this explanation I realize I haven't mentioned "advertisement" in the anatomy.)
  • Expected links are links you might need to find someday, but you'll expect them and be willing to go looking for it. For example, how do I get support? How do I open a bug?
  • Related task links are links that are directly related to what you are doing. For example, if you are looking at the git log for some repository/branch, it's highly likely you might want to see the git status for that branch.
We also have links that represent commands. These are buttons or links that let you act on a specific thing on the page. But the scopes, placement, and visual representation for these commands will be a future topic, so let's ignore them for now.

A resource by any other name?

Another discovery for me is that it's not enough to talk about "the resource" that a user is operating on. I'm not talking about the page resource/URL, I'm talking about the way the user thinks about the resource they are working with. At a minimum, a resource has a fully qualified (hierarchical) location and a name. But if you add version control to the mix, then you might also want to talk about a particular version of that resource, or perhaps a particular repository. I'm still looking for a better word, but for now I call these dimensions.

Allowing the user to consistently find (and change) dimensions can help the usability of our workflows. Let's take a specific example involving git. Today, in the Orion editor, I can be happily editing my js file. I can even use the breadcrumb to open a navigator within this hierarchy and find related files. But why can't I switch to another branch from the editor? We could hard-code a "switch branch" command into the editor page in the toolbar, but if we instead generalize this idea and have a way to show, and switch, dimensions in a common place on the page, then it will be easier for plug-ins to contribute dimensions and for users to have a common place to go to switch the resource content on the page.

Drilling down

The high level anatomy mentions "Resource Content" but we know there all kinds of ways to represent something, depending on how complex it is. The following terminology helps me talk about the different styles of pages we have:

  • A single content area is appropriate when a resource is best viewed as a unit. The Orion code editor is a good example of a resource that is best viewed with a single content area. Sometimes I think of it as "the real body of the page."
  • Sections organize the view of the resource into separate pieces, so that you can work with different aspects of a resource at a time.
  • Outliners help to navigate a content area. For a single content area, they may simply move the content in a structured way (like the editor outliner). For a resource organized in sections, they may navigate the sections (or help you to swap sections in and out on a page).

By formalizing the sectional nature of pages, we can make it easy in the future for plug-ins to contribute additional sections to a page, provide common places for the user to find commands that apply to a particular section, and common controls for expanding/collapsing or organizing sections.

HTML5: to section or not to section?

When I use the word "section" above I am really talking about a way to organize the viewing and manipulating of a resource. But I didn't want to use that word if it didn't jive with the notion of an HTML5 section. So I checked the HTML5 spec for guidance regarding HTML section elements, and I think this is the right word to use, and that we will end up with HTML5 sections as the tags for these elements on the page. In particular, the spec says, "A general rule is that the section element is appropriate only if the element's contents would be listed explicitly in the document's outline." That seems to hold up to the way we are using them.

What does this mean to our technical page architecture?

I'm not sure yet, but of course I'll guess.

  • For plug-in developers, we'll formalize our markup surrounding sections and how to describe them in a plug-in. I don't think we'll have plug-ins contributing sections per se in Orion 0.4, but I think we'll start down an implementation path that will make that possible. And we'll probably see a plugin's preferences rendered in a section on the preference page.
  • Inside the Orion implementation, I'd like to see the javascript code talking about the page in terms of tasks and task types, path, name, dimensions, etc. Some common code can map this information to a header (or footer) template, the breadcrumb, etc. If we decide we like combo boxes for changing dimensions one day, and later decide to use drop down menus, it shouldn't be the page's concern at all.
  • Having isolated our javascript code from the common templates, the page implementation code shouldn't even care how the DOM is structured in particular. But long run, it'd be nice to see the Orion page template get simpler, using HTML5 body header, footer, and sections within. Then "something outside the page" (CSS? JS? both?) can apply that to a layout that makes sense for the particular Orion installation, without mandating a particular JS library or approach for making that happen.

What I do know is that in Orion 0.4, it will be easier for you to move between pages in your workflow. And in part, that will because of this anatomy and its corresponding implementation. But while you are using Orion, I don't want you to think about that. Hopefully, you'll just instinctively know how to find what you are trying to do, and think, "wow, these guys always get those links and buttons in just the place I expect them to be!"

Sunday, November 20, 2011

Linking to the power of Orion

In my last post, I mentioned our Orion command framework, which allows our pages to define the commands that a user can run on a particular page. We were evolving the command definition to include the specification of what parameters it requires.  While I focused more on the UI in the last discussion, now I'd like to talk about how this concept will allow you to link to Orion in interesting ways.

Let's follow a simple example.  One of the things a user can do from the Orion Git Repositories page is clone a git repository into an Orion folder. In the first iteration of the command framework, any work done after the user clicked the "Clone Repository" link was done in the command's callback.

cloneGitRepositoryCommand = new mCommands.Command({
 name : "Clone Repository",
 tooltip : "Clone an existing Git repository to a folder",
 id : "eclipse.cloneGitRepository",
 callback : function(item, commandId, domId, userData) {
  var dialog = new orion.git.widgets.CloneGitRepositoryDialog({
   serviceRegistry: serviceRegistry,
   fileClient: fileClient,
   func: function(gitUrl, path, name) {
     // do the real work
   }});   
  dialog.startup();
  dialog.show();
 }
});

But now we allow the command to specify that it requires a URL parameter. We also indicate that there are additional parameters that can be collected if the user wants to specify additional options. (These snippets are intended to show you how things work, but this interface will certainly change before the next release milestone.)

var cloneParameters = {};
cloneParameters.url = {label: 'Repository URL:', type: 'url'}; 
cloneParameters.options = true;  // indicate that we could collect additional options 

cloneGitRepositoryCommand = new mCommands.Command({
 name : "Clone Repository",
 tooltip : "Clone an existing Git repository to a folder",
 id : "eclipse.cloneGitRepository",
 parameters: cloneParameters,
 callback : function(item, commandId, domId, userData, parameters) {
  if (parameters && parameters.url.value) {
   // do the real work
  } else {
   // we could trigger a dialog to get the parameters, or report an error, etc...
 }
});

So far, we've just defined a command. Nothing is going to show up in the UI until we register a command contribution on a page. In the contribution, we can specify the DOM node where the command should be shown, such as a toolbar, and a key binding that can be used to trigger the same command via the keyboard. But the fun really starts now that we allow a URLBinding to be associated with a command. With a URL binding, a page can define a URL (fragment) query parameter that can be used to trigger command, and the parameter name of any value provided in the URL. For the clone command, the URL binding looks like this.

var urlBinding = new mCommands.URLBinding("cloneGitRepository", "url"));
commandService.registerCommandContribution("eclipse.cloneGitRepository", ..., urlBinding);

This means that the query parameter cloneGitRepository should trigger the command, and the value in the URL should be bound to the url parameter in the command. From Orion's point of view, opening the Git Repositories page with the following link calls the same code as if the user had clicked on the command in the UI and typed in the URL:

http://orion.eclipse.org/git/git-clone.html#/workspace/H?cloneGitRepository=ssh://myId@github.com/path/myId.github.com.git

One important note. A command invoked by a URL binding is not called by this URL. Rather the page is opened in a state for collecting the parameters. We just prefill the parameter information, and the user can hit the Enter key to start the clone, or click the More button to provide additional information. Our URL needs to be a stable GET. Reloading the URL multiple times should never alter the state of the resource on the page. So user intervention is always required in order to actually invoke the command. The URL binding, much like a key binding, simply gives the user a shortcut for starting the process.

We think the URL binding is a powerful concept. It allows us to start exposing linkable bits of function in a way that is completely separate from the code that defines the function. Being able to specify parameters in the URL syntax means that some other site can use its own logic to figure out what the user wants, and then link to an Orion page, providing contextual information.

Our favorite simple example is a bugzilla page that could use the product and component information in the bug definition to figure out which git repository the user might want to clone to look at the code. Another idea is the ability to author "cue card" style help systems that could guide the user through some set of tasks in Orion, simply by linking to the various commands involved in the steps.

We can't wait to see what you might do with this idea.

Monday, November 7, 2011

Collecting Bits of Input

I've been looking around lately at the way different sites collect input when performing a task, and how we can do better in Orion.

For the time being, I'm ignoring the main input task in Orion - editing source code. And I'm not talking about a form-based UI where describing or creating something is the main task at hand.  Often, we just need a little bit of info (a name, a URL, a password) in order to do something. In Orion, we have a grab bag of techniques for collecting this kind of input.
  • Some times, we just put an input field near the place you are working.
  •  When we need to know more than one thing, or want to provide additional options, we open a dialog that collects parameters.
  • In some cases (where we were doing something quick and dirty), we rely on the browser's prompt dialogs.
These subtle differences can burden a user over time. We have learned in our years working on Eclipse that the best way to ensure some consistency is to provide code that does the right thing. Reducing the burden on the developer helps the user, too.

We have a command framework in Orion that lets pages define commands that the user can run on a particular page. This allows us to separate the presentation decisions from the work performed by the command. For example, if you want to define a command that should be available on files in the Orion navigator, you can describe the command and provide code that does the work, and we are free to play around with where and how the command appears. Is it a button or a link? Is it text, icon, or both? Does it appear on hover or is it always there? Where on the page does it appear (in-line, in a menu or toolbar, in the banner?) The presentation decisions can evolve without a lot of hassle for developers who contribute these commands. (I'll write another post soon about how we see our page layouts evolving in this area.)

This all sounds good, but today, we currently rely on the handler, the code that performs the command, to gather parameters. For example, when you press a "New File" link, the handler code is the one prompting you for the name and creating the file. This has its share of problems, though, and some of our new release goals for Orion 0.4 add more excitement:
  • As we've seen, it means that different commands collect parameters in different ways, causing a little extra thinking by the user.
  • We're finding that dialog placement and interaction can be problematic on tablets, and even more problematic when an on-screen keyboard pops up to collect input.
  • We want to explore scenarios where a link from some other site leads you to an Orion page that requires input. So the way we gather input needs to be even more visible and predictable when you arrive at a page that's already asking for something, without being overly disruptive when you are already working on the page and need to answer that same question.
  • We need to make sure the solution is accessible. So using a common implementation can help us focus our efforts here (pun intended).
If we can instead allow a command to describe the parameters it needs to collect, we can then provide a consistent, appropriate presentation for gathering that input. Perhaps we'll come up with a way that plays well in all the scenarios we want to support. We might instead learn we need different presentations for these different situations. From the command handler's point of view, though, the implementation won't get called until the necessary input has been gathered.

I'm currently working on a first stab at this idea. From a presentation point of view, I started out with some ideas that I'd like to validate:
  • The "form" or "dialog" that collects input should be inserted in the DOM vs. overlayed as a modal dialog or slideout. I think this can help with zooming and scrolling issues on tablets.
  • There should be enough animation that a user arriving at a page for the first time notices right away where the input is needed. But the animation should be fast and well supported on different devices, so I'm using CSS3 transitions rather than a JS library.
  • Parameter types should be described using HTML5 input types. This means the browser can optimize the input control, and for some devices, it can mean customized keyboards (numeric, URL) that make input faster.
  • For added fun, my first implementation adds the speech attribute to the input field so that parameters can be spoken. If we can avoid popping up a keyboard altogether, that might make providing simple input much faster. For complex forms and dialogs, it might be a silly idea, but it makes for a fun demo right now.
My first try uses a slide-in parameter collector. I haven't spent much time on cosmetics, so expect it to look snazzier once our graphic designer gets a look at it. In the three cases shown above, the input is now collected by the command framework, in the same way (location depends on where the command appears.)
Go to Line parameter collector (with spinner courtesy of "number" input type)
 
New File parameter collector (speech enabled)
Git Clone parameter collector
I'm not done with the code yet, but I hope to release it this week and get more user feedback on how it plays. In the meantime, I'm wondering if you've seen a technique somewhere that you like, that you think would meet similar goals?

Monday, September 26, 2011

Instant Thoughtlessness in the Cloud

I don't want to be thoughtless in an inconsiderate way.  Just the "don't make me think" or "thoughtless acts" kind of thoughtless.  I hate thinking about my tool when I'm trying to do something, so I like it when I have thoughtless experiences. I'm hoping to help bring more of the good kind of thoughtlessness into Orion.

Last week, I returned from a summer-long leave of absence from IBM, where I work on Orion and Eclipse.  As I left, we were just finishing up our first Orion release, 0.2, and some of the workflows were pretty new designs and just being wrapped up.  I had this rather strange workflow for releasing code into our git repository, which involved a combination of msysgit, both command line and git gui, combined with Orion's rapidly evolving git interface. I didn't like the workflow, but it had grown up from the time that we had no git UI in Orion, slowly moving workflows into Orion, and also working around bugs by jumping to the command line or git GUI when I didn't quite trust a build. 

Last Monday I was ready to get familiar with the code again, see how Orion had evolved while I was gone, and try to contribute something to our 0.3 release.  I could barely remember my odd workflows, where I had installed msysgit, what was in my Eclipse workspace, or what build of Eclipse I was using to run the Orion server before I left.  In the old days, I would have searched around for the current I-build Eclipse update repos and decided whether to download a new SDK or just update my Eclipse (depending on what might have changed since I was gone).  I might have started to re-synch my workspace, before realizing that I needed to build a new one since the Orion code repository had moved while I was gone.

But Monday was different.  I fortunately remembered my orion.eclipse.org login.  I logged in, deleted my old folders, and cloned the Orion client repository.  I searched through the Orion bugs to find a simple feature I could implement.  I added the feature, tested it on an Orion site, committed it, and pushed to the repository.  I had one slight hiccup because I had pasted the wrong git repository URL (with an http protocol rather than ssh).  So I had to ping a coworker to help figure out where to change that.  He was surprised I was already pushing code so soon.

It was a sweet reentry.  No downloading, no upgrading, no re-synching.  Just jump right into the cloud and produce something.

It's been a week now and I have yet to explicitly download a tool to do my work. Nice....and thoughtless.