Tag products by their price ranges, with Mechanic.

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

Tag products by their price ranges

Some themes (like Mogo!) support browsing products by price range. Under the hood, this functionality is powered by tags that look like "rprice-1-100". This task watches for new and updated products, making sure that the product range tags stay in sync with prices available for each product. And, if you run the task manually, it'll update the tags for all products in your shop.

Runs Occurs when a user manually triggers the task, Occurs whenever a product is created, and Occurs whenever a product is updated, or whenever a product is ordered, or whenever a variant is added, removed, or updated. Configuration includes tag prefix, range maximum, range minimum, range increment, use only the single smallest range that applies to each variant, and use every range that applies to each variant.

15-day free trial – unlimited tasks

Documentation

Some themes (like Mogo!) support browsing products by price range. Under the hood, this functionality is powered by tags that look like "rprice-1-100". This task watches for new and updated products, making sure that the product range tags stay in sync with prices available for each product. And, if you run the task manually, it'll update the tags for all products in your shop.

This task adds tags that specify the price ranges that describe the product. Then, choose between tagging with every applicable price range (e.g. a product with price $50 might be tagged for the ranges 0-50, 0-75, 0-100, 25-50, 25-75, 25-100, 50-75, and 50-100), or between tagging with only the smallest applicable price ranges (e.g. only 50-75).

Out of the box, this task will run on product create and update. You can also use the "Run Task" button to request a run across all products in your shop.

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
mechanic/user/trigger
shopify/products/create
shopify/products/update
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
tag prefix (required), range maximum (required, number), range minimum (required, number), range increment (required, number), use only the single smallest range that applies to each variant (boolean), use every range that applies to each variant (boolean)
Code
{% assign tag_prefix = options.tag_prefix__required %}

{% assign range_max = options.range_maximum__required_number | round %}
{% assign range_min = options.range_minimum__required_number | round %}
{% assign range_increment = options.range_increment__required_number | round %}
{% assign range_steps = range_max | minus: range_min | divided_by: range_increment %}

{% if range_max <= range_min %}
  {% error "'Range maximum' is smaller than or equal to 'Range minimum'. Try again!" %}
{% endif %}

{% assign range_max_mod = range_max | minus: range_min | modulo: range_increment %}

{% if range_max_mod != 0 %}
  {% error %}
    "Ensure both 'Range maximum' is an even multiple of {{ range_increment }} away from 'Range minimum'."
  {% enderror %}
{% endif %}

{% if options.use_only_the_single_smallest_range_that_applies_to_each_variant__boolean and options.use_every_range_that_applies_to_each_variant__boolean %}
  {% error "Use only one of the 'Use only...' options. :)" %}
{% elsif options.use_only_the_single_smallest_range_that_applies_to_each_variant__boolean == false and options.use_every_range_that_applies_to_each_variant__boolean == false %}
  {% error "Use exactly one of the 'Use only...' options. :)" %}
{% endif %}

{% assign products = array %}

{% if event.preview %}
  {% assign products[0] = hash %}
  {% assign products[0]["admin_graphql_api_id"] = "gid://shopify/Product/1234567890" %}

  {% assign tags = array %}
  {% assign tags[tags.size] = "red" %}
  {% assign tags[tags.size] = "blue" %}
  {% assign tags[tags.size] = tag_prefix | append: "1-99999999999999999" %}

  {% assign products[0]["tags"] = tags | join: ", " %}
  {% assign products[0]["variants"] = array %}
  {% assign products[0]["variants"][0] = hash %}
  {% assign products[0]["variants"][0]["price"] = options.range_minimum__required_number | plus: 0.01 %}
  {% assign products[0]["variants"][1] = hash %}
  {% assign products[0]["variants"][1]["price"] = options.range_maximum__required_number | minus: 0.01 %}
{% elsif event.topic == "mechanic/user/trigger" %}
  {% assign products = shop.products %}
{% elsif event.topic == "shopify/products/create" or event.topic == "shopify/products/update" %}
  {% assign products[0] = product %}
{% endif %}

{% for product in products %}
  {% assign product_tags = product.tags | split: ", " %}
  {% assign existing_price_range_tags = array %}
  {% assign applicable_price_range_tags = array %}

  {% for tag in product_tags %}
    {% assign possible_prefix = tag | slice: 0, tag_prefix.size %}
    {% if possible_prefix == tag_prefix %}
      {% assign existing_price_range_tags[existing_price_range_tags.size] = tag %}
    {% endif %}
  {% endfor %}

  {% if options.use_only_the_single_smallest_range_that_applies_to_each_variant__boolean %}
    {% for variant in product.variants %}
      {% assign variant_price = variant.price | times: 1 %}
      {% assign variant_price_left = variant_price | divided_by: range_increment | floor | times: range_increment %}
      {% assign variant_price_right = variant_price_left | plus: range_increment %}
      {% capture tag %}{{ tag_prefix }}{{ variant_price_left }}-{{ variant_price_right }}{% endcapture %}
      {% unless applicable_price_range_tags contains tag %}
        {% assign applicable_price_range_tags[applicable_price_range_tags.size] = tag %}
      {% endunless %}
    {% endfor %}
  {% elsif options.use_every_range_that_applies_to_each_variant__boolean %}
    {% for i in (0..range_steps) %}
      {% for j in (i..range_steps) %}
        {% if j <= i %}
          {% continue %}
        {% endif %}

        {% assign step_min = i | times: range_increment | plus: range_min %}
        {% assign step_max = j | times: range_increment | plus: range_min %}

        {% for variant in product.variants %}
          {% assign variant_price = variant.price | times: 1 %}
          {% if variant_price >= step_min and variant_price <= step_max %}
            {% capture tag %}{{ tag_prefix }}{{ step_min }}-{{ step_max }}{% endcapture %}
            {% unless applicable_price_range_tags contains tag %}
              {% assign applicable_price_range_tags[applicable_price_range_tags.size] = tag %}
            {% endunless %}
          {% endif %}
        {% endfor %}
      {% endfor %}
    {% endfor %}
  {% endif %}

  {% assign tags_to_add = array %}
  {% assign tags_to_remove = array %}

  {% for tag in applicable_price_range_tags %}
    {% unless existing_price_range_tags contains tag %}
      {% assign tags_to_add[tags_to_add.size] = tag %}
    {% endunless %}
  {% endfor %}

  {% for tag in existing_price_range_tags %}
    {% unless applicable_price_range_tags contains tag %}
      {% assign tags_to_remove[tags_to_remove.size] = tag %}
    {% endunless %}
  {% endfor %}

  {% if tags_to_add != empty or tags_to_remove != empty %}
    {% action "shopify" %}
      mutation {

        {% if tags_to_add != empty %}
          tagsAdd(
            id: {{ product.admin_graphql_api_id | json }}
            tags: {{ tags_to_add | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        {% endif %}

        {% if tags_to_remove != empty %}
          tagsRemove(
            id: {{ product.admin_graphql_api_id | json }}
            tags: {{ tags_to_remove | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        {% endif %}

      }
    {% endaction %}
  {% endif %}
{% endfor %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Tag prefix
rprice-
Range maximum
200
Range minimum
0
Range increment
25