I’ve also launched a Theme competition with real prizes – please do enter a theme, closing date December 10th 2012!
This project is the culmination of many years of usage of Grails and thinking about the problems web developers face.
As you know I’m no fan of the mess that is web app UI, and the amount of time and expertise required to make really good web app UI is not available to a great many developers who nevertheless have to create web apps. It is what it is, and we have to try to reduce the pain and time cost to create compelling UIs.
These problems became particularly clear over the years of writing Grails plugins. I always wanted Grails to have higher level plugins that provide actual high quality UI functionality.
I wanted an authentication plugin that supplied out of the box signup and login forms. I wanted to provide nice admin UIs for my email-confirmation and invitation-only plugins. I wanted to provide advanced dev-time UIs for seeing behind the curtains of your app’s plugins to help you debug and test. There was no way to achieve this.
The obstacles were hard problems; nobody can agree on a single definitive JS library to use, CSS frameworks last as long as hipster brainfarts, and as such there was no way to make plugins expose anything but the most basic ugly UI that does not integrate with your own app UI, let alone look coherent. You can’t sell a community on installing your UI based plugins if they look like crap out of the box and they have to spend ages styling them. Without meaning to be rude, but generally speaking we in the Java community are not renowned for our good taste in UI nor for our CSS skills. (and this could remain our limiting factor)
In the past, as a community we saw the YUI and monolothic and frankly nasty Grails UI plugin come and go, and this seemed to fulfill none of these requirements in a satisfactory way.
While paid to work on the Weceem CMS plugin I had to work on what is likely the “largest” UI that any Grails plugin supplies to the host application. I had to attempt to tackle a bunch of these problems without any of the tools already existing, which gave me a unique perspective on the problem domain.
So some 2-3 years ago I started on the journey of solving these problems, by creating the Resources plugin.
This solved one of the hard problems – removing explicit dependence on individual resource files so that you don’t end up with say 3 different versions of jQuery in your app because of files introduced by plugins.
Then last year I started building the next step, the Platform Core plugin with the help of Stéphane Maldini, which solves some of the other problems:
- Config integration between plugins so that you can easily write a plugin that e.g. provides a UI for another plugin
- A standard menu Navigation system that is not kludgy like my old Navigation plugin
- A security abstraction so that plugins can interact with security without mandating specific security libraries
- Events for communicating between plugins and application instead of relying on plugins to roll their own “callback” mechanisms etc.
It also has a bunch of plugin namespacing magic that stops elements from different plugins clashing – i18n strings, request, session and flash variables.
On the UI front, it took a long time to come up with the “right” solution, and I started on it about 18 months ago. Although I can’t be sure that Platform UI is the definitive solution, it is certainly a step in the right direction. Along the way I dismissed several other ideas, including a JS library abstraction layer that would have stubs for each JS library, and a unified Theme and UI system where Themes provided all the markup.
After the first implementation of Platform UI I reworked it, with a clear separation:
- Themes provide structural markup and frills
- UI Sets provide the mechanical markup, JS and styling for individual UI elements
This turned out to be a major revelation. It pulls the harder, reusable and CSS/JS framework specific part out into UI Sets separate from any Theme look and feel stuff. It makes Themes easier to write as you just need to provide some resources and a few GSP templates.
There is also a wonderful happy outcome of this: your application and plugin GSP views end up very clean and entirely focussed on the content you are presenting. Almost all of your structural layout and UI widget shenanigans are removed.
As an example, here’s the sign up screen from my Fresh Security plugin (not fully released yet) which leverages Platform UI to wrap Spring Security in something that “just works”:
Notice the complete lack of HTML shenanigans.
I’m not pretending that this is a cure-all. It is just impossible to cater for every possibility and pixel perfect custom layouts with this kind of approach. It is not about that. It is about getting you to 90% immediately. Then you can spend time on the 10% refinement – if you need to.
There are a bunch of issues that will become more important in Platform UI soon. The contracts for each UI element will need polishing, and I am pretty sure that the required Theme layout zones may also need a contract to indicate what kind of elements should go in them, or at least guidance for themes to automatically adjust the base
h1 heading level inside each zone (perhaps with an attribute on layoutZone). Another big challenge that remains is how best to allow plugin UIs to do some kind of layout or alignment of their content within zones. There’s no way to have a universal grid, so for now at least plugins or apps will need to use CSS to size elements by percentages to remain compatible with multiple themes.
We need to see how people use this to know for sure.
One thing I am sure about is that this will be my last “major effort” Grails plugin. I can’t do this scale of work unpaid any more, and as a result timelines and quality suffer.
It is certainly exciting from a creative standpoint, but I am planning to be devote my future creative energies to iOS development. I’m not turning my back on Grails, but I have an invisible tattoo on my forehead now that says “NO MORE BIG GRAILS PLUGINS”.