IViewTemplateModelRegistrator for viewModels

Nat
Nat
Vote:
 

I am trying to implement some extra templates for some pages/blocks using the IViewTemplateModelRegistrator.

This works fine when I am dealing with the Page or Block type itself, but if i use a ViewModel it does not pick the view.

does this only work when the type used is a Block or Page?

public void Register(TemplateModelCollection viewTemplateModelRegistrator)
{
	viewTemplateModelRegistrator.Add(
		typeof(MyPageViewModel),
		new EPiServer.DataAbstraction.TemplateModel()
		{
			Name = "ListView",
			Description = "Displays page for a listing.",
			Path = "~/Views/MyPage/Listing.cshtml",
			Tags = new string[] { "Listing" }
		});
[ContentType(GUID = "12345678-4321-ABCD-DCBA-1234567890AB", GroupName = PropertyGroupNames.Content)]
[ContentImageUrl]
public class ListingPage : BasePage
{
	...
	[Display(GroupName = PropertyGroupNames.Content)]
	[AllowedTypes(typeof(MyPage))]
	public virtual ContentArea Pages { get; set; }
	...
public class ListingPageController : BasePageController<ListingPage>
{
        public ActionResult Index(ListingPage currentPage)
        {
               var pages = LoadPages(.... ; // load the MyPages
               var vms = new List<MyPage>();
               foreach (var page in pages)
               {
                    vms.Add(new MyPageViewModel (page) { TeaserImagePath = Imageservice.GetImagePath(page.Image) });
               }
               var listingViewModel = new ListingPageViewModel(currentPage) 
               {
                    List = vms
               };
               return View(listingViewModel);
         }
... }
              

@model ListingPageViewModel

@Html.PropertyFor(x => x.List, new { Tag = "Listing" })

nothing gets rendered for the above PropertyFor, do I need to Create a (2nd) controller for the MyPage type and load the image in that instead?

#257254
Edited, Jun 28, 2021 13:58
Vote:
 

Are you sure you are registering view template on the right type (e.g. typeof(MyPageViewModel))?

#257439
Jul 01, 2021 17:08
Vote:
 

Hi Nat,

You can simply use ASP.NET MVC conventions to render that view model list (as it is of type List<MyPageViewModel> or IList<MyPageViewModel> in your view model of type ListingPageViewModel).

So to have only a custom display template for the type MyPageViewModel, create a new view file under '~/Views/Shared/DisplayTemplates/MyPageViewModel.cshtml' and use the type MyPageViewModel as that views model, so something like this:

@model Your.Namespace.ToThe.MyPageViewModel
@* print out the models properties the way you need *@
<h3>@Model.Page.Name</h3>
<img src="@Model.TeaserImagePath" alt="Page teaser image" />

Then in your "calling" view you would simply write:

@Html.DisplayFor(m => m.List)

And framework will automatically then call for each item in the list that display template just created for the "MyPageViewModel".

If for example you want to create a HTML list of the objects (MyPageViewModel) you could create a display template for the list. Create a new view '~/Vies/Shared/DisplayTempates/ListOfMyPageViewModel.cshtml' (the part in the view file name is your template name => ListOfMyPageViewModel is the template name in this case, you can name it in anyway you like as you will be passing the template name in the code so there is no automagic convention based template name resolving in this case)

The view file content for ListOfMyPageViewModel.cshtml:

@model IList<Namespace.ToYOur.Type.Here.MyPageViewModel>

@if (Model != null && Model.Count > 0)
{
<ul>
    @foreach (var pageItem in Model)
    {
        @* naturally you have your own stuff here ;-) *@
        <li><img src="@pageItem.TeaserImagePath" alt="@pageItem.Page.Name" /></li>
    }
</ul>
}

And then you would call it like this from your page cshtml:

@Html.DisplayFor(m => m.List, "ListOfMyPageViewModel")

Hope this helps.

#258614
Edited, Jul 08, 2021 8:34
* 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.