Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering of blocks in Episerver MVC

I have a question I have been struggling a bit with the last days. I'm trying to understand how the rendering of blocks works in Episerver 7 when working with MVC.

My current setup that actually works is as follows:

I have created a Block Type called "TeaserBlock" which has a couple of properties:

[ContentType(DisplayName = "TeaserBlock", GUID = "571582c4-6b99-4c0a-b000-f62265e312a9", Description = "A Teaser Block for show!")]
public class TeaserBlock : BlockData
{
    [Display( GroupName = SystemTabNames.Content, Order = 1)]
    public virtual string TeaserHeading { get; set; }

    [Display(GroupName = SystemTabNames.Content, Order = 2)]
    public virtual string TeaserText { get; set; }    
}

To this I have a corresponding partial view in Views/Shared/ called TeaserBlock.cshtml. This one renders the block in view mode I guess?

My biggest problem was to get the "on page edit" to work and after some trying and googling I finally got it to work with the following code:

[TemplateDescriptor(Inherited = true,
    Tags = new string[] { RenderingTags.Preview },
    TemplateTypeCategory = TemplateTypeCategories.MvcController)]
public class PreviewBlockController : ActionControllerBase, IRenderTemplate<BlockData>
{
    public ActionResult Index(BlockData currentBlock)
    {
        return View(currentBlock);
    }
}

After I added a corresponding view to the PreviewBlockController it worked in "on page edit" which was good. It took me quite a while before I realized if the line "TemplateTypeCategory = TemplateTypeCategories.MvcController)" was not there it did not work. Anyone knows why this line is necessary?

Also is there some magic involved when using the Tag "RenderingTags.Preview" ?

Let's say that I have 5 different blocks in my application do I then need 5 different preview controllers and corresponding views to them as well?

What I would like is to have a more general "block preview controller" that could handle all "on page edit" for my blocks. I'm not sure if this is possible however because all Blocks will have different properties and therefore needs individual .cshtml for their preview if the preview will be any meaningful I guess. Or is there some way for me in code to find out what properties that is relevant in the block sent it to my controller so that I can loop over them for example? And with the help of this only need one preview controller and a corresponding view?

Is there any guidelines on how to deal with this in the best way?

Hope anyone can help me understand this concept a bit better, I find it hard to find information for some concepts regarding episerver.

like image 310
Kneta_ Avatar asked Feb 18 '13 10:02

Kneta_


People also ask

How do I render a block in EPiServer?

To render Episerver content you use the IContentRenderer API. To use IContentRenderer , you need to pass in the content, if the items are located within a content area, the template model and the content renderer object.

What is block EPiServer?

KB0010850. An Accordion Block allows you to add interactive content to your page as well as adding a lot of content in a smaller vertical space. The first item will of your list will display while the following items will be hidden with a "+" icon noting these items can be expanded.

What is content area in EPiServer?

Content areas are used to hold an ordered list of references to content (pages, blocks etc) within the same EPiServer site. A content area property is a property of type PropertyContentArea. Its value type is ContentArea. It's possible to render the contents in a content area in any way we like as developers.


1 Answers

TemplateTypeCategories equals different types of "render template types" supported.

public enum TemplateTypeCategories
{
    None = 0,
    WebFormsPage = 1,
    UserControl = 2,
    ServerControl = 4,
    WebFormsPartial = 6,
    WebForms = 7,
    MvcController = 8,
    Page = 9,
    MvcView = 16,
    MvcPartialController = 32,
    MvcPartialView = 64,
    MvcPartial = 96,
    Mvc = 120,
}

Having TemplateTypeCategories.MvcController set will trick EPiServer to load the Block as if it was a normal page, remember that block instances doesn't work exactly as page instances do so we must perform this little trick. Otherwise the block instances will be registered as MvcPartialController's, and that we can't load directly in MVC.

I create my PreviewBlockController's a bit more simple than the ones in AlloyMVC.

using EPiServer.Core;
using EPiServer.Framework.DataAnnotations;
using EPiServer.Framework.Web;
using EPiServer.Web;
using System.Web.Mvc;
using Site.Externwebb.Content.Blocks;

namespace Site.Externwebb.Controllers.Blocks
{
    [TemplateDescriptor(Inherited = true, 
        Tags = new[] { RenderingTags.Preview }, 
        TemplateTypeCategory = TemplateTypeCategories.MvcController)]
    public class PreviewBlockController : Controller, IRenderTemplate<BlockData>
    {
        public ActionResult Index(BlockData currentBlock)
        {
            var baseType = currentBlock.GetType().BaseType;
            if (baseType == typeof(BarkerBlock))
            {
                return View("Barkers", currentBlock);
            }

            if (baseType == typeof(SlideshowInlineBlock))
            {
                return View("Inline", currentBlock);
            }

            // Standard return (general block controller)
            return View("RightColumn", currentBlock);
        }
    }
}

The views are placed by default in ~/Views/PreviewBlock/xxx.cshtml Here is an example

@using EPiServer.Web.Mvc.Html
@model EPiServer.Core.BlockData

@{
    Layout = "~/Views/Shared/Masters/_BlockPreviewMaster.cshtml";
}

@section MainContent{
    <div id="rightContent" style="width:300px;">
        <div id="rightcolumn">
            @{ Html.RenderContentData(Model, false); }
        </div>
    </div>
}

Good enough and easy to administer.

Good luck.

/ Eric Herlitz

like image 118
Eric Herlitz Avatar answered Oct 12 '22 23:10

Eric Herlitz