How to render pages in a content area in EPiServer 7

This article was migrated from an older iteration of our website, and it could deviate in design and functionality.


This post shows how to create a page controller for partial views in order to render pages inside content areas in EPiServer 7.

Estimated read time : 5 minutes

Jump to

Blocks and pages inside content areas

Editors can drag and drop both blocks and pages in content areas in EPiServer 7. To render blocks you normally create a controller inheriting BlockController which returns a partial view.

In order to render pages inside a content area we have to do something similar by creating a PageController which returns a partial view.

Basic rendering of a page

Let’s say we have a page type called StandardPage like so:

[ContentType]
public class StandardPage : PageData
{
    public virtual string SomeText { get; set; }
}

In order to render StandardPage pages we would create a page controller like the following:

public class StandardPageController : PageController<StandardPage>
{
    public virtual ActionResult Index(T currentPage)
    {
        return View(currentPage);
    }
}

However, that controller will only kick in when we actually browse to StandardPage pages. We still wouldn’t have any rendering for StandardPage pages when they’re rendered inside a content area.

If we would create a new StandardPage page and then add it to a ContentArea we’d see a message saying There’s no renderer for ‘StandardPage’:

image

Create a controller for partial page views

Although we could make use of naming conventions and place a partial view called StandardPage in the /Views/Shared folder, I prefer having my own controller. That way I can pass my own view model when rendering the partial view, among other things.

To achieve this we create another controller which will handle partial rendering of StandardPage pages. It’s essentially identical to our original page controller, except it returns a PartialView. It has also been decorated with a TemplateDescriptor attribute saying this controller should be used for partial rendering of pages:

[TemplateDescriptor(TemplateTypeCategory = TemplateTypeCategories.MvcPartialController, Inherited = true)]
public class StandardPagePartialController : PageController<StandardPage>
{
    public ActionResult Index(StandardPage currentPage)
    {
        return PartialView("/Views/Pages/Partials/StandardPage.cshtml", currentPage);
    }
}

Note that I set Inherited = true for the TemplateDescriptor attribute to enable this controller to also handle partial page views for any other page type inheriting StandardPage.

Note: If you prefer you can inherit PartialContentController instead (although the behavior will be the same since we specify the view path explicitly):

[TemplateDescriptor(TemplateTypeCategory = TemplateTypeCategories.MvcPartialController, Inherited = true)]
public class StandardPagePartialController : PartialContentController<StandardPage>
{
    public ActionResult Index(StandardPage currentContent)
    {
        return PartialView("/Views/Pages/Partials/StandardPage.cshtml", currentContent);
    }
}

Creating the partial page view

Now it's time to create the partial view which will control how our pages are rendered inside content areas. We create a new partial view and place it in the folder specified in our controller earlier:

image

Next we set the model type to StandardPage and add some markup:

@model StandardPage

<div class="standard-page-partial">
    @Model.SomeText
</div>

Now whenever a StandardPage page (or any page inheriting StandardPage) is dropped in a content area it will be rendered by the partial view:

image