How To Create A Global View Model For Umbraco With uSitebuilder

I’ve previously talked in How To Create A Global View Model For Your Umbraco Layout File about the benefits of creating a global view model in your MVC Umbraco project to separate your presentation code from your business code.

In the code sample I provided in that article, it was assuming that you used Umbraco based content to do your MVC hi-jacking etc.. Another approach to further improve your presentation and business logic is to use uSiteBuilder to define all your document types in code rather than the Umbraco back-end. When you use uSiteBuilder you can still use the same approach in order to render your global data like the header and footer but the base class you need to inherit from changes slightly. In today’s guide, I’m going to cover all the code you need to achieve this.

Results Filter

The first thing we need to do is create a results filter to inject the global layout model in the templates.

public void OnResultExecuting(ResultExecutingContext filterContext)
{
var model = filterContext.Controller.ViewData.Model;
var layoutModel = model as ILayoutViewModel<DocumentTypeBase>;
if (layoutModel != null)
{
var layout = new LayoutViewModel();
layoutModel.Layout = layout;
}
}

The big change from last time is the ILayoutViewModel now needs to take a DocumentTypeBase rather than an IPublishedContent. What this code is saying is that on any request that uses a base view model we will define later. Inject a new view model.

BaseViewModel

Now we have our global layout interface defined, next we need to define a base view model that all our document type controller will need to use. Again, this code is very similar to the last tutorial except we use DocumentTypeBase.

public class BaseViewModel<T> : ILayoutViewModel<T> where T : DocumentTypeBase
{
public BaseViewModel(T currentPage)
{
CurrentPage = currentPage;
}
public T CurrentPage { get; private set; }
public LayoutViewModel Layout { get; set; }
}

Layout View Model

So the next step is to define the view model, first we define an interface:

public interface ILayoutViewModel<out T> where T : DocumentTypeBase
{
LayoutViewModel Layout { get; set; }
T CurrentPage { get; }
}

Again, this is very similar to the last article, except we swap the IPublishedContent for DocumentTypeBase.

Homepage View Model

To give you an idea how we use the layout view model, I’ll go over the code to implement a specific view model for a document type. In my project I have a uSiteBuilder document type, defined like this:

[DocumentType(Name = "Homepage",
Alias="homepage",
Description = "The Homepage",
AllowedChildNodeTypes = new Type[] { typeof(ContentDocumentType) } )]
public class HomepageDocumentType : Vega.USiteBuilder.DocumentTypeBase
{
[DocumentTypeProperty(UmbracoPropertyType.Textstring, 
Name = "Page Title", 
Tab = "Page Setting", 
Description = "Page Title")]
public string PageTitle { get; set; }

The view model for the home page would look like this:

public class HomepageViewModel : BaseViewModel<HomepageDocumentType>
{
private readonly HomepageDocumentType _currentPage;
public HomepageViewModel(HomepageDocumentType currentPage)
: base(currentPage)
{
}
}

In the view model, we inherit from the base view model passing in the homepage type. We then pass the current page back into the base class so we can use it in our views.

Homepage Controller

The next step is to create a controller for the home page, get the uSiteBuilder document type and pass a home page view model back to the view to render.

public class HomePageController : Umbraco.Web.Mvc.RenderMvcController
{
public ActionResult homepage(RenderModel model)
{
var homepage = ContentHelper.GetByNodeId<HomepageDocumentType>(model.Content.Id);
var homepageViewModel = new HomepageViewModel(homepage);
return CurrentTemplate(homepageViewModel);
}
}

In our homepage controller, we now need to get the uSiteBuilder document type instance. We can do this using the GetByNodeId method. We pass in the page id and set the type we expect the page to be and we should now get a fully instantiated class that we want.

We can then pass this class into the Homepage View Model’back into the MVC pipeline.

Layout View

In our layout view, we can define

@model JonDJones.BusinessLayer.Interfaces.ILayoutViewModel<Vega.USiteBuilder.DocumentTypeBase>
@RenderBody()

In the homepage view we need to implement from:

@model JonDJones.BusinessLayer.ViewModel.HomepageViewModel
@Model.CurrentPage.PageTitle

Code Example

The code above can be quite hard to wrap your head around when it’s all a flat page or text. To make life a bit easier, I would recommend downloading this working code sample from my GitHub account, JonDJones.com.Umbraco.MegaMenu

Conclusion

In most enterprise CMS projects, using classes to define your document types is a pretty standard process. Using uSiteBuilder plugged into Umbraco means you can now do the same. When we build projects within MVC, we want to separate presentation logic and business logic and create a layout/global view model to render out the header, footer, metadata etc.. wrapping all this code into a view model is the recommended approach to work with MVC.

In today’s guide, we’ve covered all the code to use the uSiteBuilder base template, Vega.USiteBuilder.DocumentTypeBase. We create a result filter, a layout view model that types a Vega.USiteBuilder.DocumentTypeBase and then we pass this out to the controller in order to render everything.

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

3 replies
    • jon
      jon says:

      In most websites I’ve built the top header is usually the same on all pages. I’ve usually created a separate membership header that lives underneath the main header as an MVC partial that would be added to the ‘my account template’. If you want a completely different header, you can still do this. You can create as many layouts as you want and just make sure that your current template inherits from the one you want it to instead. The trick in this instance that each MVC layout you have inherits from the same interface. When the page loads the ILayoutViewModel will still be injected. I’ve used this technique a few times and it works. I might try and write a tutorial how to do this at some point in the future, hope that helps!

      Reply

Trackbacks & Pingbacks

  1. […] unit testable.  This guide assumes that you have a website structure that’s similar to this, How To Create A Global View Model For Umbraco With uSitebuilder and that you have structure map installed followed by this guide, How To Set-Up Structure Map With […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *