On this product list page: https://www.alfa.no/shop/skisko/ I need to add a size filter, to only show products that are size 45 for example AND that are in stock.

The structure is built with products and productVariants in separate channels, and productVariants (individual shoe sizes) are added to the product inside a matrix field (colorVariants), with sizes as related productVariants entries to each color. All those words look a little something like this: https://www.dropbox.com/s/2kyvfxq7xv843v6/Screenshot_2014-10-23_09_53_00.png?dl=0

So what I need in the template is to search for products that have a related productVariant in the colorVariants matrix, matching 45 in the variantSize field AND > 0 in the variantStock field.

I have only come as far as being able to list products that match the size in the matrix, with a way too simple search. It searches for the size in the colorVariants matrix field, but the approach is not targeting specific fields, like stock, in the related productVariants entries in the colorVariants matrix:

{% set filteredProductList = productList.search('colorVariants:45') %}


Yes, you're right to better not use the search parameter for such things.

Instead get all the product variants that match your criteria first (e.g. size, color) and then query for all related products. Be careful with the field parameter, as your relation is between a Matrix field and your product variant entries.

Code is not tested (as you might guess, hehe):

{% set category = craft.categories.slug('skisko').first() %}

{% set sizeParam = craft.request.getParam('size') %}
{% set colorParam = craft.request.getParam('color') %}

 # Get product variants matching our search

{% set variantParams = {
    section: 'productVariants',
    variantStock: '> 0',
    variantSize: sizeParam,
    variantColor: colorParam,
} %}

{% set variants = craft.entries(variantParams) %}

 # Get the products related to these variants

{% set productParams = {
    section: 'products',    
    relatedTo: [
            targetElement: variants,
            field: 'colorVariants.myRelationField',
            targetElement: category,
            field: 'myCategoryRelationField',
} %}

{% set products = craft.entries(productParams) %}
  • Thanks for the input! This would work great for a general search, but looking in all variants (thousands) and get products based on that, will leave us with all products that have size 43 in stock for example, not just the categories being listed on the current page. So we would have to add in a relation to the correct product category as well. Anyway for this case I changed approach: Since we already have a product entry selection based on the current category/categories being listed, I rather check for the size/stock inside the for loop while listing them out. Thanks :) – oyvind-redrabbits Oct 27 '14 at 11:32
  • Hey @oyvind, totally missed the part about this listing already being filtered. But why don't you simply add this relatedTo parameter to the "productParams" ElementCriteriaModel as well? I will update the answer to show you how to do that in a sec! ;) – carlcs Oct 27 '14 at 11:51
  • Lol, now here's many guesses about your fieldnames and relations in my code, feel free to edit them. I'd actually always prefer this approach and not use conditionals in a loop, @oyvind. It allows you to use pagination, easily get the total (using length filter) etc.! Can't say which one performs better, but I guess you use caching anyways. – carlcs Oct 27 '14 at 12:11
  • Thanks! I totally agree with you standpoint on avoiding filters in the actual loops. I'll update the code to match this approach when I have time in a few weeks :) Working on another launch now. – oyvind-redrabbits Oct 28 '14 at 12:12

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.