Wednesday, August 31, 2011

Widgets And Frameworks

Web frameworks are important because today, the target user environment is the web.  Why is this?  Because the web means anyone can use your application.  There are no barriers to installing the software and no restrictions on the hardware.  All the user needs is a decent web browser.

The web application framework itself is relevant because it enables developers to write solid software by reusing common components.  Common patterns used in all web applications.  Without these tools supplied by the framework, nothing would ever get off the ground — a diffuse time to market for smaller development teams.

What patterns are used in web frameworks?  Database connectivity, URL mapping, authentication.  The list goes on, each framework providing their own flavor of these major components.  Each is considered a pattern because any web application needs to implement it.  This quickly burdens the developer.  The role of a web framework is to parameterize these patterns and make them accessible.

What role do widgets play in web application frameworks?  By widgets, I mean standalone Javascript toolkits that have a selection of cool user interface stuff.  This includes jQuery UI, Dojo, and ExtJS.  Making these Javascript widget tool kits — which are a framework on their own — integrate seamlessly into our web application frameworks is disjointed to say the least.

Not an easy fit
Web application frameworks don't give us all the front-end browser code necessary for a finished product.  If it were a matter of delivering only HTML and CSS to the browser, we'd be all set.  This isn't the case unfortunately.  Not if there is any kind of user interaction involved — which is almost certainly the case.  For the kind of experiences users have come to expect, developers need to employ Javascript or Flash technologies.

In theory, building these rich user experiences is fairly straightforward — alter the HTML templates and serve the additional resources — Javascript, Flash, etc.  This can be achieved without any headaches — granted the project is a small one.  There many resources to worry about, not as big a user base compared to something enterprise-grade.  Every aspect of the software is scaled back slightly — and so the cause for error is scaled back accordingly.  For example, having a very large Javascript file or dozens of smaller Javascript files can be hard to maintain.  Not on their own — but because Javascript is different — it depends heavily on the DOM.

So as far as the development process goes, we need sound approach to ensuring there is some degree of coupling between individual HTML templates and their corresponding Javascript modules.  The days of implementing a monolithic Javascript file are quickly leaving us behind.  Especially if given the challenges of managing external widget library dependencies.  Imagine an application with a hundred or more HTML templates — I can't think of an optimal method where a single Javascript module suffices.

Technically speaking, uniting widget frameworks and web application frameworks wouldn't be overly strenuous.  All this entails, and this is generally how they're put together now, is serving new resources and having your HTML content ask for those resources.  The place where widgets don't fit seamlessly into the web application framework is in the back-end the web application.  How does a given view or controller (whatever the framework terminology alludes) know about which widgets are used?  Are these widget configurations persistent?  For that matter, are they configurable at all from the web framework?  For me this is a problem — widgets are a big part of the overall picture — web application frameworks should accommodate widget frameworks.

Frameworks and forms
A crucial feature of any software with a web user interface is forms.  Forms collect user feedback.  They can be simple — a single input field and a submit button.  They can be complex — a registration form that nobody in their right mind would fill out.  Web application frameworks do a pretty good job with tools that both render and validate forms.

There is good reason for.  Web frameworks define the database schema for the application.  The database is populated by user input.  Forms.  There is an obvious connection between the two concepts — this is why frameworks take great care to supply the database with what it expects.

Take Django for example.  The Django framework has a forms module that'll assist with defining forms, the validation, and rendering the form widgets for the browser.  Not unlike how Flask uses WTForms to validate and present forms.  The Pylons project also provides developers with form processing capabilities — they require a little more effort than the other Python frameworks.

What really stands out is the connection forms and their individual input widgets have the framework itself.  They're an essential ingredient to the application — a formative piece of the database.  There is a mapping between the database schema and what is presented to the end user so they can populate it.  This fits perfectly with the ideal of the web application framework — to take a pattern and expose it as a cohesive API for the developer.  This concept is further exemplified by Django where we're able to point the form subsystem to a database model and let it figure out how the form should be rendered and validated.  This isn't so easy with more general widgets that aren't necessarily used for collecting input and storing it.

