DisplayFor on IContentData

Vote:
 

In CMS 11, I would use DisplayFor or PropertyFor on IContentData properties in my view model. For blocks this could also resolve the template tag from the view data.

Example usage resolving to MenuBlock.Footer.cshml:

@model IPageViewModel
<html><head></head>
<body>
   @RenderBody()
   @Html.DisplayFor(m => m.Menu, new { Tag = "Footer" }) 
</body>
</html

I'm attempting to upgrade to CMS 12, but this appears to now render the properties of the block instead of using any tag variant of the partial views.

I've attempted to use the following, but it does not pull the template tag version as the tag is not set in the view data:

@{ Html.RenderContentData(Model.Menu, false, "Footer"); }  

Is there a preferred way to render the tag-version partial view?  Do I need to wrap this in a ContentArea to handle the tag?

#284620
Edited, Jul 29, 2022 22:17
Vote:
 

I've not written an example but I believe your original DisplayFor example is correct (maybe use PropertyFor instead since its edit mode aware).

What you probably need to do is tell Optimizely how to use your tag. Either do that by registering a new templatemodel via by implementing IViewTemplateModelRegistrator or define your tags in a TemplateDescriptor attribute. Foundation has a ton of examples you can look at.

#284732
Jul 31, 2022 23:01
Vote:
 

I think it still will attempt to display the properties, not use the any version of the views.

In Foundation, I can get similar results from the Features/Preview/Index.html by adding the following:

<h1 class="preview">PropertyFor</h1>
@Html.PropertyFor(m => m.PreviewContent)
#284766
Aug 01, 2022 15:26
Vote:
 

I found an answer. The core problem is the view models that have properties of type IContentData cannot find an appropriate display template by default in CMS-12.

There is a default display template for IContentData, but it is named simply "ContentData". A possible answer is to use the UIHint("ContentData")  attribute on these properties

public interface IPageViewModel
{
        [UIHint("ContentData")]
        IContentData Menu { get; set; }
}

I found I also needed to declare the same UIHint on the implementation of that interface for some use cases.

Is this a sane use of the hint? Should it be included somewhere in documentation?

#284818
Aug 02, 2022 14:22
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.