Widget Razor Templates

Topics: Writing modules
Jun 21, 2011 at 11:44 PM

We have built a module with a Product Content Type (and Product Part) that will contain search parameters (to a remote product database) defined at runtime. The widget will be used in several places within the same site and the module will be common to other sites. We want to write Razor code to style the output differently for each instance of the Product Widget (e.g. 2 columns, 5 rows...). We used template (files) in a previous system.

Can we define parts where we enter Razor code that render at runtime, or do we need to reference file based templates? What is the best approach?

Coordinator
Jun 21, 2011 at 11:56 PM

Can you provide a little more information on what determines what template to use?

Jun 22, 2011 at 5:56 AM

Typically what determines which template to use is based on either a view mode (List vs Detail) or a specific shape the client wants.

Further investigation has led me to test the view mode in the ProductDriver and invoke the specific Views > Parts > ProductList.cshtml or ProductDetails.cshtml view. e.g.

protected override DriverResult Display(ProductPart part, string displayType, dynamic shapeHelper)
{
    if (part.ViewMode == "List")
    {
        return ContentShape("Parts_Product", () => shapeHelper.Parts_ProductList(
                        ViewMode: part.ViewMode,
                        Location: part.Location,
                        Show: part.Show));
    } else {
        return ContentShape("Parts_Product", () => shapeHelper.Parts_ProductDetail(
                        ViewMode: part.ViewMode,
                        Product: part.Product,
                        Show: part.Show));
    }
}

This works really well and may be the best solution, using Orchard Shapes and the dynamic objects passed through.

The .cshtml views can test specific datat passed through and make decisions e.g.

@if (Model.Show == "Specials")
{
  display specials...
}

Your thoughts?

 


Coordinator
Jun 22, 2011 at 6:17 AM

Sounds good to me. What is the difference between your view mode and our display type though?

Jun 22, 2011 at 10:22 AM

Looks promising but not sure how I can set the Display Type at runtime?
Or would I define something different by say List, Detail, Summary (the default) and then choose the relevant one? If so, what am I defining?

Still new to Orchard and trying to understand the plumbing. Seems Shapes are part of the solution here.

Note these Widgets are going to display product data from a remote WCF Service.

Jun 22, 2011 at 6:20 PM

Orchard has a fairly complex system of "alternate templates" - so you can send one shape to the display, and provide a number of different templates to situationally render that shape how you need.

If you enable Shape Tracing you can use it to probe the page and see what alternate names are already there. I believe you can customise templates per-zone already.

Then you can implement IShapeTableProvider and add your own alternates there depending on whatever parameters you need.

The display types arise from the BuildDisplay methods that are typically called from ItemControllers. Normally there's no way to change this, but you can build your own displays of content items by calling IContentManager.BuildDisplay(...) and use different content types - that would involve going somewhat outside the widgets/layers system. I have a module called Mechanics that allows you to attach content or widgets to other content, and have them display in zones alongside that content, with customisable DisplayType. So if you need really flexible configuration that could be what you need.

Coordinator
Jun 22, 2011 at 9:48 PM

The display type of a shape can also be changed at any time. It's just a property on the Metadata.