On a recent project, I was asked to undertake a different approach to implementing a website in SDL Tridion using MVC. The application approach is similar to CWA, popular before the arrival of DD4T.
The alternate approach took a little bit of figuring out, and a little bit of help from my fellow Tridionaut Eric Huiza (thanks Eric!).
Now that I've got it under control, I thought I would share the approach and highlight some of the code for others to follow.
First the architecture
The application starts out as a pretty standard ASP.NET MVC application, except with no Views. The Views are published from Tridion and stored within the Tridion Content Delivery database, rather than the filesystem.
* I am in the process of updating this, to store the static views on the filesystem for performance. It is relatively easy, using the file extension option in the Storage Configuration to direct files to the database or filesystem."
So what is in Tridion? Well, Tridion looks pretty standard too. I have normal content Schemas, Page Templates, Component Templates, Pages and Components. The difference is the output of the Page and Component Templates, which is in Razor syntax -- the aforementioned Views.
So how does it work? There are two 'special' parts within the ASP.NET MVC application:
- VirtualPathProvider - An ASP.NET extension point which allows you to override where ASP.NET looks for files (default filesystem) and instead looks wherever you prefer. In my case, it will look in the Tridion Content Delivery database.
- Generic Page Controller - A Page Controller which handles all requests, mapping them to the relevant page created in Tridion.
On to the code
Let's start with Tridion. As I said, the Tridion implementation is pretty standard and you create Components and build Pages in the normal way, adding Component Presentations.
The interesting part to see is an example of a Page and Component Template (which you can see below using the Razor Mediator extension).
In this example, nothing is added at publish time. It will all be handled in the ASP.NET MVC application.
The Component Template is a hybrid. Some of the content is populated at publish time, such as title, summary and a row for each product. Then, once in the ASP.NET MVC application, the row will be decorated with the price from the dynamic Model.
Now, onto the ASP.NET MVC application. Below are the highlights:
The Controller loads the page from the Tridion Content Delivery Database and extracts the required metadata and Component Presentations, before rendering the View.
Once the controller has requested the view, it will pass off to the previously mentioned VirtualPathProvider, but first that needs to be registered in the Global ASAX.
The VirtualPathProvider now intercepts all requests by ASP.NET MVC for a View file. If the View name matches the convention I have implemented, the View will be retrieved (and cached) from the Tridion Content Delivery database.
A helper class gathers the Component Presentation data, and then calls the associated Controller Action. This allows the dynamic data to be added in the Controller, ready for rendering as per the Page View.
Now for a retrospective. Having implemented a POC using this approach, and being familiar with DD4T, I want to look back on the exercise. Would I choose this approach over DD4T when implementing MVC and Tridion in the future?
Overall, I still favor DD4T over this approach, for the following reasons:
- DD4T follows the MVC pattern more closely
- DD4T does a better job of separating the content and presentation cleanly
- As a developer, I like the control DD4T gives me over code releases
- As an editor, the experience is almost identical between the two approaches
- DD4T has an active developer community, allowing me to take advantage of other people's enhancements and maintenance
- You could achieve the same level of View control with DD4T by publishing all Views to a Views Structure Group
So why did my customer want to use this approach?
- It centralizes the control of Templates within Tridion
- Allows their front-end developers to make changes to (and publish) Views without involving the back-end team and a drawn out deployment process
- It also follows a pattern they are familiar with as a development team, which is very important to minimize impact on the business
It is an interesting approach and following the full application build, I will share more thoughts on it.