Widgets and data
If we're able to utilize the framework form processing tools to store data, how does the framework help us present data to the user?  Well, since a web application framework is only responsible for delivering the content to be rendered by the browser, all we've got is templates.  These assist in generating the markup necessary for displaying fancy Javascript widgets.

For instance, a common user interface pattern is to group logical categories using tabs.  Tabs are visually appealing and allow for intuitive navigation.  This is a top-level layout widget — meant to replace a typical sidebar navigation item.  Or consider a smaller widget — a progress bar.  This type of widget, unlike tabs, isn't a layout container.  It displays something specific about the application data.

What both layout container widgets and smaller application data widgets have in common is that they both depend on specific application details that reside on the server, within the framework.  The tabs widget needs to know what specific tabs to display and what content within each tab.  The progress bar widget probably depends on a computed number — derived from user data from the database.  So what is the preferred approach to displaying both widget types in any given application?

Navigational constructs are typically done in the template.  Maybe there is a nested div and a tag structure the Javascript widget is expecting — like the jQuery UI tabs widget.  However, the developer still needs to instantiate their widget when the page loads.  This means that the Javascript code needs to know about the template and what the rendered HTML output will look like.  This is somewhat error-prone as the developer will need to maintain dependencies between the Javascript widgets and the HTML structure they're expecting.

More challenging is the application user data presented by widgets — like a progress bar.  The progress bar needs the value to display — but where does it come from?  This might be a JSON response, returned from one of the application controllers.  Again, as with defining layout widgets, the problem lies in maintaining the connection between what the Javascript widget is expecting to see and what the framework delivers.  The problem isn't so much technical — it is more of a design problem.  One that leads to a loosely coupled system.  Too loose.

Solutions and challenges
Web frameworks already do a great job of taking common patterns on the server and making tools developers can use to efficiently develop code.  Might it be that web application frameworks have no business managing widgets?  Should this task be left to the templates and other static files?  I think there are patterns we're missing here that can be taken advantage of — it's still only an emergent thought.

One benefit to having the framework manage the connection between application data and widgets is the potential to be widget framework agnostic.  There are a lot of widget tool kits out there and a lot of similarities between them.  The commonalities across all toolkits — these are the interesting widgets.  The basic widgets that all web applications use in one form or another could potentially be integrated into web frameworks.

What might we do with the layout widgets to help standardize and improve the coupling between Javascript and framework data?  After all, layouts, if they can be standardized in some fashion, are a valuable asset.  You'll generally have a web application framework of choice and you'll almost certainly be creating more than one application.

I think layout widgets — stuff specific to the user interface and not necessarily what the application does — will be easier for frameworks to implement.  If the framework is able to introduce the concept of a widget, maybe storing it's configuration, then properly outputting the required markup and the required Javascript isn't a stretch.  For example, the configuration for a tabs widget would store what tabs are actually rendered, the contents of each tab, and should produce the necessary Javascript to instantiate it.

Widgets specific to application data — like a grid — aren't as easy.  This is because they're more toward what the application does.  Another challenge is that widgets generally depend on some data source like JSON that is generated from the user data.  This isn't so easy to stardardize on.  The framework would have to know about the data schema in addition to the visual configuration.  This means the application would have to store configuration that dictates what the widget will look like, where to get the data it needs, and how that data should be interpreted for presentation.  Not impossible, just more challenging.

Perhaps a good start to making web application frameworks a little more aware of patterns in how browser widgets interact with the framework itself is to discover patterns you're using.  How would you benefit if you're able to store some configuration that defines how and what the Javascript widgets do?  Every application is different — and so every combination of widgets used brings a new set of challenges.  This is how we make progress and is how the current features of frameworks came into being — by experimentation and pattern discovery.

Friday, August 19, 2011

Drivers Of Cloud Technology

Who ultimately makes the decisions on what features cloud service providers make available?  It isn't as though these folks base these decisions on what customers actually need, is it?  We'd certainly like to hope so anyway.  At the very least, service providers should build features that reflect the characteristics of our favourite applications and frameworks.  Maybe this is in the form of appliances — pre-configured components that play a small role in an application's architecture.  Software should be the driver of cloud technology.

