Build Query relatedTo multiple categories Trying to build a complex query and I'm sure there is bound to be a better way of doing it that the multiple if statements I currently have.
URL for the page is /products/(category1)/(category2)/(category3)

if any of the categorys in the url is selected it will display that slug other wise it will be all e.g.
/products/inks/glass/all
/products/all/glass/catname

I have been doing this:

{# get categories #}
  {% set catTypeSlug = craft.request.getSegment(2) %}
  {% if catTypeSlug != 'all' %}
  {% set catType = craft.categories.slug(catTypeSlug).first() %}
  {% endif %}

  {% set catSurfaceSlug = craft.request.getSegment(3) %}
  {% if catSurfaceSlug != 'all' %}
  {% set catSurface = craft.categories.slug(catSurfaceSlug).first() %}
  {% endif %}

  {% set catUseSlug = craft.request.getSegment(4) %}
  {% if catUseSlug != 'all' %}
  {% set catUse = craft.categories.slug(catUseSlug).first() %}
  {% endif %}


  {# set parameters #}
  {% if catType is defined and catSurface is defined and catUse is defined %}
    {% set params = { section: 'productsServices', relatedTo: catType, relatedTo: catSurface, relatedTo: catUse } %}

  {% else %}  
    {# multiple if statements checking if categories defined #}

  {% endif %}  


What's the best way to build my parameters instead of multiple if statements?
Untested, but something like this should work:

{# set base criteria #}
{% set params = {
    section: 'productsServices',
    limit: null
} %}

{# set relationship criteria #}
{% set relationParam = ['and'] %}
{% for segment in craft.request.segments %}
    {% if loop.index != 1 and segment != 'all' %}
        {% set category = craft.categories.slug(segment).first() %}
        {% set relationParam = relationParam|merge([{ targetElement:category }]) %}
    {% endif %}
{% endfor %}

{# check to ensure that at least one relationship is defined and merge criteria #}
{% if relationParam|length &gt; 1 %}
    {% set params = params|merge({relatedTo: relationParam}) %}
{% endif %}

{# retrieve entries #}
{% set entries = craft.entries(params) %}
{% for entry in entries %}
    {{ entry.title }}
    ...
{% endfor %}


Update Added a check to ensure that not all segments are set to 'all'; Fixed 'length' syntax.

Give credit to carlcs and his ElementCriteriaModel Fu in this answer.