Architecting Your Views Part 3: A Proposed Solution
And so in the spirit of Einstein’s famous quote, here is my currently proposed solution to my view design requirements . . .
Re-introducing the IBO
Anyone who follows this blog will have heard about the Iterating Business Object. In short, it is a way to encapsulate the getting and setting of the attributes of your business objects, but using a single object to handle 1..n records to handle the performance issues with creating large numbers of transient objects in ColdFusion.
Two things I wanted to automate were the creation of fields for editing attributes and any display rules for displaying the value of attributes. Both of those can be specified automatically using custom data types. However, to make this work I need to add a field() and display() method to my IBO. But these are HTML aware methods, so I really don’t want to stick them in the same IBO that I use in my model for encapsulating the business rules around getting and setting attribute values. So, I’ve added a com.view.IBOViewDecorator.BaseIBOViewDecorator.cfc with three new methods: field(), display() and loadIBO() – as well as delegates for all of the IBO methods that would be relevant in a view (attributeTitle(), get(), set(), first(), next() and hasNext()).
The benefits of the IBOViewDecorator are that it allows you to use custom data types to handle field display and value display (prefixing money data types with the appropriate currency symbols or formatting dates and times appropriately) removing a lot of the busy-work scripting from your applications and cleaning up your view templates.
The Render Object
I REALLY like Dependency injection. With DI, objects just *have* the objects they need without having to worry about it. I like it so much I thought it would be great to be able to DI within my views, but to do that I had to run LightBase page requests as a single method call (which I did – you now just call application.LightBase.processRequest()) and I needed to create a cfc to handle and hide the orchestration of all view rendering (which I did – com.view.render.cfc).
By using IBO’s I was already going to have to teach my designers to use syntax like #Product.display(“Price”)# for displaying the price of products. I thought it would be cool to be able to use the same syntax with a fairly limited vocabulary to encapsulate the complexity of any scripting from the templates my designers used.
For instance, a page template is comprised of HTML, optional snippets, and 1..n content areas, so when a designer wants to drop in a dynamic content area, they can just write #Render.contentArea(“Sidebar”)# to have the sidebar content area rendered in that place.
I also provided for #Render.snippet(“CheckoutMessage”)# for rendering snippets of content for clients to manage using the CMS and #Render.form(“UserForm”)# for displaying a user add/edit form and #Render.table(“AttorneyList”)# for displaying a list of an object in a state aware table with filtering, paging an ordering features based on the parameters associated to and the data returned by the model method bound to the “AttorneyList” table.
There are a few nice things about this approach.
I love the fact that I just need to teach designers a single manageable syntax for handling everything from displaying a product price to displaying a snippet, component or content area. I love the fact that with the exception of looping through iterators and possibly the occasionally expedient cfif, it almost entirely removes scripting from the templates, providing for a clean separation of concerns and making it feasible for designers with basic HTML knowledge to do all of the custom layout without getting into too much trouble.
I love the fact that designers don’t have to worry about passing the RequestObject or other data to each method. They don’t have to do something like #Render.table(“AttorneyList”,RequestObject.get(“AttorneyIBO”))# which would be a little confusing for a designer. I don’t love having to use the variables scope within the Render object to provide this feature as it makes the methods a little less self contained than I’d usually like, but I feel it is an appropriate solution to the problem at hand so I’ll take it as a win!
Above all, I love the levels of reusability that this provides and the flexibility it offers for declaratively specifying a huge proportion of your view logic, just leaving a set of templates for your designers to tweak as they will. This is particularly important for my use case as I have to engineer almost all of the programming out of creating custom web applications while still providing unlimited view flexibility.
UI Components
My first two UI components are table and form – and they still need a lot of work. The basic principle is that these can be used for scaffolding that is so sophisticated that for the vast majority of your pages (at least on low budget projects) the scaffolding will BE the application – perhaps with a few tweaks.
The basic idea was to provide the benefits of a Visual Studio style approach while allowing for the association of UI components to model methods rather than straight to a data source (and if I can offer Mark Drew enough drinks, cash or stock options - who knows - maybe there WILL be a visual designer for LightBase!). I also wanted something that would be capable of maintaining state so you didn’t have to write a bunch of code to ensure that when you changed the order by for a table it remembered the number of records per page or when you moved to a new page it still remembered the filters you had applied to the records in the table. I know a lot of this can be implemented using AJAX, but I wanted an HTML reference implementation to which I could then add AJAX or Flex renderers if I so chose (Q1 2007 – quicker if anyone wants to help out!).
Each user component has a set of methods together with a template so that if you don’t like how a template pulls the scripted code together, you can just create another template, set that as a parameter declaratively, and customize it. Of course, if you don’t like how any of the scripted methods work (above and beyond any parameterizations available), you can just extend the object and overload any method implementations that don’t work for you (sometimes inheritance is very cool!).
To be honest I am thoroughly relieved to have an approach to pulling together templates and components with support for DI, inheritance, good separation of concerns, intelligent conventions, unlimited flexibility to customize or extend, etc. My UI controls aren’t much good yet as I need to do a lot of thinking about state. But it’s looking like LightBase is going to be pretty good by Christmas.
Any constructive input or questions always gratefully received!


