# Themes Reference Guide for developing Shopify themes with Liquid templating. ## Liquid Templating ### Syntax Basics **Objects (Output):** ```liquid {{ product.title }} {{ product.price | money }} {{ customer.email }} ``` **Tags (Logic):** ```liquid {% if product.available %} {% else %}

Sold Out

{% endif %} {% for product in collection.products %} {{ product.title }} {% endfor %} {% case product.type %} {% when 'Clothing' %} Apparel {% when 'Shoes' %} Footwear {% else %} Other {% endcase %} ``` **Filters (Transform):** ```liquid {{ product.title | upcase }} {{ product.price | money }} {{ product.description | strip_html | truncate: 100 }} {{ product.image | img_url: 'medium' }} {{ 'now' | date: '%B %d, %Y' }} ``` ### Common Objects **Product:** ```liquid {{ product.id }} {{ product.title }} {{ product.handle }} {{ product.description }} {{ product.price }} {{ product.compare_at_price }} {{ product.available }} {{ product.type }} {{ product.vendor }} {{ product.tags }} {{ product.images }} {{ product.variants }} {{ product.featured_image }} {{ product.url }} ``` **Collection:** ```liquid {{ collection.title }} {{ collection.handle }} {{ collection.description }} {{ collection.products }} {{ collection.products_count }} {{ collection.image }} {{ collection.url }} ``` **Cart:** ```liquid {{ cart.item_count }} {{ cart.total_price }} {{ cart.items }} {{ cart.note }} {{ cart.attributes }} ``` **Customer:** ```liquid {{ customer.email }} {{ customer.first_name }} {{ customer.last_name }} {{ customer.orders_count }} {{ customer.total_spent }} {{ customer.addresses }} {{ customer.default_address }} ``` **Shop:** ```liquid {{ shop.name }} {{ shop.email }} {{ shop.domain }} {{ shop.currency }} {{ shop.money_format }} {{ shop.enabled_payment_types }} ``` ### Common Filters **String:** - `upcase`, `downcase`, `capitalize` - `strip_html`, `strip_newlines` - `truncate: 100`, `truncatewords: 20` - `replace: 'old', 'new'` **Number:** - `money` - Format currency - `round`, `ceil`, `floor` - `times`, `divided_by`, `plus`, `minus` **Array:** - `join: ', '` - `first`, `last` - `size` - `map: 'property'` - `where: 'property', 'value'` **URL:** - `img_url: 'size'` - Image URL - `url_for_type`, `url_for_vendor` - `link_to`, `link_to_type` **Date:** - `date: '%B %d, %Y'` ## Theme Architecture ### Directory Structure ``` theme/ ├── assets/ # CSS, JS, images ├── config/ # Theme settings │ ├── settings_schema.json │ └── settings_data.json ├── layout/ # Base templates │ └── theme.liquid ├── locales/ # Translations │ └── en.default.json ├── sections/ # Reusable blocks │ ├── header.liquid │ ├── footer.liquid │ └── product-grid.liquid ├── snippets/ # Small components │ ├── product-card.liquid │ └── icon.liquid └── templates/ # Page templates ├── index.json ├── product.json ├── collection.json └── cart.liquid ``` ### Layout Base template wrapping all pages (`layout/theme.liquid`): ```liquid {{ page_title }} {{ content_for_header }} {% section 'header' %}
{{ content_for_layout }}
{% section 'footer' %} ``` ### Templates Page-specific structures (`templates/product.json`): ```json { "sections": { "main": { "type": "product-template", "settings": { "show_vendor": true, "show_quantity_selector": true } }, "recommendations": { "type": "product-recommendations" } }, "order": ["main", "recommendations"] } ``` Legacy format (`templates/product.liquid`): ```liquid
{{ product.title }}

{{ product.title }}

{{ product.price | money }}

{% form 'product', product %} {% endform %}
``` ### Sections Reusable content blocks (`sections/product-grid.liquid`): ```liquid
{% for product in section.settings.collection.products %}
{{ product.title }}

{{ product.title }}

{{ product.price | money }}

{% endfor %}
{% schema %} { "name": "Product Grid", "settings": [ { "type": "collection", "id": "collection", "label": "Collection" }, { "type": "range", "id": "products_per_row", "min": 2, "max": 5, "step": 1, "default": 4, "label": "Products per row" } ], "presets": [ { "name": "Product Grid" } ] } {% endschema %} ``` ### Snippets Small reusable components (`snippets/product-card.liquid`): ```liquid
{% if product.featured_image %} {{ product.title }} {% endif %}

{{ product.title }}

{{ product.price | money }}

{% if product.compare_at_price > product.price %}

{{ product.compare_at_price | money }}

{% endif %}
``` Include snippet: ```liquid {% render 'product-card', product: product %} ``` ## Development Workflow ### Setup ```bash # Initialize new theme shopify theme init # Choose Dawn (reference theme) or blank ``` ### Local Development ```bash # Start local server shopify theme dev # Preview at http://localhost:9292 # Changes auto-sync to development theme ``` ### Pull Theme ```bash # Pull live theme shopify theme pull --live # Pull specific theme shopify theme pull --theme=123456789 # Pull only templates shopify theme pull --only=templates ``` ### Push Theme ```bash # Push to development theme shopify theme push --development # Create new unpublished theme shopify theme push --unpublished # Push specific files shopify theme push --only=sections,snippets ``` ### Theme Check Lint theme code: ```bash shopify theme check shopify theme check --auto-correct ``` ## Common Patterns ### Product Form with Variants ```liquid {% form 'product', product %} {% unless product.has_only_default_variant %} {% for option in product.options_with_values %}
{% endfor %} {% endunless %} {% endform %} ``` ### Pagination ```liquid {% paginate collection.products by 12 %} {% for product in collection.products %} {% render 'product-card', product: product %} {% endfor %} {% if paginate.pages > 1 %} {% endif %} {% endpaginate %} ``` ### Cart AJAX ```javascript // Add to cart fetch('/cart/add.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: variantId, quantity: 1 }) }) .then(res => res.json()) .then(item => console.log('Added:', item)); // Get cart fetch('/cart.js') .then(res => res.json()) .then(cart => console.log('Cart:', cart)); // Update cart fetch('/cart/change.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: lineItemKey, quantity: 2 }) }) .then(res => res.json()); ``` ## Metafields in Themes Access custom data: ```liquid {{ product.metafields.custom.care_instructions }} {{ product.metafields.custom.material.value }} {% if product.metafields.custom.featured %} Featured {% endif %} ``` ## Best Practices **Performance:** - Optimize images (use appropriate sizes) - Minimize Liquid logic complexity - Use lazy loading for images - Defer non-critical JavaScript **Accessibility:** - Use semantic HTML - Include alt text for images - Support keyboard navigation - Ensure sufficient color contrast **SEO:** - Use descriptive page titles - Include meta descriptions - Structure content with headings - Implement schema markup **Code Quality:** - Follow Shopify theme guidelines - Use consistent naming conventions - Comment complex logic - Keep sections focused and reusable ## Resources - Theme Development: https://shopify.dev/docs/themes - Liquid Reference: https://shopify.dev/docs/api/liquid - Dawn Theme: https://github.com/Shopify/dawn - Theme Check: https://shopify.dev/docs/themes/tools/theme-check