On a recent Sitecore project, our Sitecore team at Hanson Dodge Creative attempted a new coding style in our Sitecore Sublayouts, preferring <% scriptlets %> over controls, and making heavy use of Velir’s Custom Item Generator as our Domain Model and View Model to avoid tag soup and reduce our dependency on Sitecore webcontrols for field rendering. Read on to find out the why’s and the how’s.
One of our favorite aspects of ASP.NET MVC at Hanson Dodge Creative is its departure from the Webforms control and event architecture. Though its state management capabilities allow easier and faster development of some fairly complex applications, Webforms is quickly becoming a dinosaur in an era of jQuery, AJAX, and generally more complex client-side interaction. From the perspective of the .NET developer, the simplicity of the View has a certain elegance: no data binding to esoteric controls, or digging through your memory (and documentation) to recall whether you should be using the Init, Load, or PreRender event.
However the simplified View logic is possible in ASP.NET MVC only through the abstraction and delegation provided by the other two pillars of the architecture: the Model and the Controller. In Webforms, the Code-behind/beside essentially provided a Page Controller pattern to keep markup clean and avoid the tag soup that plagued classic ASP (among other page scripting languagues). But at some point you step back and ask yourself -- why am I wasting my time data binding to this ListView when I could write a damn for loop?
It's against this backdrop that we asked ourselves how we could bring the View development efficiency of MVC to our Sitecore development. Sitecore essentially provides its own MVC-ish architecture, though its "Controllers" are data-driven rather than code-driven, and its Model is very general and usually not strongly typed (e.g. Item["field"]). There is also the challenge that Sitecore's View layer is very closely tied to the Webforms architecture -- implementing the Page Editor is usually accomplished through a heavy use of Sitecore's ASP.NET controls, such as sc:Text and sc:Sublayout. Until the time when (if?) Sitecore integrates ASP.NET MVC into its architecture, a full departure from Webforms is not possible. But in rebuilding our own website on Sitecore recently, we think we found a sort-of "stepping stone" in the Custom Item Generator shared source module.
As an example:
And its code-beside is simply:
As you can see, we are still dependent on traditional Webforms:
- We still have a Page Controller, albeit with very minimal logic
- We are still using a web control for the Sitecore placeholder
However, I think anyone can recognize the overall simplicity and efficiency found here over a standard Webforms implementation. It's only possible though because of the capabilities provided by the Custom Item Generator module.....
Strongly-typed field access keeps the view logic clean, readable, and type checked.
Access to FieldRender pipeline output allows simple "Page Editor friendly" output of field data.
Use of partial classes allows the safe extension of the generated domain objects and clean, logical fields for use in view logic. In the above example, CompanyPageItem.ServiceCategories provides strongly-typed access to child items of the Company Page, which happen to be Service Category items.
In addition, following the IDisposable convention used in ASP.NET MVC HtmlHelpers, we found a creative means of implementing Edit Frames within the same style.
The approach isn't perfect though. We obviously have lost the state management capabilities of webforms, and the addition of any PostBack logic to our Sublayouts would quickly turn the code ugly. In the intial rollout of our website, this wasn't a requirement. It was a purely content-driven site. I'd also venture that in general the majority of Sitecore sublayouts are just outputting content, with no server interactivity. Our tentative plan for building functionality such as Contact forms is a use of jQuery and MVC-based JSON services. However this will have to wait for another post.
Overall, we found that this approach made our development more efficient, and less error prone. I'm curious as to the general reaction to the style, and whether anyone else in the community has attempted anything similar?
-Nick / techphoria414