# Touchmark: one-step data setup. Definitions version 1. # Creates the 9 metaobject definitions and 22 metafield definitions Touchmark reads, and turns on # Shopify's standard Product subtitle field. Creates no entries and changes no products. # Run it in Shopify's GraphiQL app with the access scopes write_metaobject_definitions, write_products and # write_online_store_pages. Safe to run again: a definition that already exists returns an error and is # left as it is. Instructions: https://touchmark.zopy.xyz/data#one-step-setup mutation TouchmarkDataSetup { # 1. Metaobject definitions. Rows and results come before the entries that list them. supplementFactRow: metaobjectDefinitionCreate(definition: { type: "supplement_fact_row" name: "Supplement fact row" description: "One row of a Supplement Facts label." displayNameKey: "nutrient" access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "nutrient", name: "Nutrient", type: "single_line_text_field", required: true } { key: "form", name: "Form or source", type: "single_line_text_field", description: "Printed in parentheses after the nutrient, for example: as magnesium bisglycinate chelate." } { key: "amount", name: "Amount", type: "single_line_text_field", required: true, description: "As printed, for example 200 or 2,500." } { key: "unit", name: "Unit", type: "single_line_text_field", description: "For example mg, mcg or g." } { key: "daily_value", name: "% Daily Value", type: "number_decimal", validations: [{ name: "min", value: "0" }], description: "Blank means no Daily Value established." } { key: "daily_value_mark", name: "Daily Value mark", type: "single_line_text_field", validations: [{ name: "choices", value: "[\"dagger\", \"asterisk\", \"none\"]" }], description: "Blank or dagger: † (no Daily Value established). asterisk: * (2,000 calorie diet). none: no mark and no Daily Value cell, as for Calories." } { key: "indent", name: "Indent", type: "boolean", description: "Nested under the row above (Dietary Fiber under Total Carbohydrate)." } { key: "key_active", name: "Key active", type: "boolean", description: "Shown among the product's key actives." } { key: "note", name: "Note", type: "single_line_text_field", description: "A short line under the row in the % Daily Value plot. End it with * to link to the compliance statement." } { key: "above_upper_limit", name: "Above the adult upper limit", type: "boolean", description: "The amount is above the tolerable upper intake level for adults." } ] }) { metaobjectDefinition { type } userErrors { field message code } } supplementFacts: metaobjectDefinitionCreate(definition: { type: "supplement_facts" name: "Supplement facts" description: "One Supplement Facts label, for a product or for a variant whose label differs." access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "serving_size", name: "Serving size", type: "single_line_text_field", description: "As printed on the label, for example 2 capsules or 1 scoop (10 g)." } { key: "servings_per_container", name: "Servings per container", type: "single_line_text_field", description: "As printed, for example 30." } { key: "rows", name: "Rows", type: "list.metaobject_reference", validations: [{ name: "metaobject_definition_type", value: "supplement_fact_row" }], description: "The label's rows, in label order." } { key: "other_ingredients", name: "Other ingredients", type: "multi_line_text_field" } { key: "allergens", name: "Allergen statement", type: "single_line_text_field" } { key: "label_version", name: "Label version", type: "single_line_text_field" } { key: "label_updated", name: "Label updated", type: "date" } { key: "label_pdf", name: "Label PDF", type: "file_reference", description: "A PDF of the printed label." } { key: "footnote", name: "Footnote", type: "multi_line_text_field", description: "Extra notes under the label. The theme writes the two standard Daily Value notes itself." } ] }) { metaobjectDefinition { type } userErrors { field message code } } ingredient: metaobjectDefinitionCreate(definition: { type: "ingredient" name: "Ingredient" description: "Why an ingredient is in a formula. One entry per product and ingredient." displayNameKey: "name" access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "name", name: "Name", type: "single_line_text_field" } { key: "form", name: "Form", type: "single_line_text_field" } { key: "source", name: "Source", type: "single_line_text_field" } { key: "origin", name: "Origin", type: "single_line_text_field" } { key: "dose", name: "Dose", type: "single_line_text_field" } { key: "why", name: "Why this form and dose", type: "multi_line_text_field" } { key: "image", name: "Image", type: "file_reference", validations: [{ name: "file_type_options", value: "[\"Image\"]" }], description: "Set the alt text on the file in Content > Files; the theme uses it as the caption." } ] }) { metaobjectDefinition { type } userErrors { field message code } } protocol: metaobjectDefinitionCreate(definition: { type: "protocol" name: "Protocol" description: "How to take a formula." access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "when", name: "When", type: "single_line_text_field" } { key: "amount", name: "Amount", type: "single_line_text_field" } { key: "take_with", name: "Take with", type: "single_line_text_field" } { key: "pairs_with", name: "Pairs with", type: "single_line_text_field" } { key: "dose_times", name: "Dose times", type: "list.single_line_text_field", validations: [{ name: "regex", value: "^([01][0-9]|2[0-3]):[0-5][0-9]$" }], description: "24-hour times for the dose clock, for example 21:00." } { key: "steps", name: "Steps", type: "list.single_line_text_field" } { key: "caution", name: "Caution", type: "multi_line_text_field" } ] }) { metaobjectDefinition { type } userErrors { field message code } } timelineStep: metaobjectDefinitionCreate(definition: { type: "timeline_step" name: "Timeline step" description: "One step of what to expect over time." displayNameKey: "label" access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "label", name: "Label", type: "single_line_text_field", description: "For example Week 2-4." } { key: "text", name: "Text", type: "multi_line_text_field" } ] }) { metaobjectDefinition { type } userErrors { field message code } } labResult: metaobjectDefinitionCreate(definition: { type: "lab_result" name: "Lab result" description: "One test result on a certificate of analysis." displayNameKey: "test" access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "group", name: "Group", type: "single_line_text_field", description: "The certificate's section, for example Potency, per 2 capsules." } { key: "test", name: "Test", type: "single_line_text_field" } { key: "specification", name: "Specification", type: "single_line_text_field" } { key: "result", name: "Result", type: "single_line_text_field" } { key: "status", name: "Status", type: "single_line_text_field", validations: [{ name: "choices", value: "[\"Pass\", \"Fail\"]" }] } ] }) { metaobjectDefinition { type } userErrors { field message code } } labBatch: metaobjectDefinitionCreate(definition: { type: "lab_batch" name: "Lab batch" description: "One tested batch and its certificate of analysis. Use the batch code as the entry handle." displayNameKey: "batch_code" access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "batch_code", name: "Batch code", type: "single_line_text_field", required: true, description: "As printed on the package, for example MG-24118. Also use it as the entry handle." } { key: "product", name: "Product", type: "product_reference", description: "The product this batch is of. Search and the batch lookup open the certificate on its page." } { key: "lab", name: "Laboratory", type: "single_line_text_field" } { key: "tested_on", name: "Tested on", type: "date" } { key: "best_before", name: "Best before", type: "date" } { key: "status", name: "Status", type: "single_line_text_field", validations: [{ name: "choices", value: "[\"Released\", \"Passed\"]" }] } { key: "certificate", name: "Certificate (PDF)", type: "file_reference", description: "The certificate of analysis, as a PDF." } { key: "method", name: "Method", type: "multi_line_text_field" } { key: "headline_results", name: "Headline results", type: "list.single_line_text_field", validations: [{ name: "list.max", value: "3" }], description: "Optional. Up to three results as printed, each written Test: result, for example Heavy metals: Pass." } { key: "results", name: "Results", type: "list.metaobject_reference", validations: [{ name: "metaobject_definition_type", value: "lab_result" }], description: "Optional. In certificate order; results with the same group print under one heading." } ] }) { metaobjectDefinition { type } userErrors { field message code } } faqEntry: metaobjectDefinitionCreate(definition: { type: "faq_entry" name: "FAQ entry" description: "One question and its answer." displayNameKey: "question" access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "question", name: "Question", type: "single_line_text_field" } { key: "answer", name: "Answer", type: "rich_text_field" } ] }) { metaobjectDefinition { type } userErrors { field message code } } author: metaobjectDefinitionCreate(definition: { type: "author" name: "Author" description: "A person credited on blog posts: the writer, or the expert who reviewed the post." displayNameKey: "name" access: { storefront: PUBLIC_READ } capabilities: { translatable: { enabled: true } } fieldDefinitions: [ { key: "name", name: "Name", type: "single_line_text_field", required: true } { key: "credentials", name: "Credentials", type: "single_line_text_field", description: "For example MS, RDN." } { key: "role", name: "Role", type: "single_line_text_field" } { key: "bio", name: "Bio", type: "multi_line_text_field" } { key: "image", name: "Portrait", type: "file_reference", validations: [{ name: "file_type_options", value: "[\"Image\"]" }] } ] }) { metaobjectDefinition { type } userErrors { field message code } } # 2. Metafield definitions, by what they belong to: products, variants, collections, pages, blog posts. productSupplementFacts: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "supplement_facts", name: "Supplement facts", type: "metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "supplement_facts" }] description: "The product's Supplement Facts label." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productIngredients: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "ingredients", name: "Ingredients", type: "list.metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "ingredient" }] description: "Why each ingredient is in the formula, one Ingredient entry each, in display order." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productProtocol: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "protocol", name: "Protocol", type: "metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "protocol" }] description: "How to take the product." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productTimeline: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "timeline", name: "Timeline", type: "list.metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "timeline_step" }] description: "What to expect over time: Timeline step entries in time order." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productLabBatches: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "lab_batches", name: "Lab batches", type: "list.metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "lab_batch" }] description: "Tested batches and their certificates. Newest first: the first is the current batch." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productFaq: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "faq", name: "FAQ", type: "list.metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "faq_entry" }] description: "Questions and answers for the product page." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productFormulaNumber: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "formula_number", name: "Formula number", type: "single_line_text_field" description: "A short number such as 04, shown with the goal on product cards and the product page." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productGoal: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "goal", name: "Goal", type: "collection_reference" description: "The product's main goal collection. Its title is the goal label and its Accent color colors the marker." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productGoals: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "goals", name: "Goals", type: "list.single_line_text_field" description: "Optional: the product's goal collection titles, for a Goal filter in the Search and Discovery app." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productServings: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "servings", name: "Servings", type: "number_integer" description: "Servings per container, used when a variant has no Servings of its own." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productDietary: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "dietary", name: "Dietary", type: "list.single_line_text_field" description: "Diet labels such as Vegan, used when the product has no Dietary preferences attribute." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productRestockNote: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "restock_note", name: "Restock note", type: "single_line_text_field" description: "Shown when a sold-out variant has no restock note of its own." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } productBundleProducts: metafieldDefinitionCreate(definition: { ownerType: PRODUCT, namespace: "custom", key: "bundle_products", name: "Bundle products", type: "list.product_reference" description: "The products in this bundle, listed by a Collapsible row block set to Bundle contents." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } variantSupplementFacts: metafieldDefinitionCreate(definition: { ownerType: PRODUCTVARIANT, namespace: "custom", key: "supplement_facts", name: "Supplement facts", type: "metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "supplement_facts" }] description: "This variant's Supplement Facts label, when it differs from the product's (another size or flavor)." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } variantServings: metafieldDefinitionCreate(definition: { ownerType: PRODUCTVARIANT, namespace: "custom", key: "servings", name: "Servings", type: "number_integer" description: "Servings in this variant. Sets the price per serving and how long a delivery lasts." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } variantRestockNote: metafieldDefinitionCreate(definition: { ownerType: PRODUCTVARIANT, namespace: "custom", key: "restock_note", name: "Restock note", type: "single_line_text_field" description: "Shown when this variant is sold out, for example Back in stock on December 3." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } collectionAccentColor: metafieldDefinitionCreate(definition: { ownerType: COLLECTION, namespace: "custom", key: "accent_color", name: "Accent color", type: "color" description: "The color of this collection's goal marker." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } collectionKeyActives: metafieldDefinitionCreate(definition: { ownerType: COLLECTION, namespace: "custom", key: "key_actives", name: "Key ingredients", type: "single_line_text_field" description: "A short line such as Magnesium, L-theanine, glycine under the goal's name in Shop by goal." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } pageFaq: metafieldDefinitionCreate(definition: { ownerType: PAGE, namespace: "custom", key: "faq", name: "FAQ", type: "list.metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "faq_entry" }] description: "Questions and answers for a page with the FAQ section." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } blogPostAuthor: metafieldDefinitionCreate(definition: { ownerType: ARTICLE, namespace: "custom", key: "author", name: "Author", type: "metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "author" }] description: "The person who wrote the post." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } blogPostReviewedBy: metafieldDefinitionCreate(definition: { ownerType: ARTICLE, namespace: "custom", key: "reviewed_by", name: "Reviewed by", type: "metaobject_reference" validations: [{ name: "metaobject_definition_type", value: "author" }] description: "The expert who reviewed the post." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } blogPostRelatedProducts: metafieldDefinitionCreate(definition: { ownerType: ARTICLE, namespace: "custom", key: "related_products", name: "Related products", type: "list.product_reference" description: "Products mentioned in the post, shown when the Article section's own Products setting is empty." access: { storefront: PUBLIC_READ }, pin: true }) { createdDefinition { ownerType namespace key } userErrors { field message code } } # 3. Shopify's standard definitions the theme reads. productSubtitle: standardMetafieldDefinitionEnable(ownerType: PRODUCT, namespace: "descriptors", key: "subtitle", pin: true) { createdDefinition { ownerType namespace key } userErrors { field message code } } }