7

How can I use Unicorn to generate Glass Mapper models for my Sitecore items?

2 Answers 2

6

The Sitecore.CodeGenerator project can convert serialized Sitecore items into GlassMapper classes, and it contains support for the Rainbow serialization format (used by Unicorn 3).

The project page has step-by-step instructions on how to install and configure it.

1
  • Is it working with Unicorn 4? I followed GitHub readme instruction, but step 5 doesn't seem to be working In GlassGenerator.tt, change the following code so the path references your serialized data:Context.Host.ResolvePath(@"..\Data\serialization\"). The path is relative to the location of the .tt files.
    – Vincent
    Commented May 15, 2017 at 7:57
2

You will have to use Rainbow (the serialization part of Unicorn) to read the YAML files and the process those with a T4 template.

I have a tool that will do the reading for you and make the objects available in a T4 template. You can use this code for that: https://github.com/Fortis-Collection/fortis.codegen.transitus.rainbow. It is also available as a NuGet package that you can install in your project. Use:

Install-Package Transitus.Rainbow

Once you have this in your project you need to parse the .yml files.

Example code:

var items = Transitus.Rainbow.TransitusProvider.FolderDeserializer.Deserialize(@"C:\Projects\transitus.rainbow\Files");
var templates = Transitus.Rainbow.TransitusProvider.TemplateFactory.Create(items);

Here is an example T4 template that uses that:

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ assembly Name="System.Core" #>
<#@ assembly Name="System.Windows.Forms" #>

// TODO: Set the paths for the assembly bindings based on the version you have installed
<#@ assembly name="$(SolutionDir)\packages\Rainbow.Core.1.1.0\lib\net45\Rainbow.dll" #>
<#@ assembly name="$(SolutionDir)\packages\Rainbow.Storage.Yaml.1.1.0\lib\net45\Rainbow.Storage.Yaml.dll" #>
<#@ assembly name="$(SolutionDir)\packages\Transitus.Rainbow.1.0.4.0\lib\net45\Transitus.Rainbow.dll" #>

// TODO: make sure the namespace imports include everything you need in your templates
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Globalization" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="Transitus.Rainbow" #>

/*
 * Generated Model Templates
 *
 * Generated at <#= DateTime.Now #>
 */
<#
    var stopwatch = Stopwatch.StartNew();

    // get the project solution path, we can use this to find the unicorn files
    string solutionsPath = this.Host.ResolveAssemblyReference("$(SolutionDir)");
    // Set a base path for all unicorn configurations that we want to use
    var myFolder = solutionsPath + @"..\Unicorn";

    // Add each configuration we want to create models for into a list
    var folders = new List<string>
    {
        myFolder + @"..\Default Configuration\User Defined"
    };
#>

<#
    var items = new List<IItem>();

    foreach (var folder in folders)
    {
        var deserializedItems = Transitus.Rainbow.TransitusProvider.FolderDeserializer.Deserialize(folder);

        items.AddRange(deserializedItems);
    }

    var templates = Transitus.Rainbow.TransitusProvider.TemplateFactory.Create(items);
#>  

using System;
using System.Collections.Generic;
using Sitecore.Data.Items;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Linq.Common;
// TODO: Add glass mapper using statements that you need here

<#

    foreach (var template in templates)
    {
        var isRenderingParametersTemplate = HasRenderingOptionsBase(template.BaseTemplateIds, template.Id);
#>
#region <#= template.Name #>
namespace MyProject.Models
{
    public partial interface I<#= template.Name #> 
    {
<#+
        foreach(var field in template.LocalFields)
        {
#>
        /// <summary><para>Template: <#= template.Name #></para><para>Field: <#= field.Name #></para><para>Data type: <#= field.TypeName #></para></summary>
        WORKOUTRETURNTYPE <#= field.Name #> { get; }

<#+
        }
#>
    }

#>
}
#endregion
<#
    }   
    stopwatch.Stop();
#>
// Generated in <#= stopwatch.ElapsedMilliseconds #>ms
// Found <#= templates.Count() #> templates in <#= folders.Count() #> folders [<#= myFolder #>]

There is still a lot to do in that example - but it should give you a start.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.