Monthly Archives: August 2016

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 🙂

Advertisements