Manage collection templates by product inventory, with Mechanic.

Mechanic is a development and ecommerce automation platform for Shopify. :)

Manage collection templates by product inventory

Use this task to automatically switch collections over to an appropriate theme template, when every product in the collection has gone completely out of stock, and to switch them back when inventory arrives.

Runs Occurs whenever an inventory level is updated, Occurs when a user manually triggers the task, and Occurs when a bulk operation is completed. Configuration includes collection template suffix when all products are out of stock, default collection template suffix, run every time an inventory level is updated, run daily, and run hourly.

15-day free trial – unlimited tasks

Documentation

Use this task to automatically switch collections over to an appropriate theme template, when every product in the collection has gone completely out of stock, and to switch them back when inventory arrives.

This task can be run manually (using the "Run task" button), or be configured to run daily/hourly. If you encounter performance issues when running every time an inventory level is updated, disable this option.

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Shopifolks, everybody.

That’s why we make it easy to configure automation without code, why we make it easy to tweak the underlying code once tasks are installed, and why we publish it all here for everyone to learn from.

(By the way, have you seen our documentation? Have you joined the Slack community?)

Open source
View on GitHub to contribute to this task
Subscriptions
{% if options.run_every_time_an_inventory_level_is_updated__boolean %}shopify/inventory_levels/update{% endif %}
mechanic/user/trigger
{% if options.run_daily__boolean %}mechanic/scheduler/daily{% endif %}
{% if options.run_hourly__boolean %}mechanic/scheduler/hourly{% endif %}
mechanic/shopify/bulk_operation
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
collection template suffix when all products are out of stock (required), default collection template suffix, run every time an inventory level is updated (boolean), run daily (boolean), run hourly (boolean)
Code
{% if event.topic contains "shopify/inventory_levels/" %}
  {% assign collections = inventory_level.variant.product.collections %}

  {% if event.preview %}
    {% capture collections_json %}
      [
        {
          "admin_graphql_api_id": "gid://shopify/Collection/1234567890",
          "template_suffix": null,
          "products": [
            {
              "variants": [
                {
                  "inventory_quantity": 0
                }
              ]
            }
          ]
        }
      ]
    {% endcapture %}

    {% assign collections = collections_json | parse_json %}
  {% endif %}

  {% for collection in collections %}
    {% assign current_template_suffix = collection.template_suffix %}

    {% comment %}
      Shopify stores this as *either* an empty string or as nil. Mechanic auto-nils
      empty strings for task options, so we coerce blanks to nils here.
    {% endcomment %}
    {% if current_template_suffix == blank %}
      {% assign current_template_suffix = nil %}
    {% endif %}

    {% assign total_inventory = 0 %}

    {% assign set_template_suffix = false %}
    {% assign new_template_suffix = nil %}

    {% for product in collection.products %}
      {% assign product_total_inventory = product.variants | map: "inventory_quantity" | sum %}
      {% assign total_inventory = total_inventory | plus: product_total_inventory %}
    {% endfor %}

    {% if total_inventory <= 0 %}
      {% if current_template_suffix != options.collection_template_suffix_when_all_products_are_out_of_stock__required %}
        {% assign set_template_suffix = true %}
        {% assign new_template_suffix = options.collection_template_suffix_when_all_products_are_out_of_stock__required %}
      {% endif %}
    {% else %}
      {% if current_template_suffix != options.default_collection_template_suffix %}
        {% assign set_template_suffix = true %}
        {% assign new_template_suffix = options.default_collection_template_suffix %}
      {% endif %}
    {% endif %}

    {
      "log": {
        "collection_id": {{ collection.admin_graphql_api_id | json }},
        "total_inventory": {{ total_inventory | json }},
        "current_template_suffix": {{ current_template_suffix | json }},
        "set_template_suffix": {{ set_template_suffix | json }},
        "new_template_suffix": {{ new_template_suffix | json }}
      }
    }

    {% if set_template_suffix %}
      {% action "shopify" %}
        mutation {
          collectionUpdate(
            input: {
              id: {{ collection.admin_graphql_api_id | json }}
              templateSuffix: {{ new_template_suffix | json }}
            }
          ) {
            userErrors {
              field
              message
            }
          }
        }
      {% endaction %}
    {% endif %}
  {% endfor %}
{% elsif event.topic == "mechanic/shopify/bulk_operation" %}
  {% if event.preview %}
    {% assign collection_object = '{"__typename":"Collection","id":"gid://shopify/Collection/1234567890","templateSuffix":null}' | parse_json %}
    {% assign product_object = '{"__typename":"Product","id":"gid://shopify/Product/1234567890","__parentId":"gid://shopify/Collection/1234567890","totalInventory":0}' | parse_json %}

    {% assign objects = array %}
    {% assign objects[0] = collection_object %}
    {% assign objects[1] = product_object %}

    {% assign bulkOperation = hash %}
    {% assign bulkOperation["objects"] = objects %}
  {% endif %}

  {% assign collection_suffixes = hash %}
  {% assign collection_total_inventory = hash %}

  {% for object in bulkOperation.objects %}
    {% case object.__typename %}
    {% when "Collection" %}
      {% assign collection_suffixes[object.id] = object.templateSuffix %}
    {% when "Product" %}
      {% assign collection_total_inventory[object.__parentId] = collection_total_inventory[object.__parentId] | default: 0 | plus: object.totalInventory %}
    {% endcase %}
  {% endfor %}

  {% for keyval in collection_total_inventory %}
    {% assign collection_id = keyval[0] %}
    {% assign total_inventory = keyval[1] %}
    {% assign current_template_suffix = collection_suffixes[collection_id] %}

    {% comment %}
      Shopify stores this as *either* an empty string or as nil. Mechanic auto-nils
      empty strings for task options, so we coerce blanks to nils here.
    {% endcomment %}
    {% if current_template_suffix == blank %}
      {% assign current_template_suffix = nil %}
    {% endif %}

    {% assign set_template_suffix = false %}
    {% assign new_template_suffix = nil %}

    {% if total_inventory <= 0 %}
      {% if current_template_suffix != options.collection_template_suffix_when_all_products_are_out_of_stock__required %}
        {% assign set_template_suffix = true %}
        {% assign new_template_suffix = options.collection_template_suffix_when_all_products_are_out_of_stock__required %}
      {% endif %}
    {% else %}
      {% if current_template_suffix != options.default_collection_template_suffix %}
        {% assign set_template_suffix = true %}
        {% assign new_template_suffix = options.default_collection_template_suffix %}
      {% endif %}
    {% endif %}

    {
      "log": {
        "collection_id": {{ collection_id | json }},
        "total_inventory": {{ total_inventory | json }},
        "current_template_suffix": {{ current_template_suffix | json }},
        "set_template_suffix": {{ set_template_suffix | json }},
        "new_template_suffix": {{ new_template_suffix | json }}
      }
    }

    {% if set_template_suffix %}
      {% action "shopify" %}
        mutation {
          collectionUpdate(
            input: {
              id: {{ collection_id | json }}
              templateSuffix: {{ new_template_suffix | json }}
            }
          ) {
            userErrors {
              field
              message
            }
          }
        }
      {% endaction %}
    {% endif %}
  {% endfor %}
{% else %}
  {% capture bulk_operation_query %}
    query {
      collections {
        edges {
          node {
            __typename
            id
            templateSuffix
            products {
              edges {
                node {
                  __typename
                  id
                  totalInventory
                }
              }
            }
          }
        }
      }
    }
  {% endcapture %}

  {% action "shopify" %}
    mutation {
      bulkOperationRunQuery(
        query: {{ bulk_operation_query | json }}
      ) {
        bulkOperation {
          id
          status
        }
        userErrors {
          field
          message
        }
      }
    }
  {% endaction %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Collection template suffix when all products are out of stock
out-of-stock
Run every time an inventory level is updated
true