Jonas Bergqvist
Nov 5, 2012
  8454
(3 votes)

EPiServer MVC content rendering – Part 2

Some days ago I wrote the part 1 of rendering MVC content. I got a comment about the example content types, that they were strange implemented. I agree that it looks strange, how I use the block in the example, but it should be looked at as an “Hello World” example, and I just want to demonstrate how the rendering of a block works.

ControllerTypeControllerFactory

One thing I forgot in the last post was that we register an IControllerFactory in the CMS, to return controllers we have resolved with the “TemplateResolver” directly. You can find the logic in the “EPiServer.Web.Mvc.ControllerTypeControllerFactory.GetControllerType” with the reflector if you’re interested.

Render controller action

When the index action in the controller “BasicPageController” gets called, MVC will try to resolve the “BasicPage” type argument. This would not have worked out of the box without the “ContentDataModelBinder” (in the “EPiServer.Web.Mvc namespace”).

ContentDataModelBinder

The ContentDataModelBinder will look if the name of the parameter is “currentPage”, “currentBlock”, or “currentContent”. If it is one of them, it will try to get the current Page/Block/Content from the “DataTokens” in the “RouteData”.

In this case, we use the “currentPage” as parameter name, and the current page will be found in the “DataTokens” list. The current page will then simply be loaded from the content area, and the PageData will be returned from the “BindModel” method.

Edit hints

In the Index action, we start by creating an instance of the “BasicPageModel” and set it’s properties. Then we create an editing hits instance, by calling the extension method “GetEditHints<TModel, TContentType>”. We do this because the “MainBody” property in the content type has another name in the model (“Body”). By adding a connection between those, we make sure the on page edit will work as the editor expect.

Calling the view

When calling the default view (“Index"), with the view model, MVC will look for a folder with the same name as the controller name in the “RouteData” instance. In this case the folder name it looks for is “BasicPage”, and it will find a index view in that folder.

PropertyFor

The view contains three different “PropertyFor” calls, one for a string, one for a XhtmlString”, and one for a block.

The “PropertyFor” extension method are a wrapper of the MVC build in helper “DisplayFor”. Everything you normaly can do with “DisplayFor” are possible to do with “PropertyFor”. The difference are mainly that the “PropertyFor” will make the “on page edit” work.

Render string

MVC will look after a partial view handling “string”. By default, we have no partial view for this type, and we will therefor make an “ToString()” call for the property instead. This works for this type. behaviour can be overridden by adding a partial view with the name “String” in your MVC project that handles string”.

Render XhtmlString

MVC will look after a partial view handling “XhtmlString”. We have a default partial view with that name, that will call the extension method “RenderXhtmlString”. This behaviour can be overridden by adding a partial view with the name “XhtmlString” in your MVC project that handles “EPiServer.Core.XhtmlString”.

Render block

MVC will look after a partial view handling “BlockData”. We have a default partial view named “ContentData” that handles “ContentData”. This will be called becouse BlockData inherits from ContentData. This behaviour can be overridden by adding a partial view with the name “BlockData” or ContentData in your MVC project that handles BlockData/ContentData.

The "ContentData” view will call the html helper “RenderContentData”.

RenderContentData

By default, the html helper “RenderContentData” will be used when DisplayFor or PropertyFor are used for a property in a view.

The extension method will first use the “TemplateResolver” to figure out what template that should handle the content. Then it will call the “MvcContentRenderer” class (EPiServer.Web.Mvc namespace), which will use the template to render the content.

MvcContentRenderer

The render method in the “MvcContentRenderer” will first look if the template the “TemplateResolver” returned are a partial view. If it is a partial view, it means that it doesn't use any controller, and the view should be called directly.

In case the tamplate is a partial view, the “ViewEngine” will be used to call it. This is the fast way of rendering content. If it’s not a partial view, we will call the html helper method “RenderAction” instead, which will look for the controller, resolved by the “TemplateResolver”. When calling the “RenderAction”, we will add the content (in this case the block) to the “RouteValueCollection” with key “currentContent”.

BlockController

Just as for the page controller, the block controller have the block type as a parameter. The parameter are named “currentBlock” in this example, but it could also have hade the name “currentContent”. The same model binder as the one resolved the PageData object will now resolve the BlockData object in almost the same way.

This time, the model binder will not find any node to use, instead it will find a value for the key “currentContent”, and the binder will return the content (in this case the block) to the parameter.

Partial view

The block controller will look for a partial view in the same way as it does for a view. The block view in this example just outputs the Heading and the Body, just as the page, and that is done exactly in the same way as for the page.

Nov 05, 2012

Comments

Please login to comment.
Latest blogs
Opti ID overview

Opti ID allows you to log in once and switch between Optimizely products using Okta, Entra ID, or a local account. You can also manage all your use...

K Khan | Jul 26, 2024

Getting Started with Optimizely SaaS using Next.js Starter App - Extend a component - Part 3

This is the final part of our Optimizely SaaS CMS proof-of-concept (POC) blog series. In this post, we'll dive into extending a component within th...

Raghavendra Murthy | Jul 23, 2024 | Syndicated blog

Optimizely Graph – Faceting with Geta Categories

Overview As Optimizely Graph (and Content Cloud SaaS) makes its global debut, it is known that there are going to be some bugs and quirks. One of t...

Eric Markson | Jul 22, 2024 | Syndicated blog

Integration Bynder (DAM) with Optimizely

Bynder is a comprehensive digital asset management (DAM) platform that enables businesses to efficiently manage, store, organize, and share their...

Sanjay Kumar | Jul 22, 2024

Frontend Hosting for SaaS CMS Solutions

Introduction Now that CMS SaaS Core has gone into general availability, it is a good time to start discussing where to host the head. SaaS Core is...

Minesh Shah (Netcel) | Jul 20, 2024

Optimizely London Dev Meetup 11th July 2024

On 11th July 2024 in London Niteco and Netcel along with Optimizely ran the London Developer meetup. There was an great agenda of talks that we put...

Scott Reed | Jul 19, 2024