Rendering of blocks in Episerver MVC
Asked Answered
Z

1

7

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.

Zebu answered 18/2, 2013 at 10:39 Comment(4)
@Kenta_ I'd suggest looking at Joel Abrahamsson's Alloy MVC Sample which can be downloaded from here. It looks like he's doing some of the same concepts you are mentioning with the preview controller. I wish I could be more help, but I'm also trying to wrap my head around this.Wanitawanneeickel
@Wanitawanneeickel Thanks for the input. Ye I've been looking on Joel's samples but some concepts still is still a bit tricky to understand thou for me. I find it hard to find information for some concepts.Zebu
@Kenta_ Can you post the code for your TeaserBlock view?Wanitawanneeickel
@Wanitawanneeickel Sure, it looks like this: ( Ignore the \ in \@ I had to add it here) \@using EPiServer.Core \@using EPiServer.Web.Mvc.Html \@model AlloyTestMVC.Models.Blocks.TeaserBlock <div class="border"> <div class="media"> <div class="mediaImg"> <img src="\@Model.TeaserImage" \@Html.EditAttributes(x => x.TeaserImage)/> </div> <div class="mediaText"> <h2 \@Html.EditAttributes(x => x.TeaserHeading)>\@Model.TeaserHeading</h2> <p \@Html.EditAttributes(x => x.TeaserText)>\@Model.TeaserText</p> </div> </div> </div>Zebu
P
3

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

Psyche answered 9/4, 2013 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.