No, Glass Mapper can't map Template
or TemplateItem
out of the box. However, it's easy to create field mappers so that it can.
Field Mappers
To map Template
, create the following field mapper:
public class SitecoreFieldTemplateMapper : AbstractSitecoreFieldMapper
{
public SitecoreFieldTemplateMapper()
: base(typeof(Template))
{
}
public override object GetFieldValue(
string fieldValue,
SitecoreDataMappingContext context)
{
if (!ID.TryParse(fieldValue, out var templateId)) return null;
var templateEngine = context.Service.Database.Engines.TemplateEngine;
var template = templateEngine.GetTemplate(templateId);
return template;
}
public override string SetFieldValue(
object value,
SitecoreFieldConfiguration config,
SitecoreDataMappingContext context)
{
if (value == null) null;
var template = value as Template;
if (template == null)
throw new MapperException($"The value is not of type {typeof(Template)}");
return template.ID.ToString();
}
}
To map TemplateItem
, create the following mapper:
public class SitecoreFieldTemplateItemMapper : AbstractSitecoreFieldMapper
{
public SitecoreFieldTemplateItemMapper()
: base(typeof(TemplateItem))
{
}
public override object GetFieldValue(
string fieldValue,
SitecoreFieldConfiguration config,
SitecoreDataMappingContext context)
{
if (!ID.TryParse(fieldValue, out var templateId)) return null;
var item = context.Service.Database.GetItem(templateId);
if (item?.TemplateID != Sitecore.TemplateIDs.Template) return null;
return new TemplateItem(item);
}
public override string SetFieldValue(
object value,
SitecoreFieldConfiguration config,
SitecoreDataMappingContext context)
{
if (value == null) return null;
var templateItem = value as TemplateItem;
if (templateItem == null)
throw new MapperException($"The value is not of type {typeof(TemplateItem)}");
return templateItem.ID.ToString();
}
}
In both cases, you pass the type (e.g., typeof(Template)
) to the base constructor to instruct Glass Mapper which property types it should use the field mapper for (e.g., Template
, IEnumerable<Template>
). The GetFieldValue
method tells Glass Mapper how to read from Sitecore to your property; the SetFieldValue
method tells Glass Mapper how to write from your property back to Sitecore.
You don't need to write separate mappers for IEnumerable<Template>
or IEnumerable<TemplateItem>
because the built-in SitecoreFieldIEnumerableMapper
will handle that for you.
Add to Glass Mapper
Glass Mapper 5 offers a slightly cleaner way to register custom mappers than 4 through pipeline processors. Although the method for Glass Mapper 4 technically works with 5, I recommend the processor approach for flexibility and future-proofing.
Notice that in both versions the mappers are added to the DataMapperFactory
with First
and not Add
. This is important--if the custom mappers are added after the SitecoreFieldIEnumerableMapper
in the DataMapperFactory
, the custom mappers will never get invoked.
Glass Mapper 5
For Glass Mapper 5, create the following pipeline processor to wire up the field mappers:
public class AddTemplateMappers : CreateResolverProcessor
{
public override void Process(CreateResolverPipelineArgs args)
{
var dependencyResolver = args.DependencyResolver;
dependencyResolver.DataMapperFactory.First(
() => new SitecoreFieldTemplateMapper());
dependencyResolver.DataMapperFactory.First(
() => new SitecoreFieldTemplateItemMapper());
}
}
and add it to the glassMapper.createResolver
pipeline:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<glassMapper.createResolver>
<processor type="YourAssembly.AddTemplateMappers, YourAssembly" />
</glassMapper.createResolver>
</pipelines>
</sitecore>
</configuration>
Glass Mapper 4
For Glass Mapper 4, modify the GlassMapperScCustom
in your solution as follows:
public static class GlassMapperScCustom
{
public static IDependencyResolver CreateResolver()
{
var config = new Glass.Mapper.Sc.Config();
var dependencyResolver = new DependencyResolver(config);
dependencyResolver.DataMapperFactory.First(
() => new SitecoreFieldTemplateMapper());
dependencyResolver.DataMapperFactory.First(
() => new SitecoreFieldTemplateItemMapper());
return dependencyResolver;
}
// other methods omitted for brevity
}