Experience Sitecore ! | All posts tagged 'Code-generation'

Experience Sitecore !

More than 200 articles about the best DXP by Martin Miles

Glass Mapper with Sitecore 9 and Helix

I was trying to implement T4 CodeGeneration of Glass Mapper for my current Helix on Sitecore 9 project. In the beginning, it all went well, and I did not suspect any of issues. However, the issues still occurred later when trying to navigate to LaunchPad. I have been presented a very confusing error with the description, saying:

The file '/sitecore/shell/client/Speak/Layouts/Layouts/Speak-Layout.cshtml' does not exist.

on the following screen:


After investigating a call stack, I came to the conclusion that it is definitely something with Glass Mapper. After playing a while with my configuration, I have identified exact getModel pipeline processor that triggered that issue:

  <mvc.getModel>
    <processor patch:before="*[@type='Sitecore.Mvc.Pipelines.Response.GetModel.GetFromItem, Sitecore.Mvc']" 
         type="Glass.Mapper.Sc.Pipelines.Response.GetModelFromView, Glass.Mapper.Sc.Mvc"/>
  </mvc.getModel>

Commenting this line returned LaunchPad fully functional, however, obviously, Glass Mapper stopped working with a familiar Sitecore MVC error:

The model item passed into the dictionary is of type 'Sitecore.Mvc.Presentation.RenderingModel', but this dictionary requires a model item of type 'Sitecore.Feature.Navigation.Models.ILink'.

So I started digging around and assumed that maybe I have got not the latest version of Glass, that does not support Sitecore 9. With that in mind, I updated to latest stable version of Glass, which was 4.4.0.199. After upgrading, I tried to run build but it failed. Again, much time spent on investigation, so later found out that latest version of Glass does not have namespace Glass.Mapper.Sc.Configuration.Attributes. Previously that namespace was at Glass.Mapper.Sc.dll but that dll did not present within the latest package.

Suddenly ReSharper came into a play, obligingly offering to reference required library. After ReSharper added that reference - project compiled successfully. I performed a deployment, and ... it broke again, with the same error. What? Why? How? I couldn't understand that...

Furthermore investigations... at some moment, I noticed that ReSharper referenced one of the old Glass.Mapper.Sc.dll from somewhere, so the very first thing I made sure was to provide thorough sanity check and fix across entire solution. After removing all Glass Mapper trails, I've readded latest version of Glass Mapper again, and expectedly it did not find that namespace, mentioned above.

At this time I took dotPeek and carefully went through all the libraries. Just to find out that there is no such namespace, indeed- in all of the Glass libraries.

But wait! What if... What if.. If I try to check that namespace in the latest beta version?

So I picked up the latest available beta version, which was 4.4.1.331 ...

Install-Package Glass.Mapper.Sc -Version 4.4.1.331-beta

... and voila!!! Namespaces were there. So I decided to go ahead with that beta versions, and trick did work!

After couple more sanity clean-up in both my solution and web folder, I finally did some required configuration changes, then install for certain projects in your solution and finally concluded that solution work well for me.

Helix + Glass Mapper + T4 Templates = Code Generation

The objective of given exercise is to achieve automatic code generation of Glass Mapper model (an interface) from a corresponding serialized interface template.

First of all, you need to install Visual Studio Extension for T4 templates: for Visual Studio 2017 or 2015. Also very recommend installing Devart T4 Editor - a markup highlighter and intellisense for T4 templates, that is also a plugin for Visual Studio 2017 or 2015.

Another prerequisite is Glass Mapper itself, obviously. I would advise going with BoC.Glass.Mapper.Sc by Chris Van Steeg from Sitecore NuGet repository. The fork contains several fixes for code-first and content search usage (project fork GitHub page).

The main thing you need is Sitecore CodeGenerator, located in https://github.com/hermanussen/sitecore.codegenerator

You'll also need to have "base" templates - GlassGenerator.tt and GlassMappedClassTemplate.tt as below:


SitecoreTemplates.tt - is the template you are going to copy to each module where you may need to generate models, you may want to rename each instance of it to reflect module name.

Once copied, just paste a list of your interfaces templates into SitecoreTemplates.tt (or WhateverYouCallIt.tt, in the example below I called that same as a module name) and save the file, or optionally right-clicking "SitecoreTemplates.tt" and choosing "Run Custom Tool". You'll see you interfaces magically generated as the child items of *.tt file, with all the references set up (in my case ILink.gen.cs and ILinkMenuItem.gen.cs)

NavigationTemplates.tt (from Feature/Navigation module):

<#@ template language="C#" debug="True" #>
<#@ output extension="gen.txt" #>
<#@ include file="T4Toolbox.tt" #>
<#@ include file="$(SolutionDir)tools\CodeGeneration\T4.Templates\base\GlassGenerator.tt" #>
<#
	GlassGenerator generator = new GlassGenerator(
			"master",
			new [] { 
					"/sitecore/templates/Feature/Navigation/_Link",
					},
			(fieldId, fieldOptions) =>
				{
				});
    generator.Run();
    
	WriteLine("These files were generated:");
#>



I am attaching these TT files for your convenience below:

GlassGenerator.tt (3.6KB), GlassMappedClassTemplate.tt (3.8KB) and SitecoreTemplates.tt (1020B).

If you need to change the way how the code is being generated please consider modifying "GlassGenerator.tt" and "GlassMappedClassTemplate.tt" file located in "Configuration\CodeGeneration\Templates\Base\" solution folder.


Notes: you may have Sitecore.CodeGenerator as a part of your solution, or unload from it - code generation still would work, just please make sure template files are referencing the right paths. Samples provided above are configured as at the image above.