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?

3
  • 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, 2018 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, 2018 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, 2018 at 12:14

1 Answer 1

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.

3
  • 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!) Nov 17, 2018 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 Nov 18, 2018 at 12:50
  • Gladly, but I still miss 45 points to do so ;-) Nov 18, 2018 at 16:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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