> ## Documentation Index
> Fetch the complete documentation index at: https://quickbutik.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Mustache Template Basics

> Master the fundamentals of Mustache templating for Quickbutik themes

Mustache is a logic-less templating language that Quickbutik uses to create dynamic storefronts. This guide covers the core syntax and fundamental concepts you need to get started with Mustache templates.

<Info>
  **Why Mustache?**

  * Simple, readable syntax
  * Logic-less design prevents complex business logic in templates
  * Cross-platform compatibility
  * Secure by design - prevents code injection
</Info>

## Template Syntax Overview

All Mustache templates use double curly braces `{{}}` to denote dynamic content. Here are the basic patterns:

<CardGroup cols={2}>
  <Card title="Variables" icon="tag">
    `{{variable}}` - Outputs the value of a variable
  </Card>

  <Card title="Sections" icon="code-branch">
    `{{#section}}...{{/section}}` - Conditional blocks or loops
  </Card>

  <Card title="Inverted Sections" icon="x">
    `{{^section}}...{{/section}}` - Shows content when condition is false
  </Card>

  <Card title="Comments" icon="comment">
    `{{! This is a comment }}` - Not rendered in output
  </Card>
</CardGroup>

## Variables and Output

The simplest Mustache tag outputs a variable's value:

<CodeGroup>
  ```mustache Basic Variables theme={null}
  <!-- Display product information -->
  <h1>{{product.title}}</h1>
  <p>Price: {{product.price}} {{product.currency}}</p>
  <p>SKU: {{product.sku}}</p>

  <!-- Display store information -->
  <footer>© {{shop.name}}</footer>
  ```

  ```html Expected Output theme={null}
  <!-- Display product information -->
  <h1>Amazing T-Shirt</h1>
  <p>Price: 299 SEK</p>
  <p>SKU: SHIRT-001</p>

  <!-- Display store information -->
  <footer>© My Awesome Store</footer>
  ```
</CodeGroup>

### HTML Escaping

By default, Mustache escapes HTML characters for security. Use `{{{variable}}}` or `{{&variable}}` to render unescaped HTML:

<CodeGroup>
  ```mustache HTML Escaping Examples theme={null}
  <!-- Escaped HTML (safe) -->
  <div>{{product.description}}</div>

  <!-- Unescaped HTML (renders HTML tags) -->
  <div>{{&product.description}}</div>
  <div>{{{product.description}}}</div>
  ```

  ```html Output Comparison theme={null}
  <!-- If product.description contains: "<strong>Bold text</strong>" -->

  <!-- Escaped version -->
  <div>&lt;strong&gt;Bold text&lt;/strong&gt;</div>

  <!-- Unescaped version -->
  <div><strong>Bold text</strong></div>
  ```
</CodeGroup>

<Warning>
  **Security Note**: Only use unescaped output (`{{&}}` or `{{{}}}`) with trusted content like product descriptions that you control. Never use it with user-generated content.
</Warning>

## Basic Sections and Conditionals

Sections are the core of Mustache's logic. They render content based on the truthiness of a value:

<CodeGroup>
  ```mustache Simple Conditionals theme={null}
  <!-- Show content if product is on sale -->
  {{#product.has_before_price}}
      <div class="sale-badge">SALE!</div>
      <span class="original-price">{{product.before_price}}</span>
  {{/product.has_before_price}}

  <!-- Show content if product is NOT sold out -->
  {{^product.soldOut}}
      <button class="add-to-cart">Add to Cart</button>
  {{/product.soldOut}}

  <!-- Show content if product IS sold out -->
  {{#product.soldOut}}
      <div class="sold-out-notice">Sorry, this item is sold out</div>
  {{/product.soldOut}}
  ```
</CodeGroup>

### Basic Loops

When a section's value is an array, Mustache loops through each item:

<CodeGroup>
  ```mustache Simple Loops theme={null}
  <!-- Loop through product images -->
  <div class="product-gallery">
      {{#product.images}}
          <img src="{{image}}" alt="{{alttext}}" class="product-image">
      {{/product.images}}
  </div>

  <!-- Loop through navigation items -->
  <nav>
      {{#linklist.main}}
          <a href="{{url}}">{{name}}</a>
      {{/linklist.main}}
  </nav>

  <!-- Handle empty arrays -->
  {{#basket.items}}
      <div class="cart-item">{{item.title}} - {{qty}}</div>
  {{/basket.items}}
  {{^basket.items}}
      <p>Your cart is empty</p>
  {{/basket.items}}
  ```
</CodeGroup>

## Basic Object Access

Use dot notation to access object properties:

<CodeGroup>
  ```mustache Object Properties theme={null}
  <!-- Simple object properties -->
  {{product.title}}
  {{product.price}}
  {{shop.name}}

  <!-- Nested object properties -->
  {{order.customer.firstname}}
  {{order.customer.lastname}}
  {{order.customer.ship_address}}
  ```
</CodeGroup>

### Understanding Context

Inside a section, the context changes to that object:

