Inhalte aufrufen

Profilbild

Variant URL Format (Question about changing/design decision)


  • Bitte melden Sie sich an, um eine Antwort zu verfassen.
9 Antworten zu diesem Thema

#1 altmoola

altmoola

    Advanced Member

  • Members
  • 66 Beiträge

Geschrieben: 21 April 2021 - 19:21

Hello,

 

I use the variants (combinations) quite a lot on my website and I've been wondering about the variant URL format and why it was chosen as such.

 

Here is an example of the current query parameters built for a variant:

?pvari2161-0-62-469=2562&pvari2161-0-61-470=2564

If we take a look at something like Shopify, they use a simple ?variantId=1234567890. I went looking into the code to implement something like this. I found that SmartStore actual currently supports this style of query parameter with something like this:

?pvari=5348

Which is parsed at ProductVariantQueryFactory.CreateFromQuery:

else if (item.Key.IsCaseInsensitiveEqual("pvari") && 
         int.TryParse(item.Value.FirstOrDefault()?.NullEmpty() ?? "0", out var variantCombinationId) &&
         variantCombinationId != 0)
{
    query.VariantCombinationId = variantCombinationId;
}

So my questions are:

  1. Why was the current query parameter format chosen over the more simple pvari=####?
  2. Were there some design implications for this decision?
  3. If I wanted to change it so that SmartStore used ?pvari=#### by default, can you advise the points in the code that I would need to consider if I were to make this change? Could I simply modify ProductVariantQueryItem.CreateKey to accept a variant combination ID and just return pvari=####?

Thank you for your time.



#2 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3638 Beiträge

Geschrieben: 21 April 2021 - 20:56

The first format selects a certain attribute value, the second a certain attribute combination. Attribute combinations do not necessarily have to exist, hence two formats. The second format is only an addition.
3. No. The keys are also used for the control names in HTML forms. Please see ProductUrlHelper.ToQueryString. It's the place where the URL query string is built.

Schöne Grüße aus Düsseldorf,
Marcus Gesing


#3 altmoola

altmoola

    Advanced Member

  • Members
  • 66 Beiträge

Geschrieben: 22 April 2021 - 00:35

Thanks Marcus for the reply. I see that there is a VariantCombinationId on the ProductVariantQuery. I can make the ToQueryString use this if it is specified to override the query string formatting, however there are a lot of locations that would need to be changed so that it can be supplied this ID. It seems like if I could make the DeserializeQuery supply that value it would solve this for me, but I'm not seeing an easy quick way of getting that value populated. Unfortunately the AttributesXml does not have this combination ID.

 

Snipped from ToQueryString 

if (query.VariantCombinationId != 0)
{
    qs.Add("pvari", query.VariantCombinationId.ToString());
}
else
{
    // Variants
    foreach (var item in query.Variants)
    {
        if (item.Alias.IsEmpty())
        {
            item.Alias = _catalogSearchQueryAliasMapper.Value.GetVariantAliasById(item.AttributeId, _languageId);
        }


        if (item.Date.HasValue)
        {
            qs.Add(item.ToString(), string.Join("-", item.Date.Value.Year, item.Date.Value.Month, item.Date.Value.Day));
        }
        else if (item.IsFile || item.IsText)
        {
            qs.Add(item.ToString(), item.Value);
        }
        else
        {
            if (item.ValueAlias.IsEmpty())
            {
                item.ValueAlias = _catalogSearchQueryAliasMapper.Value.GetVariantOptionAliasById(item.Value.ToInt(), _languageId);
            }


            var value = item.ValueAlias.HasValue()
                ? $"{item.ValueAlias}-{item.Value}"
                : item.Value;


            qs.Add(item.ToString(), value);
        }
    }
}

Any suggestions to make all calls to this method formal the URL this way?



#4 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3638 Beiträge

Geschrieben: 22 April 2021 - 11:16

That sounds like a lot of code to change. Wherever ProductVariantQuery is instantiated, VariantCombinationId would have to be obtained and transferred. Maybe adding a VariantCombinationId parameter to ProductUrlHelper.GetProductUrl and GetAbsoluteProductUrl would be the right way to start. 

Schöne Grüße aus Düsseldorf,
Marcus Gesing


#5 altmoola

altmoola

    Advanced Member

  • Members
  • 66 Beiträge

Geschrieben: 22 April 2021 - 18:46

Is there a quick query using ProductId and AttributesXml to lookup to a ProductVariantAttributeCombinationId?



#6 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3638 Beiträge

Geschrieben: 22 April 2021 - 19:28

ProductAttributeParser.FindProductVariantAttributeCombination but in most situations where you have AttributesXml, you also have a ProductVariantAttributeCombination record (because that's where AttributesXml comes from) and therefore also the ProductVariantAttributeCombination.Id.

Schöne Grüße aus Düsseldorf,
Marcus Gesing


#7 altmoola

altmoola

    Advanced Member

  • Members
  • 66 Beiträge

Geschrieben: 22 April 2021 - 19:42

In that case I believe, in addition to the above code, all I need to do is add this line:

query.VariantCombinationId = (_productAttributeParser.FindProductVariantAttributeCombination(productId, attributesXml)?.Id).GetValueOrDefault();

Into the DeserializeQuery method since this method will need to be called before it will be able to call ToQueryString and therefore format the URL.

 

Please correct me if I am wrong.



#8 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3638 Beiträge

Geschrieben: 23 April 2021 - 10:56

No, I would not change DeserializeQuery. I would pass the ID to GetProductUrl and then pass it to ProductVariantQuery and only load it if unknown.


Schöne Grüße aus Düsseldorf,
Marcus Gesing


#9 altmoola

altmoola

    Advanced Member

  • Members
  • 66 Beiträge

Geschrieben: 23 April 2021 - 15:24

Interesting, I must be overlooking something. If I go the path you suggest I will have to change approximately 30+ locations of code considering how many calls there are to the ProductUrlHelperExtensions methods as well. Also taking a quick look at these calling methods, it seems like the ProductVariantAttributeCombination is not readily available.



#10 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3638 Beiträge

Geschrieben: 23 April 2021 - 17:37

Yes, you are right. DeserializeQuery seems to be a better way to do it centrally. It should actually work like that.


Schöne Grüße aus Düsseldorf,
Marcus Gesing