Tuesday, April 28, 2009

DRY views using builders - AKA markup sucks

In this post I'm taking a look at how to DRY the view code from the Getting Started with Rails

The first thing I noticed about the Getting Started Guide was that the mark-up was really not very dry, so the question became how can I dry up the mark-up? OK so it does use a partial for the shared edit and new form. It has been my experience that most forms and lists are pretty simple and should not need this much mark-up. Truth be told, I hate writing mark-up. So how can I describe the presentation with enough detail so that I don't have to write so much? Don't get me wrong I don't mind writing mark-up that is unique for a given page. Just don't make me write more form and table markup...please.

So we want to be dry, cool. But we also want to be DRO (don't repeat others). So who is solving this problem? Let's start with our forms. How to DRY our forms. A quick look around a common pattern appears: Use Builders. A builder allows an application to emit custom code for a given form field. Were going to examine the formtastic plugin:
* http://github.com/justinfrench/formtastic/tree/master

In our case we would like to write simple erb code that emits all the tags for our form. In keeping with our DRO model we are going to take the formtastic plugin for a spin and see what we get.

First thing is to install the formtastic plugin:


script/plugin install git://github.com/justinfrench/formtastic.git


Now let's see if we can update the _form.html.erb file using formtastic:


<% @post.tags.build if @post.tags.empty? %>
<% form_for(@post) do |post_form| %>
<%= post_form.error_messages %>
<p>
<%= post_form.label :name %><br/>
<%= post_form.text_field :name %>
</p>
<p>
<%= post_form.label :title, "title" %><br/>
<%= post_form.text_field :title %>
</p>
<p>
<%= post_form.label :content %><br/>
<%= post_form.text_area :content %>
</p>
<h2>Tags</h2>
<% post_form.fields_for :tags do |tag_form| %>
<p>
<%= tag_form.label :name, 'Tag:' %>
<%= tag_form.text_field :name %>
</p>
<% unless tag_form.object.nil? || tag_form.object.new_record? %>
<p>
<%= tag_form.label :_delete, 'Remove:' %>
<%= tag_form.check_box :_delete %>
</p>
<% end %>
<% end %>
<p>
<%= post_form.submit "Save" %>
</p>
<% end %>


With our new form builder we can dry this up a little bit:

<% @post.tags.build if @post.tags.empty? %>

<% semantic_form_for(@post) do |post_form| %>
<%= post_form.error_messages %>
<%= form.inputs %>

<h2>Tags</h2>
<% post_form.fields_for :tags do |tag_form| %>
<p>
<%= tag_form.label :name, 'Tag:' %>
<%= tag_form.text_field :name %>
</p>
<% unless tag_form.object.nil? || tag_form.object.new_record? %>
<p>
<%= tag_form.label :_delete, 'Remove:' %>
<%= tag_form.check_box :_delete %>
</p>
<% end %>
<% end %>
<%= form.buttons %>
<% end %>


A couple of things to notice when you run this. You now have some more view logic that was provided by formtastic. Required fields are marked on the form with an *. The form is now drawn with a fieldset. The form uses left justified labels. If you look at the browswer source you'll also notice that it uses a <ol>> elements. (This is why the fields are numbered.) The form fields tags now have classes and id's for all the tags.

OK that went pretty well..so let's go a step further and refactor the tags:

<% @post.tags.build if @post.tags.empty? %>
<% semantic_form_for(@post) do |post_form| %>
<%= post_form.inputs %>
<% post_form.semantic_fields_for :tags do |tag_form| %>
<% tag_form.inputs :name, :name => 'Tags' do %>
<%= tag_form.input :name %>
<% unless tag_form.object.nil? || tag_form.object.new_record? %>
<%= tag_form.input :_delete, :as=>:boolean, :label => 'Remove:' %>
<% end %>
<% end %>
<% end %>
<%= post_form.buttons %>
<% end %>


Now we are getting somewhere! No mark-up! I could get use to doing forms like this.

My next implementation step is to generate client side validations by reading the model validations and presenting them at input time. Check out the livevalidation plugin

Friday, April 17, 2009

All great journeys start with one step

Like most of you that came to Ruby on Rails.  I was excited to see what this promising framework could do for productivity.  Before Rails I had designed large scale commercial web applications on both C++ and Java.  My real specialty was to define the framework and then extend it as the application demands.  We wanted our code to be DRY (before everyone was using the term DRY).  A good framework adds structure, is easy to understand, is easy to extend and eliminates repetitive code.  Rails certainly lives up to my definition of a good framework. It handles many of the most common issues that teams building data driven web applications have to solve.  Ruby is the giant's shoulders that Rails stands on.  The language is so expressive and dynamic it creates so many possibilities.  

Now it is time for a small trip down architecture memory lane. 

I've been developing data driven web applications since 1996.  Looking back on it is seems archaic.   At the time we were forging new ground.  

Version 1.0 1996:  We created one of the earliest commercial, dynamic, configurable, web based business applications.  One thing that made these applications so effective is that they were massively configurable by the clients.  Everything, and I mean everything, could be customized by the client.  Back then the tools were non-existent.  Our first application was MSFT based.  Good old fashion COM objects talking to ASP 1.0.  We developed a model layer with the COM objects and the ASP programmers then consumed them to present the view.  It was a simple MV design.  (No controller.)  HTML was so limited back then, so we had a java applet that handled the advanced data entry UI.  This essentially had to mimic what we had built as a windows application.   

Version 2.0 1997: We designed a JavaScript version that eliminated the 'heavy' Java applet from the client. This was a very ambitious multiplatform JavaScript library.  It had to understand a very rich meta-data layer that described how the data entry for the client should behave.  The DOM was not very rich and if you wanted to dynamically do much of anything on the client you had to write it from scratch and then make it work on all the browsers.

Version 3.0 1998: So far these applications were installed by large fortune 500 businesses.   But it was too complicated to setup and maintain for a midsize company.  So we introduced the Software as a Service (SaaS).  Back then we called it ASP or our Hosted business.  This introduced a whole bunch of new design challenges.  Should there be one database per customer or larger databases shared with a 'domain' column partitioning the data.  How do you manage it?  How do you scale it? How do you secure it.  This is before really anyone else had a viable SaaS product much less business model.

Version 3.0 2001:  The success of all the earlier projects led to more customers with even more needs.  This time they need to have a global solution that could handle many languages simultaneously.  Like many code bases the investment into refactoring the original design was borrowed from for years.  As a result it never really evolved as it could have.  By now the tools had advanced very far.  Java (J2EE) was leading the charge with MSFT 'embracing and 'extending' with .Net.  We had already  switched to Java (J2EE) and built a very cool XML driven B2B product that integrated suppliers in the procurement chain. 

So it was time to build the mother of all projects.  It had a list of requirements that would scare off most engineers.   

We started with a simple J2EE stack layered with a bunch of Apache technologies.  We chose Turbine as our MVC. Our model layer was based on Torque.  Torque was great for navigating the model, insert, updates, deletes and transactions.  But our views were often hitting many tables and a pedestrian Torque implementation would result in too many database round trips.  So we introduced our own read only data access layer RDAL (Rapid Data Access Layer).  RDAL allowed us to write portable SQL and get very efficient data-access out of the system all while looking like a Torque model object to the view.  We considered JSP, ECS and Struts for the view layer.  In the end we decided against all of them to selected Velocity.  What attracted me to Velocity was the simplicity of the templating language.  It could do what you normally need to do in a view very well, loop, conditionals.  It was not expressive enough to put logic into the view.  We could re-use snippets of code with it (like a Rails partial).   Essentially what we had was a J2EE/Apache MVC stack that did much of what you find in Rails.  

So now we had an application framework, big deal.  We were building database driven web applications.  So we have a lot of CRUD operations to deal with.  Those CRUD interfaces all had to deal with the following:

·          It was a SaaS offering so every CRUD set of views had to be domain aware.

·          Most CRUD views had to support custom fields

·          Every view had to be multi-lingual with multiple users viewing the site in different languages simultaneously.

·          Views had to support role based behavior.  (Be aware of the role of the current user and present different options based on their role.)

·          It was a SaaS application so it had to be VERY secure.  We chose to implement the OWASP security standards for the application.

·          Every view could be customized by an consulting engineer.  That customization would override the default view behavior on a per-customer basis.  The consults should also be able to add new views for that client.

Dang that’s a lot of stuff each developer has to be concerned about.  Where to start? The view layer really does nothing to provide any productivity to solve any of these problems.  If you want to build a new or edit form you have to write a whole bunch of form html.  If you wanted a list you would have to write a bunch of table markup.  So the question became how do you DRY up the view and meet the requirements above? 

Our answer was to introduce a presentation markup language.  You would describe your model in the markup and it would generate a CRUD set of views for you that does all of the above automatically.  It was really easy to add new CRUD views on a given model.   It was easy to change the UI design for a given element.  We had a UI designer that would introduce new behavior as we progressed on the project.  We could modify all the views built so far with this new UI behavior.  Did I mention that it would generate tests for you as well? It was slick as snot.

The presentation markup was concerned only with how you want to render the model(s).  From the markup you could embed velocity code just like a partial.  You could call java ‘helper’ methods.  It allowed us to have declarative UI for much of the system. 

This blog is will follow along as I solve the same problem, extending the rails framework along the way.