Amazon's EC2 is the best example of a cloud technology derived from another domain.  Amazon built EC2 as a product because they were able to reflect on the challenges they themselves faced with building large and complex applications.  They saw what the future of cloud computing looked like not only for Amazon, but for almost every other technology company in the world.  Only now is Amazon associated with technological prowess — a far cry from their core business only a few years ago.  Go figure — a book store played a key role in what cloud offerings look like today.

Cloud technology derived from a domain — an online store — is one avenue to innovation.  Another is the technology that utilizes the cloud.

But is this in fact a motivator for mature cloud service providers?  Are they paying attention to the consumer technology taking advantage of cloud services?  See, a key issue with cloud stuff is over-generalization — trying to satisfy every single use case with only a handful of features.  I think part of this conundrum is with virtualization — how the providers can opperate profitably.  It doesn't cost providers much in the way of overhead to spin up new virtual machines.

These virtualized, on-demand environments are ideal if you need these resources and that the provisioning of these resources can be automated.

What I think is missing from the big picture here is the consumer application.  Actually, forget about that — what about the application framework?  Since applications typically sit on top of frameworks, shouldn't the framework have a say with regard to what the cloud proffers?  I think so.  Because ultimately, no developer with framework expertise is going to abandon the bona fide methodologies.  This of course presupposes that the cloud can offer something application frameworks want.  What?

Virtual machines are just one way to make use of on-demand resources.  The cloud is our application as this is where it runs.  However, one single virtual machine isn't going to be of great benefit.  Why not just run it on a dedicated host somehwere?  We've got to utilize the cloud resources made available to us, and this is exactly why virtual machines are handy — they consume their own resources.  An obvious example of this is running your database server in it's own virtual machine.

These specialized virtual machines imply that we've dissected our application — if not the framework too — insulating components from one another.  Of course, this isn't easy to do.  Some frameworks have separately deployed components by nature.  Take Django for instance.  A typical Django deployment might have three virtual machines — one for the Django application itself, one for the database, and one for a memcache server.  Each of these components can be expanded further — maybe the database has one or more slave virtual machines or maybe there are 3 memcached servers.  Django's architecture makes it easy to discern the separable components that can safely run in an isolated environment.  But beyond this, we've got a challenging task ahead of us.

Imagine a Django development shop that specializes in Django websites and applications for companies.  They have large clients and thus need to scale their deployments.  For this, I think this shop needs an easy way to deploy the types of configurations discussed above — a Django application, along with database and cache nodes.  Instantiating this type of deployment requires extra effort by the development shop.  They can't simply click a deploy button without a lot of ancillary work in developing a deployment tool that'll go through the process of launching these virtual machines.  This is time this shop will not be spending on creating great software for their clients.

So what does the cloud offer for third-party consumer software?  A whole lot of hardware resources.  They're made available on demand as this is the reality for any application — traffic peaks and traffic slumps.  Virtual machines are great in their flexibility — we can take any component of our application and deploy it independently.  With this flexibility comes a cost however — the cost of becoming cloud experts.  I think the best thing cloud vendors can do is listen to the technology.  What is the most efficient way to deploy a typical Drupal site?  What would make the lives of Django development shops easier?  This is what should drive the next steps in making cloud computing accessible to everyone.

Tuesday, August 9, 2011

jQuery UI Icon Buttons

The jQuery UI button widget is flexible in that it can have several different configurations.  They can display text only, icon only, or a combination of the two.  This setup works with either a button or an anchor as the underlying element.  So right out of the box, the button widget is flexible enough to use more than one HTML element type.

One thing the button can't do without modification is display as an icon — without the other theme attributes like the border and background styles.  So if you want a button that only displays as an icon, maybe for a help button placed beside a text input, you've no choice but to alter the button.  An alternative is to extend the theme — to directly modify the theme to not display the border or background styles for button widgets. 

