-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new task: set product types by title keywords
- Loading branch information
Showing
4 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Set product types by title keywords | ||
|
||
Tags: Products | ||
|
||
Use this task to quickly reset product types in bulk based on product titles. When run manually, it will query for all products in the shop and for each product with a matched keyword in the title, the task will assign the paired product type to it. | ||
|
||
* View in the task library: [tasks.mechanic.dev/set-product-types-by-title-keywords](https://tasks.mechanic.dev/set-product-types-by-title-keywords) | ||
* Task JSON, for direct import: [task.json](../../tasks/set-product-types-by-title-keywords.json) | ||
* Preview task code: [script.liquid](./script.liquid) | ||
|
||
## Default options | ||
|
||
```json | ||
{ | ||
"product_types_and_keywords__keyval_multiline_required": { | ||
"Shirts": "shirt\nt-shirt\ntee" | ||
} | ||
} | ||
``` | ||
|
||
[Learn about task options in Mechanic](https://learn.mechanic.dev/core/tasks/options) | ||
|
||
## Subscriptions | ||
|
||
```liquid | ||
mechanic/user/trigger | ||
``` | ||
|
||
[Learn about event subscriptions in Mechanic](https://learn.mechanic.dev/core/tasks/subscriptions) | ||
|
||
## Documentation | ||
|
||
Use this task to quickly reset product types in bulk based on product titles. When run manually, it will query for all products in the shop and for each product with a matched keyword in the title, the task will assign the paired product type to it. | ||
|
||
Configure the product types to set on the left, and the keyword(s) on the right. The task is pre-filled with a sample entry for "Shirts", which can be replaced if not needed. | ||
|
||
**Notes:** | ||
- The task will search for keywords in the order of entry in the task configuration, and it will stop once a match is made. | ||
- If a product title does not contain any of the configured keywords, then that product will be ignored. | ||
|
||
## Installing this task | ||
|
||
Find this task [in the library at tasks.mechanic.dev](https://tasks.mechanic.dev/set-product-types-by-title-keywords), and use the "Try this task" button. Or, import [this task's JSON export](../../tasks/set-product-types-by-title-keywords.json) – see [Importing and exporting tasks](https://learn.mechanic.dev/core/tasks/import-and-export) to learn how imports work. | ||
|
||
## Contributions | ||
|
||
Found a bug? Got an improvement to add? Start here: [../../CONTRIBUTING.md](../../CONTRIBUTING.md). | ||
|
||
## Task requests | ||
|
||
Submit your [task requests](https://mechanic.canny.io/task-requests) for consideration by the Mechanic community, and they may be chosen for development and inclusion in the [task library](https://tasks.mechanic.dev/)! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
{% assign product_types_and_keywords = options.product_types_and_keywords__keyval_multiline_required %} | ||
|
||
{% comment %} | ||
-- set preview values for the configuration field that will work with the preview query data | ||
{% endcomment %} | ||
|
||
{% if event.preview %} | ||
{% capture product_types_and_keywords_json %} | ||
{ | ||
"Shoes": "shoe\nshoes" | ||
} | ||
{% endcapture %} | ||
|
||
{% assign product_types_and_keywords = product_types_and_keywords_json | parse_json %} | ||
{% endif %} | ||
|
||
{% assign cursor = nil %} | ||
|
||
{% comment %} | ||
-- query for all products in the shop (if > 25K products, the "100" loop value can be adjusted upward) | ||
{% endcomment %} | ||
|
||
{% for n in (1..100) %} | ||
{% capture query %} | ||
query { | ||
products( | ||
first: 250 | ||
after: {{ cursor | json }} | ||
) { | ||
pageInfo { | ||
hasNextPage | ||
endCursor | ||
} | ||
nodes { | ||
id | ||
title | ||
productType | ||
} | ||
} | ||
} | ||
{% endcapture %} | ||
|
||
{% assign result = query | shopify %} | ||
|
||
{% if event.preview %} | ||
{% capture result_json %} | ||
{ | ||
"data": { | ||
"products": { | ||
"nodes": [ | ||
{ | ||
"id": "gid://shopify/Product/1234567890", | ||
"title": "Alpha Shoe", | ||
"productType": "Shirts" | ||
} | ||
] | ||
} | ||
} | ||
} | ||
{% endcapture %} | ||
|
||
{% assign result = result_json | parse_json %} | ||
{% endif %} | ||
|
||
{% comment %} | ||
-- process each product in this result before querying for more products | ||
{% endcomment %} | ||
|
||
{% for product in result.data.products.nodes %} | ||
{% comment %} | ||
-- use downcase on product title and configured keywords since the "contains" operator is case-sensitive | ||
{% endcomment %} | ||
|
||
{% assign product_title_downcase = product.title | downcase %} | ||
{% assign product_type_to_set = nil %} | ||
|
||
{% for keyval in product_types_and_keywords %} | ||
{% assign product_type = keyval.first %} | ||
{% assign keywords = keyval.last | split: newline %} | ||
|
||
{% for keyword in keywords %} | ||
{% if keyword == blank or keyword == "" %} | ||
{% comment %} | ||
-- protect against accidental empty keyword lines in the task config | ||
{% endcomment %} | ||
|
||
{% continue %} | ||
{% endif %} | ||
|
||
{% assign keyword_downcase = keyword | downcase %} | ||
|
||
{% if product_title_downcase contains keyword_downcase %} | ||
{% assign product_type_to_set = product_type %} | ||
{% break %} | ||
{% endif %} | ||
{% endfor %} | ||
|
||
{% if product_type_to_set != blank %} | ||
{% break %} | ||
{% endif %} | ||
{% endfor %} | ||
|
||
{% comment %} | ||
-- set a new product type if a keyword match was made and the product does not already have that type | ||
{% endcomment %} | ||
|
||
{% if product_type_to_set != blank and product_type_to_set != product.productType %} | ||
{% action "shopify" %} | ||
mutation { | ||
productUpdate( | ||
input: { | ||
id: {{ product.id | json }} | ||
productType: {{ product_type_to_set | json }} | ||
} | ||
) { | ||
product { | ||
title | ||
productType | ||
} | ||
userErrors { | ||
field | ||
message | ||
} | ||
} | ||
} | ||
{% endaction %} | ||
{% endif %} | ||
{% endfor %} | ||
|
||
{% if result.data.products.pageInfo.hasNextPage %} | ||
{% assign cursor = result.data.products.pageInfo.endCursor %} | ||
{% else %} | ||
{% break %} | ||
{% endif %} | ||
{% endfor %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"docs": "Use this task to quickly reset product types in bulk based on product titles. When run manually, it will query for all products in the shop and for each product with a matched keyword in the title, the task will assign the paired product type to it.\n\nConfigure the product types to set on the left, and the keyword(s) on the right. The task is pre-filled with a sample entry for \"Shirts\", which can be replaced if not needed.\n\n**Notes:**\n- The task will search for keywords in the order of entry in the task configuration, and it will stop once a match is made.\n- If a product title does not contain any of the configured keywords, then that product will be ignored.", | ||
"halt_action_run_sequence_on_error": false, | ||
"name": "Set product types by title keywords", | ||
"online_store_javascript": null, | ||
"options": { | ||
"product_types_and_keywords__keyval_multiline_required": { | ||
"Shirts": "shirt\nt-shirt\ntee" | ||
} | ||
}, | ||
"order_status_javascript": null, | ||
"perform_action_runs_in_sequence": false, | ||
"preview_event_definitions": [], | ||
"script": "{% assign product_types_and_keywords = options.product_types_and_keywords__keyval_multiline_required %}\n\n{% comment %}\n -- set preview values for the configuration field that will work with the preview query data\n{% endcomment %}\n\n{% if event.preview %}\n {% capture product_types_and_keywords_json %}\n {\n \"Shoes\": \"shoe\\nshoes\"\n }\n {% endcapture %}\n\n {% assign product_types_and_keywords = product_types_and_keywords_json | parse_json %}\n{% endif %}\n\n{% assign cursor = nil %}\n\n{% comment %}\n -- query for all products in the shop (if > 25K products, the \"100\" loop value can be adjusted upward)\n{% endcomment %}\n\n{% for n in (1..100) %}\n {% capture query %}\n query {\n products(\n first: 250\n after: {{ cursor | json }}\n ) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n id\n title\n productType\n }\n }\n }\n {% endcapture %}\n\n {% assign result = query | shopify %}\n\n {% if event.preview %}\n {% capture result_json %}\n {\n \"data\": {\n \"products\": {\n \"nodes\": [\n {\n \"id\": \"gid://shopify/Product/1234567890\",\n \"title\": \"Alpha Shoe\",\n \"productType\": \"Shirts\"\n }\n ]\n }\n }\n }\n {% endcapture %}\n\n {% assign result = result_json | parse_json %}\n {% endif %}\n\n {% comment %}\n -- process each product in this result before querying for more products\n {% endcomment %}\n\n {% for product in result.data.products.nodes %}\n {% comment %}\n -- use downcase on product title and configured keywords since the \"contains\" operator is case-sensitive\n {% endcomment %}\n\n {% assign product_title_downcase = product.title | downcase %}\n {% assign product_type_to_set = nil %}\n\n {% for keyval in product_types_and_keywords %}\n {% assign product_type = keyval.first %}\n {% assign keywords = keyval.last | split: newline %}\n\n {% for keyword in keywords %}\n {% if keyword == blank or keyword == \"\" %}\n {% comment %}\n -- protect against accidental empty keyword lines in the task config\n {% endcomment %}\n\n {% continue %}\n {% endif %}\n\n {% assign keyword_downcase = keyword | downcase %}\n\n {% if product_title_downcase contains keyword_downcase %}\n {% assign product_type_to_set = product_type %}\n {% break %}\n {% endif %}\n {% endfor %}\n\n {% if product_type_to_set != blank %}\n {% break %}\n {% endif %} \n {% endfor %}\n\n {% comment %}\n -- set a new product type if a keyword match was made and the product does not already have that type\n {% endcomment %}\n\n {% if product_type_to_set != blank and product_type_to_set != product.productType %}\n {% action \"shopify\" %}\n mutation {\n productUpdate(\n input: {\n id: {{ product.id | json }}\n productType: {{ product_type_to_set | json }}\n }\n ) {\n product {\n title\n productType\n }\n userErrors {\n field\n message\n }\n }\n }\n {% endaction %} \n {% endif %} \n {% endfor %}\n\n {% if result.data.products.pageInfo.hasNextPage %}\n {% assign cursor = result.data.products.pageInfo.endCursor %}\n {% else %}\n {% break %}\n {% endif %}\n{% endfor %}", | ||
"subscriptions": ["mechanic/user/trigger"], | ||
"subscriptions_template": "mechanic/user/trigger", | ||
"tags": ["Products"] | ||
} |