One of the most common questions asked about Glass is about code generation. Although Glass does not have it's own way of generating templates you can easily use third party tools such as Team Development for Sitecore to generate your models.

Code generation is great because it simplifies the process of generating your models. It also ensures that your models contain the correct fields and avoids the situation where a field is deleted but the property still exists in your code. 

Models that are based on the templates and generated by code generation I term Template Models, but there is also another type of model which I term Rendering Models. Rather than represent the data source Rendering Models represent the data that is need by view (a user control, or Razor view) . In this blog post I will explore the advantages of each an when you might want to use one rather then other.

Template Models

I will start with Template Models because most developers will probably start with these. Template Models are literally as the name states, the model maps all the fields that the template contains. For example if I had the following template:

 

My model will contains all the fields as properties:
    public partial interface IPageTitles : IGlassBase 
    {
        bool DisplayInMenu  {get; set;}
	bool Dropdown  {get; set;}			
	string Icon  {get; set;}
	string LongTitle  {get; set;}			
	string ShortTitle  {get; set;}
	string StrapLine  {get; set;}
    }

This makes it very easy to find the model you want to use because you just have to look at the name of the template and then find the matching class.

One issue to overcome is the multiple inheritance of templates. This is easily solved by making use of interfaces as we have done above. A model of a sub-template can easily inherit the interfaces of the super-templates. For example if I have a content page that inherits my IPageTitles template and a IMetadata template then my Content interface can inherit both:
public interfacet Content : IPageTitles, IMetadata{
}

Template Models are easy for new developers to understand and it is easy to trace where the data is coming from however it does have certain limitations:

  1. It requires a lot of code to be written and maintained and this is why developers opt to use code generation tools. Trying to write all this code by hand would be tedious and time consuming.
  2. To accurately replicate the multiple inheritance of Sitecore templates the solution must use interfaces for all the models. This forces your models to be Anemic Domain Models and reduces the flexibility of your model. It is possible to add some functionality via extensions methods but this would be an awkward solution.
  3. All the fields are mapped even if you are only using one. Take for example a template that has 50 different fields, your code might only use the Title field but the other 49 fields had to be mapped as well, this isn't very efficient.

There are several scenarios when Template Models have a clear advantage:

  • Saving or creating items in Sitecore.
  • The template fields map one to one with the rendering, e.g. templates used as data sources for rendering components
  • Rendering parameters
  • Code generation

Rendering Models

Rendering Models are models that are designed to contain just the properties that required by a rendering. For example lets create a model that represents the breadcrumb at the top of this page:

    public class Breadcrumb
    {     
        [SitecoreQuery("ancestor::*[@displayinbreadcrumb='1']", IsRelative = true)]
        public virtual IEnumerable<Breadcrumb> Ancestors { get; set; }
        
        public virtual string ShortTitle { get; set; }

        public virtual string Url { get; set; }
    }

You can see that this model contains just the properties we need to render the breadcrumb. The model is also responsible for retrieving the ancestor items removing the need for any additional code. My model has now become a bit smarter and part of the logic that I might have had to put into a controller or web control is now in the model.

As a result of not having to represent Sitecore's multiple template inheritance I am now free to use a class. This allows me to start adding logic and methods to my model, for example I am going to update my Breadcrumb title so that it checks if a ShortTitle has been supplied and if it hasn't then use the item's name:

    public class Breadcrumb
    {
        [SitecoreQuery("ancestor::*[@displayinbreadcrumb='1']", IsRelative = true)]
        public virtual IEnumerable<Breadcrumb> Ancestors { get; set; }

        protected virtual string ShortTitle { get; set; }

        protected virtual string Name { get; set; }

        public virtual string Url { get; set; }

        public string Title
        {
            get { return string.IsNullOrWhiteSpace(ShortTitle) ? Name : ShortTitle; }
        }

    }

Notice that I have made the ShortTitle and Name properties protected and exposed the Title property, by doing this I make it clearer to anyone using the class which property should be used for rendering.

We can see that the Rendering Model gives a lot more flexibility in how we map our data and also in how we manipulate it. Rendering Models can easily pull in data from other items in Sitecore using configuration such as SitecoreQuery, SitecoreNode, SitecoreChildren and SitecoreLinked. The properties that you expose via the Rendering Model also make it clearer what information should be available to the rendering when another developer looks at the model.

However Rendering Models still have some limitations:

  • It is difficult to link properties to the fields in Sitecore. One solution is to use code generation to create a list of field name constants and then use attribute or fluent configuration to link these names to the properties on your view models but this is more labour intensive. 
  • Fields are duplicated in multiple models, for example I have the Breadcrumb model above which contains the ShortTitle field but I might also have a PageHeadings model that has a ShortTitle property as well.
  • Must be hand-coded, this is both a positive and a negative. Personally I don't mind crafting my models myself but I know that this isn't the same for everyone.
  • Some people may not like logic being pushed onto the model, for example the query shown in the Breadcrumb example.

Despite these limitations Rendering Models have the advantage that they can be used everywhere. Almost all the code you will write in a solution is a view of your data in one manor or another.


Summary

When thinking about your Sitecore models don't just think of them as having to match you template. One of the major advantages of Glass is it's flexibility to allow you to craft your models in a way that suits your solution with relatively few lines of code. 

As you start to make use of Rendering Models instead of Template Models you will quickly find that much of the backend code that you wrote to manipulate the data into a sensible manor is no longer need because the model does this for you.
comments powered by Disqus