Mechanic is a development and ecommerce automation platform for Shopify. :)
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.
Runs Occurs whenever a product is created, Occurs whenever a product is updated, ordered, or variants are added, removed or updated, Occurs when a user manually triggers the task, and Occurs when a bulk operation is completed. 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.
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.
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).
Run the task manually to update the tags for all active and draft products in your shop.
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?)
shopify/products/create shopify/products/update mechanic/user/trigger mechanic/shopify/bulk_operation
{% 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 use_only_the_single_smallest_range = options.use_only_the_single_smallest_range_that_applies_to_each_variant__boolean %} {% assign use_every_range = options.use_every_range_that_applies_to_each_variant__boolean %} {% 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 use_only_the_single_smallest_range and use_every_range %} {% error "Use only one of the 'Use only...' options. :)" %} {% elsif use_only_the_single_smallest_range == false and use_every_range == false %} {% error "Use exactly one of the 'Use only...' options. :)" %} {% endif %} {% if event.topic == "shopify/products/create" or event.topic == "shopify/products/update" %} {% comment %} -- query product and variant data, up to 2K variants {% endcomment %} {% assign products = array %} {% assign variants = array %} {% assign cursor = nil %} {% for n in (1..8) %} {% capture query %} query { product(id: {{ product.admin_graphql_api_id | json }}) { id variants( first: 250 after: {{ cursor | json }} ) { pageInfo { hasNextPage endCursor } nodes { price } } } } {% endcapture %} {% assign result = query | shopify %} {% if event.preview %} {% capture result_json %} { "data": { "product": { "id": "gid://shopify/Product/1234567890", "tags": {{ tag_prefix | append: "1-99999999999999999" | json }}, "variants": { "nodes": [ { "price": {{ range_min | plus: 0.01 | json }} }, { "price": {{ range_max | minus: 0.01 | json }} } ] } } } } {% endcapture %} {% assign result = result_json | parse_json %} {% endif %} {% comment %} -- only save the product ID and tags from the product object; a separate array is used to support 2K variants {% endcomment %} {% assign products[0] = result.data.product | except: "variants" %} {% assign variants = variants | concat: result.data.product.variants.nodes %} {% if result.data.product.variants.pageInfo.hasNextPage %} {% assign cursor = result.data.product.variants.pageInfo.endCursor %} {% else %} {% break %} {% endif %} {% endfor %} {% elsif event.topic == "mechanic/user/trigger" %} {% comment %} -- get all active and draft products in the shop, and all of their variant prices {% endcomment %} {% capture bulk_operation_query %} query { products( query: "-status:archived" ) { edges { node { __typename id tags variants { edges { node { __typename id price } } } } } } } {% endcapture %} {% action "shopify" %} mutation { bulkOperationRunQuery( query: {{ bulk_operation_query | json }} ) { bulkOperation { id status } userErrors { field message } } } {% endaction %} {% break %} {% elsif event.topic == "mechanic/shopify/bulk_operation" %} {% if event.preview %} {% capture jsonl_string %} {"__typename":"Product","id":"gid://shopify/Product/1234567890","tags":[{{ tag_prefix | append: "1-99999999999999999" | json }}]} {"__typename":"ProductVariant","id":"gid://shopify/ProductVariant/1234567890","price":{{ range_min | plus: 0.01 | json }},"__parentId":"gid://shopify/Product/1234567890"} {"__typename":"ProductVariant","id":"gid://shopify/ProductVariant/2345678901","price":{{ range_max | minus: 0.01 | json }},"__parentId":"gid://shopify/Product/1234567890"} {% endcapture %} {% assign bulkOperation = hash %} {% assign bulkOperation["objects"] = jsonl_string | parse_jsonl %} {% endif %} {% assign products = bulkOperation.objects | where: "__typename", "Product" %} {% assign bulk_variants = bulkOperation.objects | where: "__typename", "ProductVariant" %} {% endif %} {% comment %} -- using products array, either process the product which triggered the event, or all products from bulk op query {% endcomment %} {% for product in products %} {% if event.topic == "mechanic/shopify/bulk_operation" %} {% assign variants = bulk_variants | where: "__parentId", product.id %} {% endif %} {% 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 | push: tag %} {% endif %} {% endfor %} {% if use_only_the_single_smallest_range %} {% for variant in 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 | push: tag %} {% endunless %} {% endfor %} {% elsif use_every_range %} {% 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 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 | push: 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 | push: tag %} {% endunless %} {% endfor %} {% for tag in existing_price_range_tags %} {% unless applicable_price_range_tags contains tag %} {% assign tags_to_remove = tags_to_remove | push: tag %} {% endunless %} {% endfor %} {% if tags_to_add != blank or tags_to_remove != blank %} {% action "shopify" %} mutation { {% if tags_to_add != blank %} tagsAdd( id: {{ product.id | json }} tags: {{ tags_to_add | json }} ) { userErrors { field message } } {% endif %} {% if tags_to_remove != blank %} tagsRemove( id: {{ product.id | json }} tags: {{ tags_to_remove | json }} ) { userErrors { field message } } {% endif %} } {% endaction %} {% endif %} {% endfor %}
rprice-
200
0
25