This post is another rare case example and, as the usual disclaimer, 99% of the time you will never need to do this. The information in this article is a working that may be required in exceptional circumstances.
Situations like custom caching or rendering of content spring to mind. This should not be used for getting around routing issues, like form post back in blocks. In a recent project, I needed to create a custom cache layer in my architecture. This custom cache meant only rendering certain blocks within a content area at specific times.
In the majority of situations, the easy way to render a block is to use the PropertyFor HTML helper provided by Episerver. In my situation, I wanted to write out specific blocks based within an ActionFilterAttribute.
First you will have to decide how to get Episerver to render the block? In the attribute, or, a controller, for example, you do not have access to the HTM
Creating A HTMLHelper Instance From A Attribute
In the attribute situation, you're lucky to still have access to a lot of the page context, so life isn't too hard. If you inherit from ActionFilterAttribute, you will need to implement the OnActionExecuting and OnResultExecuted. Both these methods get passed the ActionExecutingContext, which is exactly the parameter you need to new-up a HTML-Helper.
Let's talk through what's going on to create a new HTMLHelper instance. We wrap the initialization in a StringWriter. When we come to render the Episerver content later, Episerver writes the output to a stream rather than return the HTML in a string. When we write the data out we will need a way to capture the HTML. We also use the filterContext passed in via the overload.
The HTMLHelper takes a ViewContext and a ViewPage, in this instance we need to create a new context. Using the ActionExecutingContext instance, we pass in the controller context, the view data and temp data. We pass in our new StringWriter and create a new WebFormView object. After this has been set-up we can create the object.
Rending The Block
Now we have created our own HTMLHelper in code, we can get on with rendering the content. In the code, I'm assuming you have got an IContent instance from IContentRepository.
In my code example, the way I got mine is very specific to my project and it's based on getting the content reference from a third-party source which won't be relevant to anyone else, so I'm skipping that code. The first part of getting this working is getting the correct template model for the content that we care about.
In order to do this, we use the Episerver TemplateResolver which we get from a ServiceLocator. Using the HTML Helper we created, we pass in the page context. We then pass the content data in. In my situation, I only care about blocks and not pages, so I use the MvcPartial template type.
If you get this bit wrong then the template resolver will return null, so be warned you may need to experiment to get the object returned. The last part is using the display tag, I've written about this before in How To Make A Block Use Multiple Views? A Partial View Controller Explained.
More information about how to get the tag can be found here in How To Get The Action, Controller and Tag Data Out Of The Context In Episerver
Now we have all the configuration set-up.. eventually! We can call the Episerver API. To do that we create an instance of IContentRenderer from IContentRenderer from Service Locator, we pass in the content, if the items are in a content area, the new template model we created and the content render. Getting The Block HTML Manually We now have the data.
If you remember the first step where we create a StringReader, our code should not look like this:
To get the HTML all you need to do is call the ToString() method on the StringWriter and, voila,you have it.
The way you create the HTML helper way vary, depending on where you are, say an attribute, a controller, or a standard bit of code. In a later guide, I'll cover how to render a page controller in normal code when you don't have access to the context.
The theory behind rendering the block content is quite simple. We create a new instance of HTMLHelper, create a stream writer, then call the Episerver extension to render the block passing in the correct template resolver.