I'm in the custom tag camp still as I think the tags are more intuitive for my situation and the other people that are working with tags and also that there is a certain amount of legacy I have to consider.
I basically split them up into two sets:
- LAYOUT: document, head, header, navigation, main, secondary, tertiary, footer
- UI: button, calendar, cell, date, fieldset, form, grid, heading, hidden, include, input, pagination, row, secret, select, table, text, textarea, tree, upload, xhtml, checkboxgroup, radiogroup
Nothing within the above is rocket science, just making certain form like requirements again and again made me consolidate them into a tag (ie labels, required, etc)
Where I am currently refactoring is the 'Multiple Dynamic Content Areas' that you talked about in the first part of your series. It is this reasoning that I have split the tagset (which was all originally under one tagset of UI) into the two of Layout and UI.
But I'm struggling further, as when I try and satisfy this requirement, I end up coding within the Layout set framework specific code that I just know should not go there!
I'm currently using a similar method to the Render that you talk about (inspired by ModelGlue in my case) in the fact that you can 'renderView' or 'appendView' and finally 'renderDisplay' to draw the whole page and when you renderView or appendView you can target a specific content area.
These just call CFM files that use the UI tagset and syntax, with the caveat that there should be NO CFML code in the files other than CFIMPORT and attributes that have CFML variables being passed into them (sometimes not easy in practice!).
In reality though, I feel I should be doing all of the above using XSL with the XML passed from my model. Thing is I'm no hot shot at XSL and also when I have tried to achieve that, I've just ended up with an unholy mess of XSL files that are hard to decipher. I do believe that this is because of my relative inexperience with XSL though rather than anything else...
Anyways, as ever, fantastic set of posts from yourself and got me thinking as to where I was heading with my own adventures. Please do continue this series, it would interesting to hear what you end up with.
All the best
--
David
A lawyer may work in 1..N offices. Each office-lawyer relationship has it's own phone number. They have an attorney listing page. In round one, they want to list each lawyer with their TOP office / phone number (1 -to- 1 style). Then three months later, round two, they want to change the list so that all lawyer names are listed once, but for each lawyer, all offices / phone are listed. Then, three months later in round three, they want each lawyer listed once with only TOp phone number, but then a sub note (per list item IF available) that "Lawyer also available at office X,Y, and Z".
Now, to me, this is a change in the Query that gets run AND it's a change in the View. Do you agree? Or would the lawyers be part of some IBO that had something like GetTopOffice() and GetAllOffices()... remember, I don't always want to return ALL offices.
And how would a reusable UI thing work for this? What really got me thinking about this was your line:
Render.table( “AttorneyList” )
How does this work when the definition of an attorney list change? Who makes that change? the UI people or the programmer? Especially given that the definition can change just the Layout AND/OR the actual data that is pulled from the database?
I think your ideas are awesome, I am just having a hard time wrapping my head around applying it to my other projects.
Thanks for the comment! I did consider custom tags, they are the most common approach in the CF world and I definitely see why people would use them. For me I just preferred using objects as I could wrap a template call together with a bunch of script methods to create (for instance) a table.cfc with a clean separation of concerns between rendering the main template and concatenating the little bits of content (like paging links) that are easier to just concatenate in a separate method. I also liked the fact that I could use inheritance so if you don't like BaseTable.cfc's paging mechanism, you can extend it with YourTable.cfc and write your own modifier to the paging system.
I think XML/XSLT is one template based approach, but I don't love it myself. I think that ColdFusion can solve the same problems with less typing as XSLT is just a templating language with a subset of the functionality of ColdFusion. There is nothing wrong with using XSLT just as there is nothing wrong with learning Ruby - but I don't think either are essential to build a web app using ColdFusion.
I'm having issues now with the relationship between controller model and view to make as elegant a solution as possible for multiple content areas, so keep watching. Sample code over the weekend.
Great question! Basically, I don't believe views should know anything they don't HAVE to know, so wherever possible I use dynamic forms, tables and detail screens. Obviously this breaks down when you want to have really custom formatting and at that time you extend using a custom template that DOES know about the data.
If you just need a standard display, the view just needs to be provided with an IBO and it'll loop through the gettableAttributeList which defines both the attributes to display and the order to display them. In a table it'll start by looping through getting Attorney.title(ThisAttributeName) and then it'll display the values. If you looked at a very simplified generic default table template
it'd be something like:
<table>
<cfloop list="#Attorney.gettableAttributeList#" index="ThisAttributeName">
<th>#Attorney.title(ThisAttributeName)#</th>
</cfloop>
<cfloop condition="#Attribute.HasNext#">
<tr>
<cfloop list="#Attorney.gettableAttributeList#" index="ThisAttributeName">
<td>#Attorney.display(ThisAttributeName)#</td>
</cfloop>
</tr>
<cfset Attorney.Next()>
</cfloop>
</table>
As such, just change the AttorneyService method and it'll automatically set the right parameters to call the BaseDAO, so you don't repeat yourself anywhere You may also need to set some custom attributes in the Attorney IBO in the getPhone() or whatever, but that is also easy enough.
Of course, if you do create a custom layout template to put specific fields in precise places, you will have repeated yourself and will have to change both the service method and the layout template, but that is an unavoidable repetition as far as I can tell.
Make sense?
I can see where this would rock hard core for things that have more generic interfaces. I have gotten to the point in my coding skills where I can have a generic "Delete Confirmation" page most of the time, but that's about all I have been able to wrap my head around.
Looking forward to seeing some examples. Thanks!
Will be looking forward to the code samples you mention. Cheers!
Thanks! Just one thing to bear in mind. There was never a problem with putting display code into CFC's (although sometimes the message was shortened to that). The problem was putting view code into MODEL CFC's that truly shouldn't have any responsibility for display, so it was a separation of concerns and cohesion issue that just got chinese whispered into "don't put HTML into your CFCs".