Managing the UI
Peter Bell has an interesting series on "Architecting Your Views". As usual, his thoughts are very interesting and inpsired me to share my own views on the matter.
Peter starts by referencing my article on layout components and then describes his requirements for a CMS. In brief, they are:
- Page Templates
- Multiple Dynamic Content Areas
- Reusable Screens
- Extensible UI Components
- Snippets
- Separation of Concerns
- Declarative Specification
I think that the distinction between a CMS and a site layout is an important one. Layout components can help with some (but not all) of these requirements. Many of them, however, are outside the scope of what your layout mechanism should provide.
Layout components can help with page templating by providing an easy mechanism to switch to a different layout.
In order to use my "Home" layout (as opposed to, perhaps, my default one), I add the following code above my call to the layout component.
<cfset layout = layout.switchLayout("Home")>
No reason why that couldn't be a dynamic value from the CMS instead of a hard-coded "Home" as well.
Most of the remaining functionality isin the domain of the CMS, but I do want to touch on a few other points that I will combine in one basic topic.
Snippets and Extensible UI Components are both reusable visual elements. Peter uses a Render component while many other people use custom tags. I think this brings up an important distinction. Some UI components are inherently general in purpose while others are intrinsically tied to the layout.
For example, every administrative section I have worked on needs tables and forms with similar functionality. As such, I have custom tags to manage each (available on my site, but still need to be cleaned up a bit). On the other hand, a given site may have a small calendar widget that will be used in various places throughout the site. It won't be used on other sites, but will need to be used in various places on this one.
In that case, I often add a method to my layout component. In this example, I would add a calendar() method which would render the calendar component. This also allows the calendar method to be extended for different layouts. For example, it might show up in the Home or Default layout, but not the layout used for outputting to MS Word.
I think that the Render component idea has some promise, but also may be more complex than is often needed. Most significantly, however, I think the distinction between general UI components and components that are essentially a part of the layout is an important distinction.
Incidentally, if you would like to see a full-fledged example of layout components at work, check out CodeCop (which will also review your code and which - thanks to layout components - looks right in CF6 admin, CF7 admin, or on its own). It is still in beta, but makes for a pretty good example of layout components (as well as the previously mentioned custom tags).
Interesting as always! I do distinguish between application specific components and those I want to reuse but I do that as part of a general mechanism/approach using subclassing that allows ANYTHING to be overloaded on a project bases, so if you don't like the base controller in LightBase, write your own, extend the LightBase one and then just tweak the LightWire config file to give the new class path. Equally there is a place in applications where you can put components and the only thing I'd do differently with the calendar, if I'd just drop it into its own cfc and then use a delegate to call it either directly from the Render method (Render.component("Calendar","MyCal")) or via some kind of component facade that would handle all UI components.
I agree that most of what I do is overkill for many smaller simpler projects (like working on a data mapper to make attributes independent of db columns so you can order by Age and it'll be smart enough to order by DateofBirth DESC). However my use case is to be able to declaratively specify the vast majority of most web apps, so I need to provide a sophisticated, granular system so that you can implement the bast majority of use cases by just setting some configuration metadata. It goes back to something I mentioned the other day. All other things being equal, you can't get rid of complexity - you can just move it around. I provide a more complex framework to make the application code much simpler and more based on declarative config which is the only way to go if you want the capacity to generate thousands of custom applications a year which is my goal!
I think that while the Law of Conservation of Complexity may be accurate, I also think that it can lead to an unhelpful perspective. Many things are more complicated than they have to be and so it can be made more simple (the point of irreducible complexity usually hasn't been met).
For example, I was working today on some code to update a county for several records based on the zip code. The original code retrieved the zip codes for records with no county, retrieved counties for those zip codes, and then updated the county for records matching that zip code. I changed it to one query that updates the county of the record with the county associated with the zip code.
The point is that complexity can often be reduced rather than moved around.
Obviously that may not be the case with what you are doing, but I thought it was an important point.
I am looking forward to seeing your results.
Your related posts for reference:
http://www.pbell.com/index.cfm/2006/12/5/Architect...
http://www.pbell.com/index.cfm/2006/12/6/Architect...
http://www.pbell.com/index.cfm/2006/12/6/Architect...