Rendering page in content area



I am creating a site where several page types will have a content area where the editors can add related pages. Each page type is a subclass to a base page type where some data for the related pages view are stored such as an image, header, some text and a link. In the editor view I would like to see all related pages in the content area. The problem I have is that if I render the content area with Html.PropertyFor(page => page.RelatedPagesContentArea) it only works for the pages that has a template at Views/Shared/PageType.cshtml and otherwise displays There's no renderer for 'PageType'. If I add the same template for every pagetype it would work as I want it but I would prefer to be able to add a single template for my base page type instead, is this possible or could it be solved in a different way?



Apr 18, 2016 12:01


It's possible. Check out the TemplateCoordinator in the Alloy project:

            viewTemplateModelRegistrator.Add(typeof(SitePageData), new TemplateModel
                Name = "PagePartial",
                Inherit = true,
                AvailableWithoutTag = true,
                Path = PagePartialPath("Page.cshtml")
Apr 18, 2016 12:43

Hi Marcus,

Take a look at this page:

You can create a new page controller and decorate it with TemplateDescriptor attribute. In TemplateDescriptor, you can specify your own tags that you want to be used with Html.PropertyFor helper.

Apr 18, 2016 12:43

That would also work :-)

Apr 18, 2016 12:45

Alright, I have added the following class:

	[TemplateDescriptor(Inherited = true, Tags = new[] { "test" })]
	public class PageDataBaseTemplate : ContentControlBase<PageDataBase>

And I now render the contentarea containing the pages with:

@Html.PropertyFor(m => m.CurrentPage.PageReferences, new { Tag = "test"})

Problem is it still doesn't show. It says for example that it doesn't have a renderer for "NewsPage" which is a pagetype that inherits from "PageDataBase". I've tried putting the .cshtml file on different locations as I am not sure of where it should be but no luck yet!

Edited, Apr 18, 2016 13:18

Got any index method?

 public ActionResult Index(IContent currentContent) that you can set the name of the view and the correct viewmodel as well.

Then add a view .csheml with the correct name and model to shared views. You probably want a generic viewmodel.

Check out the PreviewController in alloy project for some example

        Inherited = true,
        TemplateTypeCategory = TemplateTypeCategories.MvcController, //Required as controllers for blocks are registered as MvcPartialController by default
        Tags = new[] { RenderingTags.Preview, RenderingTags.Edit },
        AvailableWithoutTag = false)]
    public class PreviewController : ActionControllerBase, IRenderTemplate<BlockData>


  public ActionResult Index(IContent currentContent)
            //As the layout requires a page for title etc we "borrow" the start page
            var startPage = _contentLoader.Get<StartPage>(SiteDefinition.Current.StartPage);

            var model = new PreviewModel(startPage, currentContent);


            return View(model);


You don't need the tags for preview and edit mode though

Edited, Apr 18, 2016 14:27

First you should go for Pers solution since using controllers is not always a good approach when it comes to performance in partial views. With that said you need to put your view in a location that MVC is looking for.

In some cases the cshtml file would be in the /views/shared/displaytemplates folder. You also need to return a view as Daniel mentioned above and in that you can go for returning a view in a specific path if you like.

What is your names of the cshtml file?

Since it is for newspages your are trying to solve a partial view you could be a bit more specific and say in the controller it is for NewsPage and not for all pages inheriting from <PageDataBase>.

Apr 18, 2016 15:39

I agree, Per's solution with IViewTemplateModelRegistrator will perform better, and you don't have to create additional controllers.
But performance wise, nothing beats ContentOutputCache on top of each page controller :)

Apr 18, 2016 16:44

Yup, if you can do without controller that is the best solution :) agree. 
Depends if you need to assemble more information to your viewmodel in controller. For just printing some fields from current page a view is enough...

Edited, Apr 18, 2016 16:45
* 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.