5

I have a Helix based solution using Glass mapper. I want to build a Feature module with a component that renders an item and its children with a controller rendering. Per Helix guidelines, my feature module defines "interface" templates for the item and its children and in the project layer, I have "concrete" templates which inherit the feature's interface templates. Is there a way to write Glass Mapper code (only in the Feature module) which will work with templates derived from the interface templates?

Feature module code:

[SitecoreType(true, "{152BC181-FF05-4FDD-863A-47557CDAB763}", TemplateName = "_RichTextList")]
public interface IDatasource : ISitecoreItem
{
}

[SitecoreType(true, "{1DE3EB16-98D4-4787-88CB-2E065E00B219}")]
public interface IDatasourceChild : ISitecoreItem
{
    [SitecoreField("{4502C93C-FAA2-4FC5-8D3D-993B64E5E187}", SitecoreFieldType.RichText, FieldName = "Text", ReadOnly = true)]
    string Text { get; set; }
}

public class DataSourceViewModel
{
    public IDatasource Datasource { get; set; }
    public IList<IDatasourceChild> Items { get; set; }
}


public class MyController : GlassController
{
    public ActionResult MyComponent(IDatasource datasource)
    {
        var viewModel = new DataSourceViewModel
        {
            Datasource = datasource,
            Items = datasource?.Children.OfType<IDatasourceChild>().ToList() ?? new List<IDatasourceChild>()
        };
        return View(viewModel);
    }
}

The above code only works when the child items of the datasource use the interface template from the feature module, but not when it uses the "concrete" template from the project layer.

3

When you define the IDatasourceChild interface, you need to make sure that the EnforceTemplate property on the SitecoreType attribute is set to enable inheritance. The options are:

public enum SitecoreEnforceTemplate
{
    /// <summary>
    /// Will not enforce template check
    /// </summary>
    No,
    /// <summary>
    /// Checks only the items template
    /// </summary>
    Template,
    /// <summary>
    /// Checks the items template and any base templates
    /// </summary>
    TemplateAndBase

}

So set it to TemplateAndBase and it should work with your inheritance. The default is Template so that will not work for derived templates, so it only works with your interface template.

E.g.

[SitecoreType(true, "{1DE3EB16-98D4-4787-88CB-2E065E00B219}", EnforceTemplate = SitecoreEnforceTemplate.TemplateAndBase)]
public interface IDatasourceChild : ISitecoreItem
{
    [SitecoreField("{4502C93C-FAA2-4FC5-8D3D-993B64E5E187}", SitecoreFieldType.RichText, FieldName = "Text", ReadOnly = true)]
    string Text { get; set; }
}
  • this doesn't seem to work for me for some reason. I tried to create a separate solution to remove the possibility of something else interfering here, but it did not change the outcome :-( BTW I noticed you put the EnforceTemplate on the Text property, I think it's meant to go on the interface declaration right? – Matthew Dresser Jul 26 '17 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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