Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Kevin 35 posts 159 karma points
    Oct 20, 2016 @ 07:58
    Kevin
    0

    Get ProductOption ContentType Umbraco data from Variant

    Further to my previous thread

    Get ProductOption ContentType Umbraco data in code

    is it possible to extract virtual content type data of a shared product option from the product variant? The previous thread gets this data from the option itself, but if I do this I have to map the data to the variant myself which seems unnecessary.

    So:

    var merchello = new MerchelloHelper();
    var productQuery = merchello.Query.Product;
    var product = productQuery.TypedProductContent(productKey);
    foreach (var pvc in product.ProductVariants)
    {
        // TODO: get shared option virtual content data here
        // try pvc.OptionContentTypes - is there a neater way?
    }
    

    Thanks

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Oct 20, 2016 @ 15:03
    Rusty Swayne
    0

    Hey Kevin,

    Missing something here - you can extend variants with a content type as well (which was the original implementation).

    Can you describe your use case so I can get a better idea of what is missing.

  • Kevin 35 posts 159 karma points
    Oct 20, 2016 @ 15:32
    Kevin
    0

    Hi Rusty,

    here goes:

    As an example, let's say I am selling t-shirts and on a product details page I want to display a series of images, the image for each colour (i.e. each variant).

    In Umbraco I have created a Content Type "MyColourContentType" that has an image picker "MyColour" and in Merchello selected this content type to be the "Product Option Content Type".

    I have then defined a "Shared Product Option" for the colour of an item and created three choices for "Red", "Green" and "Blue". And because it uses "MyColourContentType" I assign an image of the correctly coloured t-shirt to each choice.

    Now, on my product details page, I have access to the product key. In my SurfaceController I would like to be able to access the media id (to get the image url) of the choice that lead to the creation of the variant.

    Is there a simple way to do this?

    I have managed it by looping through product variants, then looping through variant attributes to get the Attribute.OptionKey. Then getting the product options then choices and comparing the attribute key with the choice key. But I am thinking there is an easier way?

    Hope that makes sense.

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Oct 20, 2016 @ 15:58
    Rusty Swayne
    0

    Ok - we do something similar in one of our builds but we use the ProductAttributeKey (the Guid pk for the product option choice).

    If you look at a product variant, it has a collection of "Attributes". These are the Product option choices that are used to define the variant.

    e.g.

    Options

    Size -> Sm, Md, Lg

    Color -> White, Black (each with extended content media picker)

    Variants would be created for

    • Sm - White
    • Md - White
    • Lg - White
    • Sm - Black
    • Md - Black
    • Lg - Black

    So when a customer changes the option, you can do a quick AJAX call to look up the variant by the combination of product option choices selected at the time using the productKey & optionChoices[] as parameters.

    Then find the variant in the product with a collection of attributes that have the matching keys.

      var variant = product.ProductVariants.FirstOrDefault(
                    x =>
                    x.Attributes.Count() == optionChoices.Count() // should always be true
                    && optionChoices.All(key => x.Attributes.FirstOrDefault(att => att.Key == key) != null));
    
  • Kevin 35 posts 159 karma points
    Oct 20, 2016 @ 16:05
    Kevin
    0

    Thanks Rusty,

    that makes sense but isn't exactly what I'm trying to do - I'm trying to do it the other way around.

    In your example above you know the options as they are presumably rendered on the page.

    In my case, all I have is the product key (so I can load the product and access the variants).

    So from the product key, I want to be able to access the colour image (from the extended content media picker) of each available choice.

    I can paste my code so you can see what I am doing so far?

    Thanks again

  • Kevin 35 posts 159 karma points
    Oct 20, 2016 @ 16:20
    Kevin
    101

    This is how I currently do it (simplified), by looping through various things. I just wondered if there was a much much simpler way that I am overlooking?

    public static IList<string> GetChoiceImageUrls(IProductContent product)
    {
        var mediaUrls = new List<string>();
    
        // foreach variation, find the colour option
        // and thus determine the product sku, option sku and option image/extended content data
    
        // get the option for colours
        var colourOption = product.Options.FirstOrDefault(x => x.Name.Equals("MyColourOption"));
    
        // find the option-choice-combo that is used by the variation
        foreach (var pvc in product.ProductVariants)
        {
            foreach (var a in pvc.Attributes)
            {
                if (a.OptionKey == colourOption.Key)
                {
                    // the current attribute is for the colourOption
    
                    // get the option choice
                    var productOptionChoice = colourOption?.Choices.FirstOrDefault(x => x.Key == a.Key);
    
                    // get extended content data of the colour option for the product variation
                    var mediaId = productOptionChoice.GetPropertyValue("MyColourField");
                    var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
                    var image = umbracoHelper.Media(mediaId); // mediaId =  the (int)ID of the media
                    var imageUrl = image.url; // imageUrl now has the site root relative path of the media item
    
                    // add to list
                    mediaUrls.Add(imageUrl);
    
                    break;
                }
            }
        }
    
        return mediaUrls;
    }
    
  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Oct 21, 2016 @ 16:31
    Rusty Swayne
    0

    I see now.

    Your solution is probably the best at this point - it's difficult to create a direct API for this as we can never know what properties will be added to the choice content.

    The only thing I might do is move the umbracoHelper instantiation outside of the loop (higher up in the scope) so that it does not have to be called over and over - but it really won't make any difference.

      var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
    
Please Sign in or register to post replies

Write your reply to:

Draft