Search code examples
asp.net-mvcsitecoresitecore6sitecore-mvc

Sitecore MVC - dynamic view location


I have a site that requires "Theme" functionality. So, I created a bunch of views in the the "Themes" folder. for example:

/Themes/Theme 1/Views/Content.cshtml
/Themes/Theme 1/Views/Menu.cshtml
/Themes/Theme 2/Views/Content.cshtml
/Themes/Theme 2/Views/Menu.cshtml
/Themes/Theme 3/Views/Content.cshtml
/Themes/Theme 3/Views/Menu.cshtml

I also created Content and Menu view renderings and set the Path field to /Themes/Theme 1/Views/Content.cshtml and /Themes/Theme 1/Views/Menu.cshtml respectively.

What I need is to replace "Theme 1" with "Theme 2" somewhere in the sitecore pipeline, so that I can set the theme globally and dynamically load the views corresponding to that theme (instead of creating multiple "Menu" and "Content" view renderings).

Is there a way to do that?


Solution

  • So, this is what I did:

    Create a class to process the RenderRendering pipeline process:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Sitecore.Diagnostics;
    using Sitecore.Caching;
    using Sitecore.Mvc.Extensions;
    using Sitecore.Mvc.Presentation;
    using Sitecore.Sites;
    
    namespace MyNamespace.Pipelines.Response.RenderRendering
    {
        public class ReplacePathProcessor : Sitecore.Mvc.Pipelines.Response.RenderRendering.RenderRenderingProcessor
        {
            public override void Process(Sitecore.Mvc.Pipelines.Response.RenderRendering.RenderRenderingArgs args)
            {
                var viewRenderer = args.Rendering.Renderer as ViewRenderer;
                if (viewRenderer != null && viewRenderer.ViewPath.StartsWith("%Theme%"))
                {
                    // Get the current site
                    var site = Sitecore.Context.Site;
                    // Get the master database
                    var database = Sitecore.Data.Database.GetDatabase("master");
                    // Get the root item
                    var rootItem = database.GetItem(site.RootPath);
                    // replace the path
                    viewRenderer.ViewPath = viewRenderer.ViewPath.Replace("%Theme%", rootItem["Theme"]);
                }
            }
        }
    }
    

    Add a Configuration include

    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
      <sitecore>
        <pipelines>
          <mvc.renderRendering>
            <processor type="MyNamespace.Pipelines.Response.RenderRendering.ReplacePathProcessor, __Code">
              <patch:attribute name="type">MyNamespace.Pipelines.Response.RenderRendering.ReplacePathProcessor, __Code</patch:attribute>
            </processor>
          </mvc.renderRendering>
        </pipelines>
      </sitecore>
    </configuration>
    

    Change the MvcSettings.RenderersViewFolder to:

    <setting name="Mvc.RenderersViewFolder" value="/Themes" />

    Change the ViewPath field for all my views to use the format: %Theme%/Views/{ViewName}.cshtml

    Hope that helps someone.