4

I'm using a custom item resolver to take a call to a wildcard item and use the URL to grab an item in a catalog of products (not Commerce). I've got the parser set up, but I've hit a conundrum.

The items in the catalog of products don't have presentation details, they are data only. The wildcard item has the presentation details I want to use. The problem is that once I set the Context.Item to the product item, it takes on all properties, including the lack of layout. I've tried taking the shared/final layout from the wildcard and programmatically assigning it to the product item, but it saves that to the actual item, which is not desired. (The products are used on multiple sites and might have different layouts/renderings per site.)

Is there any way to "disassociate" the product item after retrieval, so I could assign the layout from the wildcard without saving it to the actual item? Or is the better method to retrieve the data at the rendering level, parsing the URL to get the info needed to find the datasource, and then assigning the datasource dynamically?

  • 1
    If you just want the data from the product item to inform the various components rendered on the wildcard item, could you save a serializable object of the item in the Context.Session and have your components look for datasource, if null check session, if null, use Context.Item? – Pete Navarra Nov 17 '18 at 0:57
  • This repo lets you separate the layout from the item. It lets you move the page layout to a single item and then share it across many pages. github.com/BenGGolden/Sitecore.BaseLayouts – Chris Auer Nov 17 '18 at 5:10
  • 1
    Another trick I’ve used is leverage the Context.Items array. Set your wild card as context but store your product item in Context.Items[“resolvedProduct”]. Then on your renderings just reference the product item. – jrap Nov 17 '18 at 12:14
10

Don't overwrite the Sitecore.Context item with the one you are fetching for the wildcard. Keep the wildcard item as the context item.

Instead, put the product item in a sort of wildcard context. You Helix architecture, you can put this in a foundation project.

 public static Item WildcardContextItem
    {
        get => (Item)HttpContext.Current.Items[ContextKey];
        set => HttpContext.Current.Items[ContextKey] = value;
    }

You could set the WildcardContextItem in a processor.

public class WildcardInitializer : HttpRequestProcessor
{
    public override void Process(HttpRequestArgs args)
    {
        if (Sitecore.Context.Item != null && IsWildcardItem())
        {
            var product = GetProduct();
            if (product != null)
            {
                WildcardContext.WildcardContextItem= product ;
            }
        }
    }
}

Then, the individual components can check if there is a wildcarditem in context to take precedence over the context item.

    public ActionResult Detail()
    {
        var product = WildcardContextItem??Sitecore.Context.Item;
        return View(product);
    }

Note that this is a bit of pseudo-code to explain the concept.

  • This is a similar concept to what jrap suggested above. Seems like this, or Session, is the best way to tackle this, and then we're only building out the product model once and passing it around. (Extra plus, there's no experience editor interface required here!) – Ken McAndrew Nov 17 '18 at 22:47
  • Good. Now can someone fix the question title and text up a bit, so the question actually matches this answer? :o) How would anyone on Google ever find it otherwise – Mark Cassidy Nov 18 '18 at 12:50
  • Gladly, but I still miss 45 points to do so ;-) – Bart Verdonck Nov 18 '18 at 16:04

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.