Using interfaces with Glass Mapper

In one of my previous blog post I wrote an example on how to add Glass Mapper to Helix.
I will in this blog post provide some code examples on how to map different fields with Glass Mapper. I will also provide some examples on how you could benefit more from Glass Mapper by using interfaces instead of models.

Why use interfaces instead of models

Interfaces can be inherited multiple times, this works well with inherited templates in Sitecore.
We create the common fields in the Helix Foundation layer, and use the mappings in multiple feature projects.
The mapping is created in separate interfaces. The model(interface) that should use the fields only needs to inherit from these interfaces.

For example a simple component with Title and Rich Text would only need to inherit from the GlassBase, Title and Rich Text interface
IMyComponent : IGlassBase, ITitle, IRichText

Inside Sitecore the MyComponent would need the Title and RichText field


The view then has access to the fields, and works well with Experience editor by using the following mehtod:
@Html.Glass().Editable(x => x.RichText)
@Html.Glass().Editable(x => x.Title)

I start my new projects by identifying common fields.
I create two folders, one for single fields (folder named Fields) and one for fields that are used together (older named Sets).

All these fields are being added to a Helix foundation project so they are loaded by Unicorn before any feature projects that uses them.
Fields that are specific for their feature will be added in their feature project.

An interface for a component could look something like this, where we comma separate the common fields and add the Glass Mapper mappings for the specific feature fields in the interface directly:


Inside Sitecore I have this setup for the common fields and sets:


In visual studio a similar structure is used:


Mapping different fields examples:

using Glass.Mapper.Sc.Configuration.Attributes;
using Glass.Mapper.Sc.Fields;
//Required fields for Glass Mapper
[SitecoreType]
public interface IGlassBase
{
// Mandatory for Glass Mapper DO NOT delete
[SitecoreInfo(SitecoreInfoType.Name)]
string Name { get; set; }
// Mandatory for Glass Mapper DO NOT delete
[SitecoreInfo(SitecoreInfoType.TemplateName)]
string Template { get; set; }
// Mandatory for Glass Mapper DO NOT delete
[SitecoreId]
Guid Id { get; set; }
}
//Single-Line Text
public interface ITitle
{
[SitecoreField]
string Title { get; set; }
}
//Example with field name that contains space or has diffrent name in Sitecore
public interface IMenuTitle
{
[SitecoreField("Menu Title")]
string MenuTitle { get; set; }
}
//Image
public interface IImage
{
[SitecoreField]
Image Image { get; set; }
}
//DateTime
public interface IDate
{
[SitecoreField]
System.DateTime Date { get; set; }
}
//General Link
public interface IGeneralLink
{
[SitecoreField("Link")]
Link GeneralLink { get; set; }
}
//File
public interface IFile
{
[SitecoreField]
File File { get; set; }
}
//Checkbox
public interface IShowInMenu
{
[SitecoreField("Show In Menu")]
bool ShowInMenu { get; set; }
}
//getting the Url for the mapped item
[SitecoreInfo(SitecoreInfoType.Url)]
string Url { get; set; }
//maps the children with the IMyItem interface
[SitecoreChildren]
IEnumerable<IMyItem> children { get; set; }
//Use this on the interface to tell Glass Mapper to only return the matched template ID
[SitecoreType(TemplateId = "GUID", EnforceTemplate = SitecoreEnforceTemplate.Template)]

Useful properties and methods

Image
Image has several useful properties, where the Src is the one we use the most:


There is also a method here HasValue() we use this to verify that the image has value before trying to get the image Src.

GeneralLink

To render links in a view the following can be used:


Using SitecoreChildren
The Model:
[SitecoreChildren]
IEnumerable<IMyItem> myItems { get; set; }
//EnforceTemplate Forces Glass to do a Template check agains the TemplateID specified, only children with the correct templateID will be mapped
[SitecoreType(TemplateId = "Guid", EnforceTemplate = SitecoreEnforceTemplate.Template)]
public interface IMyItem : IGlassBase
{
[SitecoreField("My Title")]
string ListTitle { get; set; }
[SitecoreField("My Teaser")]
string ListTeaser { get; set; }
[SitecoreField("My Image")]
Image ListImage { get; set; }
[SitecoreField("My Logo")]
Image ListLogo { get; set; }
[SitecoreInfo(SitecoreInfoType.Url)]
string Url { get; set; }
[SitecoreField("List Read More")]
string ListReadMore { get; set; }
}

The View:
@foreach (Mytem myItem in Model.myItems)
{
//myItem must be spedified so the correct item fields are beeing used
@Html.Glass().Editable(myItem, x => x.ListImage)
@Html.Glass().Editable(myItem, x => x.ListLogo)
@Html.Glass().Editable(myItem, x => x.ListTeaser)
@Html.Glass().Editable(myItem, x => x.ListTitle)
<a href="@myItem.Url">@Html.Glass().Editable(myItem, x => x.ListReadMore)</a>
}
view raw myItem.cshtml hosted with ❤ by GitHub

Methods to map the correct Sitecore Items

//Maps the current item
ISitecoreContext context = new SitecoreContext();
IRichText richText = context.GetCurrentItem<IRichText>();
//Maps the DataSourceItem
IRichText richText = GetDataSourceItem<IRichText>();
//Maps the Item based on Guid
IMenuItem menuItem = context.GetItem<IMenuItem>(firstLevelChild.ID.Guid);
view raw GlassMethods.cs hosted with ❤ by GitHub

Comments

Popular posts from this blog

Step by step guide to add Glass Mapper to Helix solution

Adding dynamic image source for multi-site solutions with $site$ token and setting dynamic datasource location for components