Let's look at an example.  Suppose we want a help button beside a text input — to tell the user what the input is for should they want to know.  When clicked, this button might display the contextual help in a dialog or expand some otherwise closed HTML content.  To do so with a regular button, we might implement the following HTML...

<body>
    <div>
        <input type="text"/>
        <button id="regular_button" title="Help">Help</button>
    </div>
</body>

And here is the Javascript used to instantiate the button widget, passing it a primary icon argument...

$(document).ready(function(){
    $('#regular_button').button({text:false, icons:{primary:'ui-icon-help'}});
});

Here is what the resulting layout looks like...


Without much effort on out part, we've now got a help button accompanying our text input - ready to respond to click events and display contextual content.  However, we're more concerned with the look and feel of this context button.  Might it be that in this button in it's default form might be a little overkill?  Let's try making this help button a little less invasive. 

First, we'll build on our current HTML structure so we can compare the two button formats...

<body>
    <div>
        <input type="text"/>
        <button id="regular_button" title="Help">Help</button>
    </div>
    <div>
        <input type="text"/>
        <button id="icon_button" title="Help">Help</button>
    </div>        
</body>

Next, we're going to create a new button widget — one that builds on the default button implementation...

$.widget('ui.iconbutton', $.extend({}, $.ui.button.prototype, {
    _init: function() {
        $.ui.button.prototype._init.call(this);
        this.element.removeClass('ui-corner-all')
                    .addClass('ui-iconbutton')
                    .unbind('.button');
    }		
}));

$(document).ready(function(){
    $('#regular_button').button({text:false, icons:{primary:'ui-icon-help'}});
    $('#icon_button').iconbutton({text:false, icons:{primary:'ui-icon-help'}});
}); 
 

Finally, our new button implementation needs to be themed...

.ui-iconbutton {
    background: transparent;
    border: none;
}

The demo page now has two text inputs and two corresponding help buttons — the latter using our new button implementation that only shows the icon...


As you can see, iconbutton removes the border and background styles from the button — aside from that, we've got a regular button image.  With this widget customization, we're only modifying the appearance.

Did we have to create a custom widget just to remove the border and background styles from a button?  Could we not have just applied the appropriate help icon class to a span element and achieve the same result with less work?  Absolutely, we could have.  But in the end, creating a custom widget implementation has several benefits that aren't discernible at first.

The key advantage to this approach is that the iconbutton and button widgets are interchangeable.  Since the iconbutton is simply extending the button widget, it accepts the same parameters.  This is why I'm illustrating both buttons on the same page — the HTML and Javascript are identical except for the widget name.  What this means is that if you don't want the icon button any more, it can simply be replaced by a regular button.  Conversely, the icon button can replace regular buttons.

Thursday, August 4, 2011

Simplicity And Longevity

Nothing lasts forever — but simple things generally last a long time.  Why?  Because the more moving parts a thing has, the more subject it is to breakage and eventual death.  Even some smaller, simpler things don't last too long. But these can be enjoyed again and again because they're simple — easy to reproduce.  Travelling into outer space, walking on the moon, surviving re-entry — this an incredibly complex trip, disaster-prone and unlikely to happen to the same person twice in a lifetime.

Classic cars — the vettes, the chargers, the 57 chevs.  They're beautiful machines by any measure.  They're also simple by today's automobile standards.  Could it be that simplicity alone has driven these classic cars into the future?  Could this concept have any bearing on the longevity of software?

Maybe going back several decades — to the early days of Bell Laboratories — might help shed some light on simple software.  This was during the development of both Unix and the C programming language — two systems that are still hugely relevant today.

The C programming language, designed by Dennis Ritchie has a long and interesting development history.  What I find particularly intesting about the C programming language is that it still beats newer languages in popularity, and in overall usage.  Why?  It's not as though C has some superset of features, derived from an earlier variation on the language.  I think it's for this exact reason — the lack of features — that C has been so successful, so widespread, and so relied upon for almost any software system.

Portability wasn't a concern to Ritchie during the early days of C.  However, portability came almost naturally to the language as a result of the minute number of pieces, the underlying mechanisms unique to each hardware architecture.  Again, few moving parts means that simplicity alone made this possible.

