Shape for custom class

Topics: Customizing Orchard, Writing modules
Apr 17, 2013 at 8:01 AM
Edited Apr 17, 2013 at 8:04 AM
Let's say I have abstract class ModelA. I've createD subclasses of ModelA called ModelB and ModelC. I want to create view in my module that renders list of instances of subclasses ModelA. Something like this:
@foreach(var model in (@Model as IEnumerable<ModelA>))
   //render "model"
The thing is, that I want to customize UI of ModelB and ModelC separately (I want to make their front-end different [different cshtmls] ).
I assume that I should create shapes for ModelB and ModelC, right? Should I create content driver? I do not need to access it (content type or shape) from dashboard (so I do not need to create record). So can I create partless content type? Is somewhere tutorial or guid how can I acomplish it?
Apr 17, 2013 at 10:11 AM
Edited Apr 17, 2013 at 10:11 AM
Yes, all you have to do is create shapes and render those things. Drivers are needed only when you create content parts that need rendering and/or be welded on to content types. Ultimately, the rendering is all done with shapes, so if you can create shapes without drivers, that's perfectly fine.

In your scenario, you could go about it in at least 2 ways:
  1. Create 2 shape types that have the same properties as your 2 models.
  2. Or, use a single shape type, but add an alternate based on your model's type name, and stick the model (A or B) into a property on your shape. Your 2 alternate views will know what their model is, since you created those alternates.
Apr 17, 2013 at 10:26 AM
Edited Apr 17, 2013 at 11:10 AM
Thanks for a reponse!
The problem is.. I do not know how to create shape. There are tutorials that shows how to build shapes with driver, but I do not need any driver. Do you know any tutorial or sample? I'd like to impelement it in the second way. I've tried to create shape on my own, but it was completely failure.

I've created shape:
        public void Discover(ShapeTableBuilder builder)
                displaying =>
                        var elementObject = displaying.Shape;
                        var elementId = elementObject.Id;
                        elementObject.Metadata.Alternates.Add("MyModel__" + EncodeAlternateElement(elementId));

        private string EncodeAlternateElement(string alternateElement)
            return alternateElement.Replace("-", "__").Replace(".", "_");
How can I associate it with MyModelB that id equals 10 (let's say). I want to use it in view as
How can I "bind" it with shape?

I've figured out solution :)
    @foreach (var model in @Model)
            @Display(@New.MyModel(Id: model.Id, modelInstance: model))

Working! :)