<CodeGroup>
  ```mustache Context Changes theme={null}
  <!-- Outside any section, we're in global context -->
  <h1>Welcome to {{shop.name}}</h1>

  {{#basket.items}}
      <!-- Inside this section, context is each basket item -->
      <div class="cart-item">
          <h3>{{item.title}}</h3>  <!-- item.title, not basket.items.item.title -->
          <p>Quantity: {{qty}}</p>  <!-- qty, not basket.items.qty -->
          <p>Price: {{item.price}}</p>
      </div>
  {{/basket.items}}

  {{#product}}
      <!-- Inside this section, context is the product object -->
      <h1>{{title}}</h1>  <!-- product.title is now just title -->
      <p>{{description}}</p>  <!-- product.description is now just description -->
  {{/product}}
  ```
</CodeGroup>

## Helper Functions Overview

Quickbutik provides special wrapper functions for common tasks:

<CodeGroup>
  ```mustache Helper Function Examples theme={null}
  <!-- Image resizing -->
  <img src="{{#img}}{{product.firstimage}}_400x400{{/img}}" alt="{{product.title}}">

  <!-- Text translation -->
  <button>{{#lang}}Add to Cart{{/lang}}</button>

  <!-- Asset linking -->
  <link rel="stylesheet" href="{{#assets}}css/styles.css{{/assets}}">
  ```
</CodeGroup>

<Info>
  **Learn More**: Helper functions are covered in detail in the [Wrappers and Functions](/theme-development/wrappers-and-functions) guide.
</Info>

## Best Practices

<CardGroup cols={2}>
  <Card title="Keep It Simple" icon="heart">
    Mustache is designed to be logic-less. Keep business logic in your data, not your templates.
  </Card>

  <Card title="Use Descriptive Names" icon="tag">
    Use clear, descriptive variable names in your templates for better maintainability.
  </Card>

  <Card title="Handle Empty States" icon="circle-xmark">
    Always provide fallbacks for empty arrays and missing data.
  </Card>

  <Card title="Escape User Content" icon="shield">
    Use default (escaped) output for any user-generated content.
  </Card>
</CardGroup>

### Template Organization

<CodeGroup>
  ```mustache Good Structure theme={null}
  <!-- Clear sections with comments -->
  {{! Product Gallery Section }}
  <div class="product-gallery">
      {{#product.images}}
          <img src="{{#img}}{{image}}_600x600{{/img}}" alt="{{alttext}}">
      {{/product.images}}
  </div>

  {{! Product Information Section }}
  <div class="product-info">
      <h1>{{product.title}}</h1>
      
      {{! Price Display }}
      <div class="price">
          {{#product.has_before_price}}
              <span class="was-price">{{product.before_price}}</span>
          {{/product.has_before_price}}
          <span class="current-price">{{product.price}}</span>
      </div>
  </div>
  ```
</CodeGroup>

## Common Mistakes to Avoid

<AccordionGroup>
  <Accordion title="Forgetting to close sections">
    ```mustache theme={null}
    <!-- Wrong: Missing closing tag -->
    {{#product.soldOut}}
        <p>Sold out!</p>

    <!-- Correct: Properly closed -->
    {{#product.soldOut}}
        <p>Sold out!</p>
    {{/product.soldOut}}
    ```
  </Accordion>

  <Accordion title="Incorrect context assumptions">
    ```mustache theme={null}
    <!-- Wrong: Assuming global context inside a loop -->
    {{#basket.items}}
        <p>{{product.title}}</p>  <!-- product is not available here -->
    {{/basket.items}}

    <!-- Correct: Using the actual context -->
    {{#basket.items}}
        <p>{{item.title}}</p>  <!-- item is the correct context -->
    {{/basket.items}}
    ```
  </Accordion>

  <Accordion title="Using unescaped output unnecessarily">
    ```mustache theme={null}
    <!-- Wrong: Unescaping when not needed -->
    <h1>{{{product.title}}}</h1>

    <!-- Correct: Default escaping is usually fine -->
    <h1>{{product.title}}</h1>

    <!-- Only unescaped when rendering HTML content -->
    <div>{{&product.description}}</div>
    ```
  </Accordion>
</AccordionGroup>

## Testing Your Templates

<Steps>
  <Step title="Use the preview function">
    Always test your templates using Quickbutik's preview feature before publishing
  </Step>

  <Step title="Test edge cases">
    Test with products that have no images, are sold out, or have no variants
  </Step>

  <Step title="Check different page types">
    Make sure your templates work across different contexts (product pages, category pages, etc.)
  </Step>

  <Step title="Validate HTML output">
    Use browser developer tools to ensure your templates generate valid HTML
  </Step>
</Steps>

## Next Steps

Now that you understand the basics, dive deeper into specific aspects:

<CardGroup cols={2}>
  <Card title="Objects and Attributes" icon="box" href="/theme-development/objects-and-attributes">
    Learn about all the data objects and how to access their properties
  </Card>

  <Card title="Conditionals" icon="code-branch" href="/theme-development/conditionals">
    Master advanced conditional logic and pattern matching
  </Card>

  <Card title="Wrappers and Functions" icon="brackets-curly" href="/theme-development/wrappers-and-functions">
    Discover all available helper functions and their usage
  </Card>

  <Card title="Global Objects" icon="globe" href="/theme-development/global/shop">
    Explore store-wide data like settings, navigation, and cart
  </Card>
</CardGroup>
