Different views for Normal and Experience Editor mode

After some time of using view renderings I began to notice that the code for markup in the view essentially has to be duplicated by dividing the layout for the visitors and the content editor by using of such constuction:

@if (Sitecore.Context.PageMode.IsExperienceEditor)
{
    // html code for content editors
}
else
{
    // html code which visitors see
}

I wanted to have two different views. First one for what the end user of the site will see (visitor), second one – view which is used by the content editor during its work process. And if in case of controller rendering I was happy with such kind of logic:

public ActionResult Index()
{
    var viewPath = Sitecore.Context.PageMode.IsExperienceEditor
        ? "~/Views/renderings/Report/Index-EE.cshtml"
        : "~/Views/renderings/Report/Index.cshtml";
    return View(viewPath);
}

then in case of using of view rendering resulting ‘crocodile’ made me depressed. And as result of discomfort I felt sprang approach which I want to share with you.

So.

Create template which contains single field – ‘Experience Editor View Path’, for easy of use I put that field in ‘Data’ section.

Template

Further extend the list of base templates of system ‘View rendering’ template with just created one.

Template 1

In this way now when you create view rendering except of good old ‘Path’ field you have new ‘Experience Editor View Path’ one in which you place path to view which used by content editors working in Experience Editor.

rendering

Next step – patch mvc.getRenderer pipeline:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <mvc.getRenderer>
        <processor patch:before="processor[@type='Sitecore.Mvc.Pipelines.Response.GetRenderer.GetViewRenderer, Sitecore.Mvc']" 				   type="IndependentView.Pipelines.GetRenderer.GetIndependentView, IndependentView" />
      </mvc.getRenderer>
    </pipelines>
  </sitecore>
</configuration>

And implement GetIndependentView class accordingly:

namespace IndependentView.Pipelines.GetRenderer
{
    using Sitecore.Mvc.Extensions;
    using Sitecore.Mvc.Names;
    using Sitecore.Mvc.Pipelines.Response.GetRenderer;
    using Sitecore.Mvc.Presentation;

    public class GetIndependentView : GetRendererProcessor
    {
        public override void Process(GetRendererArgs args)
        {
            if (args.Result != null
                || !args.Rendering.RenderingType.EqualsText("r")
                || args.Rendering.RenderingItem == null
                || args.Rendering.RenderingItem.InnerItem.TemplateID != TemplateIds.ViewRendering)
            {
                return;
            }

            var viewPath = Sitecore.Context.PageMode.IsExperienceEditor
                    ? args.Rendering.RenderingItem.InnerItem["experience editor view path"]
                    : args.Rendering.RenderingItem.InnerItem["path"];

            if (viewPath.IsWhiteSpaceOrNull())
            {
                return;
            }

            args.Result = new ViewRenderer
            {
                ViewPath = viewPath,
                Rendering = args.Rendering
            };
        }
    }
}

Voilà.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s