I think the real measure of C's simplicity is outlined by the mere fact that nothing like it has been invented in all these decades — nothing came along and simplified C.  And through these times, amongst all the fabulous software, there were, and are today, dozens of brilliant computer scientists just like Ritchie — none of whom took C and made a simpler version of it.  To me, that says a simpler version of the language doesn't exist.  For that power it brought, it was as simple as it gets.

The art of longevity by means of simplicity doesn't end with C.  Python is another example of this phenomenon.  Also with a long history, the Python programming languages takes simplicity to another level.  Just as C simplified logic (relative to it's B predecessor), by introducing types, Python simplified it's programs by making types dynamic.

Python isn't a better simplification of C — the two languages solve different problems.  They are related though — Python is written in C.  This is exactly the type of task C excels at — implementing other programming languages.  The lower-level, system-based things where performance is important.  At least much more so than in domains where interpreted languages prevail.

Python is has quickly transformed itself into a language for the web because it has strong network library support and because the syntax is easy to learn.  I think the greatest insight Guido van Rossum had with Python was that code should better resemble English.  That is, you should have a general understanding of what the code is doing at a glance.

This is a drastic shift from what C is all about — performance.  A lot of the performance gained by C applications is due to the direct sacrifice of readability.  Rather than telling the computer what to do, with C, you also had to tell it how to do so efficiently.  This level of control is an absolute must for programmers developing system software.  But is it a requirement for all applications?

Python sacrifices performance for readability.  The fact that we're able to write software so fast with a language such as Python means we're able to invest more time in other activities — like testing it.  Maybe this had something to do with Python becomming one of the dominate forces of the web.  It's there, it's got the libraries, all you need to do is write some code.

Even with cool languages like Python, one can't help but notice there are certain domains — like stuff on the web — where patterns are repeated, again and again.  Even if we're able to cheaply crank out Python code because it is so simple, it's still monotonous and labour intensive.  It'd be nice to use a framework that takes care of at least some of these common tasks.

And this is arguably a problem with Python — it's such a good web language that there's an overpopulation of Python web frameworks.  It's good in a variety sense, but bad for standardization.  What is the default framework for the programming language of the web?

Django wins for simplicity — probably longevity too.  Django aims to simply only the common stuff that no web developer wants to take care of.  Things like database connections, template rendering and loading, URL-view mapping.  I'm obviously over-simplifying everything that Django does.  But a key Django hallmark — one I find other developers sometimes miss is that it gets out of the way.  I think this is an important trait for web frameworks.  With such a rapidly evolving medium, we do not have room for giant tools that try to espouse the whole development process.  Think small, think standard.  This is what Django does, and it does it well.  I think it'll be the default Python web framework for some time to come.

These are just three software systems that come to mind when I think about simplicity and longevity.  There are probably hundreds of things exhibiting this phenomenon — both in the software world and in day-to-day life.  If something is going to last a long time, that is, be of practical value to a large group of people, then it should be simple.  Engineer your software to be "as simple as possible, but no simpler" as I'm sure Einsten would have done.

Monday, August 1, 2011

jQuery UI Themes: Beginner's Guide

I'm pleased to announce the availability of my new book — JQuery UI Themes Beginner's Guide.  Also available directly from Packt Publishing.  Here is a brief chapter outline:

  1. Themeable User Interfaces — Just a little theory on themes.
  2. Using Themes — Introduction to using jQuery UI and themes.
  3. Using The ThemeRoller — Guide to using the ThemeRoller.
  4. Working With Widget Containers — Learn about the fundamental building block of the jQuery UI theme framework.
  5. Transforming Interaction States — Theme your interface based on the state of interactions.
  6. Customizing Interaction Cues — Bring theme styles to your user notifications.
  7. Creating Theme Icons — Extend the theme icon set with your own icons.
  8. Special Effects — Add further embellishments to your theme with shadows and overlays.
  9. Theming Custom Widgets — Build your own widget and learn to theme it accordingly.
Stay tuned — I'll be posting some variations on the examples in book here over the coming months.