Rendering page in content area

Vote:
 

Hello!

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?

Best,

Marcus

#147536
Apr 18, 2016 12:01
Vote:
 

Hi,

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")
            });
#147539
Apr 18, 2016 12:43
Vote:
 

Hi Marcus,

Take a look at this page: http://world.episerver.com/documentation/Items/Developers-Guide/Episerver-CMS/9/Rendering/Rendering/

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.

#147540
Apr 18, 2016 12:43
Vote:
 

That would also work :-)

#147541
Apr 18, 2016 12:45
Vote:
 

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!

#147544
Edited, Apr 18, 2016 13:18
Vote:
 

Got any index method?

 public ActionResult Index(IContent currentContent)

...in 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

  [TemplateDescriptor(
        Inherited = true,
        TemplateTypeCategory = TemplateTypeCategories.MvcController, //Required as controllers for blocks are registered as MvcPartialController by default
        Tags = new[] { RenderingTags.Preview, RenderingTags.Edit },
        AvailableWithoutTag = false)]
    [VisitorGroupImpersonation]
    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

#147551
Edited, Apr 18, 2016 14:27
Vote:
 

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>.

#147557
Apr 18, 2016 15:39
Vote:
 

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 :)

#147561
Apr 18, 2016 16:44
Vote:
 

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...

#147562
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.