3
votes

Setup

Models

POCOs, virtual is required by Glass Mapper.

using System.Collections.Generic;
using Glass.Mapper.Sc.Configuration.Attributes;
using Glass.Mapper.Sc.Fields;

namespace Sample
{
    public class Parent<T>
    {
        [SitecoreId]
        public virtual Guid Id { get; set; }
        public virtual string Title { get; set; }
        public virtual IEnumerable<T> Children { get; set; }
    }

    public class Article
    {
        [SitecoreId]
        public virtual Guid Id { get; set; }
        public virtual string Title { get; set; }
        public virtual string Text { get; set; }
    }

    public class Teaser
    {
        [SitecoreId]
        public virtual Guid Id { get; set; }
        public virtual string Title { get; set; }
        public virtual Image Banner { get; set; }
    }
}

Views

Referenced by Sitecore as view renderings, with the model pointing to Sample.Parent (see below for Sitecore model definitions).

@inherits Glass.Mapper.Sc.Web.Mvc.GlassView<Sample.Parent<Sample.Article>>

<h1>@Editable(x => x.Title)</h1>
<div class="article-list">
    @foreach (var article in Model.Children)
    {
        <article class="article">
            <h2 class="article-title">@Editable(article, x => x.Title)</h2>
            <div class="article-content">@Editable(article, x => x.Text)</div>
        </article>
    }
</div>
@inherits Glass.Mapper.Sc.Web.Mvc.GlassView<Sample.Parent<Sample.Teaser>>

<h1>@Editable(x => x.Title)</h1>
<div class="teaser-list">
    @foreach (var teaser in Model.Children)
    {
        <article class="teaser">
            <h2 class="teaser-title">@Editable(teaser, x => x.Title)</h2>
            <div class="teaser-banner">@RenderImage(teaser, x => x.Banner)</div>
        </article>
    }
</div>

Sitecore model definitions

Here's where I'm not sure if I did it right. These are the model types I defined as the Sitecore models (under /sitecore/layout/models).

  • Sample.Parent`1[T], Sample

    Also tried (without success):

    • Sample.Parent, Sample
    • Sample.Parent`1[Sample.Article, Sample], Sample
    • Sample.Parent<Sample.Article>, Sample)
  • Sample.Article, Sample

  • Sample.Teaser, Sample

Is this possible?

The example code is simplified, but should capture what I'm trying to do. Basically I want to be able to use the generic type as a way to reuse more code. Because of external restrictions I'm unable to use anything but Glass Mapper 3. The errors I'm seeing are either that Sitecore cannot find the type, or a "object reference not set" (it appears to use Sitecore.Mvc.Presentation.RenderingModel, Sitecore.Mvc as a model when this happens).

Or am I being crazy? :) Is there a better way to accomplish this?

1
When you say "the model pointing to Sample.Parent", did you create a Model definition under /sitecore/layout/Models and then set that in the Model field of your View Rendering definition under /sitecore/layout/Renderings? I don't normally use generics, I usually use model inheritance... - jammykam
@jammykam Yes, that's correct. After I wrote this I also tried the inheritance approach and it does work in this case. Though it then requires me to define types such as class MyType : Parent<Article>, and then reference that from Sitecore. This (to me) defeats the purpose somewhat. At least I don't have to write duplicate code, but I do have to add a reference to each type in Sitecore. Thankfully the views can keep the generic type declaration. - Simon Ingeson
AFAIK, you have to add the references to the types in Sitecore, otherwise the View will expect an object of type RenderingModel, so there's no way around that. If you set up your template inheritance correctly then generally it's not an issue since you are always binding against the most specific template possible. In your specific example above, you could also use Types Inference: glass.lu/Mapper/Sc/Tutorials/Tutorial17 - jammykam
@jammykam Thanks! I'll look into that and report my findings :) - Simon Ingeson

1 Answers

1
votes

I think there is probably difficulties in the way that Glass tries to process the generic string (To be honest I never designed it to handle generic strings).

If you are using V4 then you don't need to define a model in Sitecore. Leave the model field blank and Glass should resolve the model from the @inherits deceleration in the cshtml file.