Dynamic Views

Topics: Writing modules
Jul 7, 2011 at 12:23 AM
Edited Jul 7, 2011 at 12:25 AM

Can I define a dynamic view that allows the view to be defined on a part (from the Views directory) and selected at runtime?

For example in my ProductDriver class:

public class ProductPartDriver : ContentPartDriver<ProductPart>
    protected override DriverResult Display(ProductPart part, string displayType, dynamic shapeHelper)
        var products = Service.GetProducts();
        var template = part.Template;

        //return ContentShape("Parts_Product",() => shapeHelper.Parts_ProductList(Products: products));
        return ContentShape("Parts_Product",() => shapeHelper.template(Products: products));

What I want to do here is replace the Part_ProductList with a template that can be defined on the Part i.e. shapeHelper.template(Products: products) or similar.

Maybe the DisplayType comes into play here?

Any ideas?


Jul 7, 2011 at 12:41 AM

You are free to name the part any name you want, and the template will be resolved according to that name.

Jul 7, 2011 at 1:28 AM
Edited Jul 7, 2011 at 4:22 AM

Great but struggling to get the following to work:

    return ContentShape("Parts_Product",() => shapeHelper.part.Template(Products: products));

I have tried saving various combinations in part.Template but my template is not being found. I assumed storing "Parts_ProductList" would resolve accordingly.

It works with the Editor as you define the TemplateName explictly e.g.

   return ContentShape("Parts_Product_Edit", () => shapeHelper.EditorTemplate(TemplateName: part.Template, Model: part, Prefix: Prefix));

What am I doing wrong?

Jul 7, 2011 at 10:06 PM

return ContentShape("Parts_Product", () => ShapeHelper.Parts_Product(Products:products, ContentPart:part, ContentItem: part.ContentItem) or something like that should work just fine.

Jul 7, 2011 at 10:45 PM

In the Display, I don't have a problem returning a specific shape e.g Parts_ProductList if coded.

The code above doesn't address the issue. What I am trying to do here is replace Parts_ProductList with a variable that can be assigned at runtime so I can implement different views for different clients with the same module without code change. The only other way I see I can do it is to predefine a few views and select them from a dropdown e.g. Parts_ProductList1, Parts_ProductList2...

As in the Editor, can I determine the shape in the Display at runtime?

Jul 7, 2011 at 10:57 PM

There are many ways you can create the shape. ShapeHelper is a convenient way to do it, but you could just as well use an IShapeFactory and call create on that, passing in the string that you want for your shape name.

Jul 8, 2011 at 12:24 AM

Thanks Bertrand, we got it going using IShapeFactory. Code snippet:

var dict = new Dictionary<string, object> {{ "Products", products }};
var args = ClaySharp.Implementation.Arguments.From(dict.Values, dict.Keys);
return ContentShape("Parts_Product", () => ShapeFactory.Create(part.Template, args));

The part.Template is resolved at runtime and can be chosen from a dropdown (of views in the relevant directory).

Thanks again. Orchard is looking awesome as we delve further into it.