0

I have a Sitecore site running: https://mysite.dev.local. The pages on this site have a JSS layout and JSON renderings on them. Navigation to a page (e.g. https://mysite.dev.local/foo/bar) would render via JSS (I assume). This is effectively what running in integrated mode is, yes?

If I have a node site running: https://locahost:3000, that has an scjssconfig targeting my Sitecore site, then that is connected mode?

Assuming those assumptions are correct, has anyone done a wildcard implementation via integrated mode?

We have wildcards working in connected mode by setting Sitecore.Context.Item in the mvc.requestBegin pipeline. However, setting the context item in this pipeline appears to be ignored by my pages when loaded in integrated mode; they are still resolving to the * item. I tried to add resolution in a couple of other places:

  1. httpRequestBegin - this one doesn't really appear to be doing anything different
  2. getLayoutServiceContext - this one doesn't appear to let you change the context item
  3. IItemResolver - implemented a custom item resolver for the LayoutServiceController. This is working for connected mode, but not integrated mode

  4. LayoutServiceController - implemented custom LayoutServiceController. This is working for connected mode, but not integrated mode.

For 3 and 4, I added log messages to my custom implementations. Those log messages show up when accessing the page via connected mode, but do not appear when accessing via integrated mode. This tells me that Sitecore is running through a different process for integrated mode.

How is Sitecore setting the Sitecore.Context.Item JSS page access via integrated mode?

| improve this question | | | | |
0

I ended up accomplishing this using a custom Contents Resolver and a Layout Extension:

Contents Resolver:

using Sitecore.Data.Items;
using Sitecore.LayoutService.Configuration;
using Sitecore.LayoutService.ItemRendering.ContentsResolvers;
using Sitecore.Mvc.Presentation;
using System.IO;
using System.Web;

namespace Website.Jss
{
    public class WildcardRenderingContentsResolver : RenderingContentsResolver
    {
        protected override Item GetContextItem(Rendering rendering, IRenderingConfiguration renderingConfig)
        { 
            var contextItem = Sitecore.Context.Item;

            if (contextItem.Name == "*")
            {
                Sitecore.Diagnostics.Log.Info($"Wildcard Contents Resolver - resolving wildcard contents for path {contextItem.Paths.Path}", this);

                var lastPart = Path.GetFileName(HttpContext.Current.Request.Path == "/sitecore/api/layout/render/jss"
                    ? HttpContext.Current.Request.QueryString["item"]
                    : HttpContext.Current.Request.Path);

                contextItem = WildcardUtility.FindItemByNameOrDisplayName(contextItem, lastPart);

                Sitecore.Diagnostics.Log.Info($"Wildcard Contents Resolver - new context item: {contextItem.Paths.Path}", this);
            }

            return contextItem;
        }
    }
}

The above resolver extends the base RenderingContentsResolver and overrides the GetContextItem to check for *. If we are on a wildcard item, then WildcardUtility.FindItemByNameOrDisplayName performs a Solr search for the id by name (based on the URL path) and retrieves the appropriate item from Sitecore.


I have some components that depend on knowing the context of the item for wildcard scenarios. To inform those components, I added a Layout Extension:

using Sitecore.JavaScriptServices.Configuration;
using Sitecore.JavaScriptServices.ViewEngine.LayoutService.Pipelines.GetLayoutServiceContext;
using Sitecore.LayoutService.ItemRendering.Pipelines.GetLayoutServiceContext;
using System.IO;
using System.Web;

namespace Website.Pipelines.JSS
{
    public class SetWildcardContextItem : JssGetLayoutServiceContextProcessor
    {
        public SetWildcardContextItem(IConfigurationResolver configurationResolver) 
            : base(configurationResolver)
        {
        }

        protected override void DoProcess(GetLayoutServiceContextArgs args, AppConfiguration application)
        {
            if (Sitecore.Context.Item.Name != "*")
            {
                return;
            }

            var lastPart = Path.GetFileName(HttpContext.Current.Request.Path == "/sitecore/api/layout/render/jss"
                ? HttpContext.Current.Request.QueryString["item"]
                : HttpContext.Current.Request.Path);

            var contextItem = WildcardUtility.FindItemByNameOrDisplayName(Sitecore.Context.Item, lastPart);

            if (contextItem != null)
            {
                args.ContextData.Add("wildcardContextItem", contextItem.ID);
            }
        }
    }
}

The extension also checks for a wildcard context item. If we are on a wildcard, then perform the same Solr search to get the id of the proper item, and add it to the context data that is returned to the JSS components.

The new context item can be accessed like this:

this.sitecoreContext.state.value.sitecore.context["wildcardContextItem"]

Where sitecoreContext is the injected JssContextService

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.