Map your rendering parameters to your Glass.Mapper viewmodels in Sitecore

HeroImage

I’ve been having(and still) the great pleasure to work with Glass.Mapper for Sitecore and I must say it makes your life so much easier as a developer. Mike Edwards, the founder has done one heck of a job πŸ™‚

I really like the interface model approach where you let an interface represent a sitecore item.

This is a quick post regarding rendering parameters and mapping them to a viewmodel.

In Glass.Mapper when using(inheriting) the GlassController you will find some very nifty methods like GetDataSourceItem and GetRenderingParameters.

Let’s say you have following rendering parameters in Sitecore:
RenderingParams

This is how it will be represented as an interface

[SitecoreType(TemplateId = "{here is a template id}", AutoMap = true)]
public interface IVisibilityRenderingParameters
{
	bool VisibleOnDesktop { get; set; }

	bool VisibleOnTablet { get; set; }

	bool VisibleOnMobile { get; set; }
}

To get the rendering parameters in your Action Result you just have to call the GetRenderingParameters method(You need of course inherit the GlassController to your controller).

  IVisibilityRenderingParameters renderingParameters = GetRenderingParameters<IVisibilityRenderingParameters>();

That is very nice and so easy to use.

Now what I would like to do is to add(map) the parameters to my interface viewmodel. Here is the viewmodel representing a news spot item:

[SitecoreType(AutoMap = true)]
public interface INewsSpotModel : IVisibilityRenderingParameters
{
	string Header { get; set; }
		
	string Subheader { get; set; }

	Image BackgroundImage { get; set; }

		
}

As you can see I’m inheriting the IVisibilityRenderingParameters.

What will happen when I call the GetDataSourceItem(which is also from the GlassController) for the viewmodel INewsSpotModel?

  INewsSpotModel model = GetDataSourceItem<INewsSpotModel>();

Well the tree properties from IVisibilityRenderingParameters will not be set, but…

What if we could do something like this and get the data from the rendering parameters to the viewmodel

  INewsSpotModelmodel = GetDataSourceItemWithRenderingParameters<INewsSpotModel, IVisibilityRenderingParameters>();

I’ve added a generic method to our controller(best would be if you had a base controller which of course needs to inherit the GlassController).

using AutoMapper;
using Glass.Mapper.Sc.Web.Mvc;

namespace Sandbox.Website
{
	public class MyBaseController : GlassController
	{

		/// <summary>
		/// Map rendering parameters to datasource item interface.
		/// </summary>
		/// <typeparam name="TModel">Datasource item interface</typeparam>
		/// <typeparam name="TRenderingParameters">Rendering parameters interface</typeparam>
		/// <param name="isLazy"></param>
		/// <param name="inferType"></param>
		/// <returns></returns>
		protected TModel GetDataSourceItemWithRenderingParameters<TModel, TRenderingParameters>(bool isLazy = false,
			bool inferType = false) where TModel : class where TRenderingParameters : class
		{
			TModel model = GetDataSourceItem<TModel>(isLazy, inferType);

			TRenderingParameters parameters = GetRenderingParameters<TRenderingParameters>();

			//If no parameters
			if (parameters == null)
				return model;

			Mapper.Initialize(cfg => cfg.CreateMap<TRenderingParameters, TModel>());

			model = Mapper.Map(parameters, model);

			return model;
		}
	}

}

We will get the viewmodel(TModel) item using the GetDataSourceItem method and to get the rendering parameters(TRenderingParameters) we use the GetRenderingParameters method.

Now to map the rendering parameters to the viewmodel we will use AutoMapper. In the Mapper.Initialize method we will set the mapping configurations and it’s all generic πŸ™‚

 Mapper.Initialize(cfg => cfg.CreateMap<TRenderingParameters, TModel>());

The actual mapping happens in this line:

 model = Mapper.Map(parameters, model);

To make it even prettier we could move the mapping configuration(and initializing) to a dependency injection container. But then we will have to specify what viewmodel is using/inheriting rendering parameter model and so on.

I’m not sure if we could use something from Glass.Mapper instead, I mean there is AutoMap().

That’s all for now folks πŸ™‚


2 thoughts on “Map your rendering parameters to your Glass.Mapper viewmodels in Sitecore

  1. Interesting read and I wish I had implemented something similar in my last project, It used plenty of Rendering Parameter templates.

    I think you are right with regards to finding a Glass way of mapping instead of the AutoMapper .Map but I’m not sure how you would. I would also be interested in finding out more about the Mapping and Initialization via a DI.

    One final observation, on the TModel constraint don’t you need to specify TRenderingParameters as the base type ?

    Liked by 1 person

    1. Hey Mark
      Thanks for reading πŸ™‚

      You know what? With the latest Automapper you don’t need to do this anymore:
      Mapper.Initialize(cfg => cfg.CreateMap());

      Just this(If you have it as DI):
      model = Mapper.Map(parameters, model);
      Pretty neat πŸ™‚

      About specify base type for TRenderingParameters, I use class
      At the end of the method:
      TRenderingParameters : class

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.