Last updated

Build Fluid Themes

Build fast, flexible themes at scale using Liquid templating language, JSON sections, and modern web technologies including HTML, CSS, and JavaScript.

Build a new theme - Create a new theme based on Fluid's root themes (Fluid, Vox, or Base)

Customize a theme - Update the look and feel of an existing theme to tailor it to your company's unique brand and requirements


Table of Contents

  1. Getting Started
  2. Key Concepts
  3. Architecture
  4. Layouts
  5. Templates
  6. Sections
  7. Blocks
  8. Settings
  9. Config
  10. Locales
  11. Best Practices

Getting Started

Overview

Fluid themes are a package of template files, building blocks, and supporting assets that define how your company's pages look and function. The theme system provides multiple levels of customization, from simple CSS variable changes to complete template overrides.

Quick Start

  1. Choose a Root Theme: Select from Fluid, Vox, or Base themes
  2. Clone for Customization: Create a company-specific copy
  3. Configure Variables: Set brand colors, fonts, and spacing
  4. Customize Templates: Override specific page layouts as needed
  5. Publish: Activate your theme for all users

The theme system handles the technical implementation behind the scenes, allowing you to focus on design and customization.


Key Concepts

Themes vs Application Themes

Legacy Themes - Simple theme selection system for basic switching Application Themes - Full-featured system with template management, versioning, and customization

Theme Hierarchy

  • Root Themes: Platform-provided base themes (fluid, vox, base)
  • Company Themes: Company-specific themes that clone and customize root themes
  • Template Inheritance: Company themes can override specific templates while inheriting others

Template Types

Templates in Fluid themes handle different content types and page layouts:

Template TypePurposeExamples
Content TemplatesRender specific content itemsproduct, medium, library
Page TemplatesHandle page typeshome_page, shop_page, cart_page
Layout ComponentsProvide page structurenavbar, footer, layouts
Structural ComponentsReusable template partssections, components, config

Architecture

Theme-Company Relationships

CompanyintidPKstringnamestringsubdomainApplicationThemeintidPKintcompany_idFKNULL for root themesstringnametextvariablesJSON CSS variablestextcustom_stylesheettextglobal_stylesheetstringversionintstatus0=draft, 1=activeApplicationThemeTemplateintidPKintcompany_idFKintapplication_theme_idFKstringnameintthemeable_typeproduct, medium, home_page, etctextcontentLiquid or JSON templatestringformatliquid or jsonintstatus0=draft, 1=activebooleandefaultdefault for themeable_typeFileReferenceProductMediumPagehas many themeshas one current_themecontains templatesreferences filescan have specific templatecan have specific templatecan have specific template

Template Resolution Priority

  1. URL Parameter Override - ?template_id=123 (highest priority)
  2. Content-Specific Assignment - Individual content items with assigned templates
  3. Company Theme Default - Default templates in company's active theme
  4. Root Theme Fallback - Inherit from root theme if company theme lacks template

Request Flow

User Request → Controller → Template Resolution → Variable Population → Rendering → Response

Layouts

Layouts provide the structural wrapper for your content, defining the overall page structure including HTML document structure, navigation, and footer elements. The layout file (theme.liquid) serves as the foundation of your theme and is located in the layout folder. This file contains:

  • Common elements (headers, footers)
  • Shared JavaScript files
  • Global CSS styles
  • Other repeated theme elements

Layout Folder Structure

theme/
├── layout/
│   ├── theme.liquid
├── ..
:

content_for_layout variables

Dynamically returns content based on the current template.

Include {{ content_for_layout }} in your layout files between the <body> and </body> HTML tags.

content_for_header variables

Returns the content of 'app/views/layouts/_theme_header.html.slim' which includes all metadata, scripts, global variables, and other required data by Fluid.

Include {{ content_for_header }} in your layout files between the <head> and </head> HTML tags.

Important: You must include the {{ content_for_header }} and {{ content_for_layout }} in your layout files for the theme to render correctly.

Layout Structure

<!DOCTYPE html>
<html lang="{{ request.locale.iso_code }}">
  <head>
    {{ content_for_header }}
    <style>
      :root {
        --primary-color: {{ settings.primary_color }};
        --font-family: {{ settings.font_family }};
      }
    </style>
  </head>
  <body>
    <!-- Navigation -->
    {'%' section 'navbar' '%'}
    
    <!-- Main content area -->
    {{ content_for_layout }}
    
    <!-- Footer -->
    {'%' section 'footer' '%'}
    
    <!-- JavaScript -->
    <script src="{{ 'theme.js' | asset_url }}"></script>
  </body>
</html>

Layout Assignment

Templates can specify their layout using:

Liquid Templates:

{'%' layout 'theme' '%'}
<!-- Template content -->

Custom Layouts

Create specialized layouts for different page types:

<!-- layouts/minimal.liquid -->
<!DOCTYPE html>
<html>
  <head>
    <title>{{ page_title }}</title>
    {{ theme.global_stylesheet_with_variables | raw }}
  </head>
  <body class="minimal-layout">
    {{ content_for_layout }}
  </body>
</html>

To use a different layout from the default theme.liquid, add the {'%' layout "custom_layout_name" '%'} tag at on your template file:

{'%' layout "minimal" '%'}

Disabling layout

To render a template without any layout, use {'%' layout none '%'} on your template file:

{'%' layout none '%'}
<!DOCTYPE html>
<html>
 <head>
  {{ content_for_header }}
 </head>
 <body>
   <h1>Welcome to the Dashboard</h1>
 </body>
</html>

You will still have access to content_for_header variable which includes all necessary metadata, scripts and stylesheets required to run the page smoothly.


Templates

Templates define the structure and content for specific page types. Fluid supports both Liquid and JSON template formats.

Liquid Templates

Traditional server-side templating using Liquid syntax:

{'%' comment '%'}
  Product page template
{'%' endcomment '%'}

<article class="product-page">
  <header class="product-header">
    <h1>{{ product.name }}</h1>
    <div class="product-price">
      {{ product.price | money }}
    </div>
    {'% if product.tags.size > 0 %'}
      <div class="product-tags">
        {{ product.tags | join: ', ' }}
      </div>
    {'% endif %'}
  </header>

  <div class="product-gallery">
    {'% for image in product.images %'}
      <img src="{{ image.url | img_url: '600x400' }}" 
           alt="{{ image.alt }}" />
    {'% endfor %'}
  </div>

  <div class="product-description">
    {{ product.description }}
  </div>

  {'% if product.available %'}
    <button class="btn-purchase" data-product-id="{{ product.id }}">
      {{ 'products.add_to_cart' | t }}
    </button>
  {'%' endif '%'}
</article>

Available Template Types

  • product - Individual product pages
  • medium - Media post pages
  • enrollment_pack - Enrollment pack pages
  • home_page - Homepage layout
  • shop_page - Shop/catalog pages
  • cart_page - Shopping cart
  • page - Custom pages
  • navbar - Navigation header
  • footer - Page footer
  • sections - Reusable sections
  • layouts - Page wrapper layouts
  • components - Resuable blocks
  • join_page - List of enrollment packs page
  • collection_page - List of collections page
  • collection - Individual collection page
  • category_page - List of categories page

Navbar and Footer templates are located in the navbar and footer folders respectively. They are referenced in the layout as:

{'%' section 'navbar' '%'}

{'%' section 'footer' '%'}

theme/
:
├── navbar/
│   ├── default/
│   │   ├── index.liquid
│   │   └── styles.css
├── footer/
│   ├── default/
│   │   ├── index.liquid
│   │   └── styles.css
└── ...
:

Sections

Sections are reusable components that can be added to templates. Each section has its own Liquid template and JSON schema defining available settings.

Section Template Structure

<!-- sections/product_header.liquid -->
<div class="product-header" 
     style="background-color: {{ section.settings.background_color }};">
  <div class="product-header-content">
    {'%' if section.settings.show_vendor and product.vendor '%'}
      <div class="product-vendor">{{ product.vendor }}</div>
    {'%' endif '%'}

    <h1 class="product-title product-title--{{ section.settings.title_size }}">
      {{ product.name }}
    </h1>

    {'%' if section.settings.show_price '%'}
      <div class="product-price">
        {{ product.price | money }}
      </div>
    {'%' endif '%'}
  </div>
</div>

{'%' schema '%'}
{
  "name": "Product Header",
  "settings": [
    {
      "type": "checkbox",
      "id": "show_vendor",
      "label": "Show vendor",
      "default": true
    },
    {
      "type": "checkbox", 
      "id": "show_price",
      "label": "Show price",
      "default": true
    },
    {
      "type": "select",
      "id": "title_size",
      "label": "Title size",
      "options": [
        {"value": "small", "label": "Small"},
        {"value": "medium", "label": "Medium"},
        {"value": "large", "label": "Large"}
      ],
      "default": "medium"
    },
    {
      "type": "color",
      "id": "background_color", 
      "label": "Background color",
      "default": "#ffffff"
    }
  ]
}
{'%' endschema '%'}

Using Sections in Templates

{'%' section 'main_product', id: 'main_product' '%'}
{'%' section 'related_products', id: 'related_products' '%'}

{'%' schema '%'}
{
  "sections": {
    "main_product": {
      "type": "main_product",
      "settings": {
        "show_breadcrumb": true
      }
    },
    "related_products": {
      "type": "related_products",
      "settings": {
        "heading": "Products",
        "heading_size": "h1"
      }
    }
  }
}
{'%' endschema '%'}

Section Processing

  1. Section Resolution: Each section type maps to a Liquid template
  2. Settings Injection: Section settings merged with schema defaults
  3. Block Processing: Dynamic blocks processed with individual settings
  4. Template Rendering: Section template rendered with populated variables

Blocks

Blocks are dynamic content elements within sections that can be added, removed, and reordered. They provide flexibility for content creators to customize sections.

Block Definition in Schema

{
  "name": "Testimonials Section",
  "settings": [
    {
      "type": "text",
      "id": "section_title",
      "label": "Section Title",
      "default": "What Our Customers Say"
    }
  ],
  "blocks": [
    {
      "type": "testimonial",
      "name": "Customer Testimonial",
      "limit": 10,
      "settings": [
        {
          "type": "text",
          "id": "customer_name",
          "label": "Customer Name"
        },
        {
          "type": "textarea",
          "id": "testimonial_text",
          "label": "Testimonial"
        },
        {
          "type": "image_picker",
          "id": "customer_photo",
          "label": "Customer Photo"
        }
      ]
    }
  ]
}

Using Blocks in Templates

{
  "sections": {
    "testimonials": {
      "type": "testimonials_section",
      "settings": {
        "section_title": "Customer Reviews"
      },
      "blocks": {
        "testimonial_1": {
          "type": "testimonial",
          "settings": {
            "customer_name": "John Doe",
            "testimonial_text": "Great product!",
            "customer_photo": "photo.jpg"
          }
        }
      },
      "block_order": ["testimonial_1"]
    }
  }
}

Block Rendering in Liquid

<!-- sections/testimonials_section.liquid -->
<div class="testimonials">
  <h2>{{ section.settings.section_title }}</h2>
  
  {'%' for block in section.blocks '%'}
    <div class="testimonial" 
         data-fluid-section-block-id="{{ block.id }}"
         data-fluid-section-block-type="{{ block.type }}">
      {'%' case block.type '%'}
        {'%' when 'testimonial' '%'}
          <blockquote>{{ block.settings.testimonial_text }}</blockquote>
          <cite>{{ block.settings.customer_name }}</cite>
        {'%' when 'divider' '%'}
          <hr class="testimonial-divider">
      {'%' endcase '%'}
    </div>
  {'%' endfor '%'}
</div>

Block Characteristics

  • Dynamic Quantity: Add/remove blocks as needed
  • Reorderable: Drag blocks to change sequence
  • Type-Specific: Different block types have different settings
  • Limited: Optional limit property restricts maximum blocks

Settings

Settings define configurable options for themes, sections, and blocks. They automatically generate form interfaces for customization.

Setting Types

TypeDescriptionExample
textSingle-line text inputProduct title, headings
textareaMulti-line text inputDescriptions, long content
selectDropdown with optionsLayout styles, sizes
checkboxBoolean toggleShow/hide elements
colorColor pickerBrand colors, backgrounds
rangeSlider with min/maxFont sizes, spacing
numberNumeric inputQuantities, dimensions
urlURL input with validationLinks, external resources
image_pickerAsset selectionImages, icons

Theme-Level Settings (CSS Variables)

{
  "primary_color": "#2c5aa0",
  "secondary_color": "#f8f9fa", 
  "font_family": "Inter, sans-serif",
  "heading_font": "Playfair Display, serif",
  "border_radius": "8px",
  "container_width": "1200px"
}

Section Settings Example

{
  "name": "Hero Section",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "label": "Hero Heading",
      "default": "Welcome to Our Store"
    },
    {
      "type": "textarea", 
      "id": "description",
      "label": "Hero Description",
      "default": "Discover amazing products"
    },
    {
      "type": "select",
      "id": "layout",
      "label": "Layout Style",
      "options": [
        {"value": "centered", "label": "Centered"},
        {"value": "left", "label": "Left Aligned"},
        {"value": "right", "label": "Right Aligned"}
      ],
      "default": "centered"
    },
    {
      "type": "color",
      "id": "background_color",
      "label": "Background Color", 
      "default": "#ffffff"
    },
    {
      "type": "range",
      "id": "padding",
      "label": "Section Padding",
      "min": 0,
      "max": 100,
      "step": 10,
      "unit": "px",
      "default": 40
    },
    {
      "type": "checkbox",
      "id": "show_button",
      "label": "Show Call-to-Action Button",
      "default": true
    },
    {
      "type": "image_picker",
      "id": "background_image",
      "label": "Background Image"
    }
  ]
}

Using Settings in Templates

<section class="hero hero--{{ section.settings.layout }}"
         style="background-color: {{ section.settings.background_color }};
                padding: {{ section.settings.padding }}px 0;">
  {'%' if section.settings.background_image '%'}
    <div class="hero-background">
      <img src="{{ section.settings.background_image | img_url: '1920x1080' }}" 
           alt="Hero background" />
    </div>
  {'%' endif '%'}
  
  <div class="hero-content">
    <h1>{{ section.settings.heading }}</h1>
    <p>{{ section.settings.description }}</p>
    
    {'%' if section.settings.show_button '%'}
      <a href="#" class="btn btn-primary">Learn More</a>
    {'%' endif '%'}
  </div>
</section>

Config

Configuration templates define global theme settings and provide structured data for theme customization.

Theme Configuration Structure

{
  "name": "Fluid Theme Configuration",
  "settings": [
    {
      "type": "header",
      "content": "Colors"
    },
    {
      "type": "color",
      "id": "primary_color",
      "label": "Primary Color",
      "default": "#2c5aa0"
    },
    {
      "type": "color", 
      "id": "secondary_color",
      "label": "Secondary Color",
      "default": "#6c757d"
    },
    {
      "type": "header",
      "content": "Typography"
    },
    {
      "type": "font_picker",
      "id": "font_family",
      "label": "Body Font",
      "default": "Inter, sans-serif"
    },
    {
      "type": "font_picker",
      "id": "heading_font", 
      "label": "Heading Font",
      "default": "Playfair Display, serif"
    },
    {
      "type": "header",
      "content": "Layout"
    },
    {
      "type": "range",
      "id": "container_width",
      "label": "Container Max Width",
      "min": 960,
      "max": 1600,
      "step": 40,
      "unit": "px",
      "default": 1200
    },
    {
      "type": "select",
      "id": "border_radius",
      "label": "Border Radius Style",
      "options": [
        {"value": "0px", "label": "Square"},
        {"value": "4px", "label": "Slightly Rounded"},
        {"value": "8px", "label": "Rounded"},
        {"value": "16px", "label": "Very Rounded"}
      ],
      "default": "8px"
    }
  ]
}

Global Settings Access

<!-- Access theme variables in any template -->
<div class="container" style="max-width: {{ settings.container_width }};">
  <h1 style="font-family: {{ settings.heading_font }}; 
             color: {{ settings.primary_color }};">
    {{ page.title }}
  </h1>
</div>

CSS Variable Integration

<!DOCTYPE html>
<html>
  <head>
    {{ content_for_header }}
    <style>
      :root {
        --primary-color: {{ settings.primary_color }};
        --secondary-color: {{ settings.secondary_color }};
        --font-family: {{ settings.font_family }};
        --heading-font: {{ settings.heading_font }};
        --border-radius: {{settings.border_radius }};
        --container-width: {{ settings.container_width }};
      }
    </style>
  </head>
  <body>
    {{ content_for_layout }}
  </body>
</html>
.container {
  max-width: var(--container-width);
  font-family: var(--font-family);
}

.btn-primary {
  background-color: var(--primary-color);
  border-radius: var(--border-radius);
}

Locales

Localization support enables themes to display content in multiple languages and adapt to different regional preferences.

Translation Files Structure

Fluid themes use JSON locale files organized by components and sections for better maintainability:

// locales/en.json
{
  "cart_page": {
    "checkout": "Checkout",
    "order_summary": "Order Summary",
    "shipping": "Shipping estimate",
    "ships_in": "Ships in 3-5 business days",
    "shopping_cart": "Shopping Cart",
    "subtotal": "Subtotal",
    "tax": "Tax estimate",
    "total": "Order total"
  },
  "components": {
    "comment_form": {
      "email": "Email",
      "full_name": "Full Name",
      "leave_info": "Please leave your information so {{ company }} will know who you are. You only need to do this once.",
      "placeholder": "Add your comment",
      "post": "Post",
      "want_to_leave_comment": "Want to leave a comment?"
    }
  },
  "navbar": {
    "button_1": "Button 1",
    "button_2": "Button 2",
    "countries": "Countries",
    "country": "Country",
    "language": "Language",
    "shop": "Shop",
    "enrollments": "Enrollments",
    "view_my_site": "View MySite"
  },
  "product": {
    "add_to_cart": "Add to Cart",
    "buy_now": "Buy Now",
    "details": "Details",
    "free_shipping": "Free Shipping over {{amount}}",
    "quantity": "Quantity",
    "reviews": "{{reviews}} reviews",
    "stars": "{{stars}} stars",
    "one_time_purchase": "One time purchase",
    "subscribe": "Subscribe"
  },
  "shared": {
    "button": "Button",
    "medium_heading": "Medium length heading goes here",
    "short_heading": "Short heading here",
    "tagline": "Tagline",
    "view_all": "View All"
  }
}
// locales/es.json  
{
  "cart_page": {
    "checkout": "Finalizar Compra",
    "order_summary": "Resumen del Pedido",
    "shipping": "Estimación de envío",
    "ships_in": "Se envía en 3-5 días hábiles",
    "shopping_cart": "Carrito de Compras",
    "subtotal": "Subtotal",
    "tax": "Estimación de impuestos",
    "total": "Total del pedido"
  },
  "components": {
    "comment_form": {
      "email": "Correo electrónico",
      "full_name": "Nombre completo",
      "leave_info": "Por favor deja tu información para que {{ company }} sepa quién eres. Solo necesitas hacer esto una vez.",
      "placeholder": "Añade tu comentario",
      "post": "Publicar",
      "want_to_leave_comment": "¿Quieres dejar un comentario?"
    }
  },
  "navbar": {
    "button_1": "Botón 1",
    "button_2": "Botón 2",
    "countries": "Países",
    "country": "País",
    "language": "Idioma",
    "shop": "Tienda",
    "enrollments": "Inscripciones",
    "view_my_site": "Ver Mi Sitio"
  },
  "product": {
    "add_to_cart": "Añadir al Carrito",
    "buy_now": "Comprar Ahora",
    "details": "Detalles",
    "free_shipping": "Envío gratis por encima de {{amount}}",
    "quantity": "Cantidad",
    "reviews": "{{reviews}} reseñas",
    "stars": "{{stars}} estrellas",
    "one_time_purchase": "Compra única",
    "subscribe": "Suscribirse"
  },
  "shared": {
    "button": "Botón",
    "medium_heading": "Encabezado de longitud media aquí",
    "short_heading": "Encabezado corto aquí",
    "tagline": "Eslogan",
    "view_all": "Ver Todo"
  }
}

Using Translations in Templates

<!-- Basic translation -->
<button class="btn-primary">{{ 'product.add_to_cart' | t }}</button>

<!-- Translation with variables -->
<p class="price">{{ 'product.free_shipping' | t: amount: '$50' }}</p>

<!-- Component-based translations -->
<div class="comment-form">
  <label>{{ 'components.comment_form.email' | t }}</label>
  <input type="email" placeholder="{{ 'components.comment_form.placeholder' | t }}">
  <button>{{ 'components.comment_form.post' | t }}</button>
</div>

<!-- Navigation translations -->
<nav class="navbar">
  <a href="/shop">{{ 'navbar.shop' | t }}</a>
  <a href="/enrollments">{{ 'navbar.enrollments' | t }}</a>
  <button>{{ 'navbar.button_1' | t }}</button>
</nav>

<!-- Cart page translations -->
<div class="cart-summary">
  <h2>{{ 'cart_page.shopping_cart' | t }}</h2>
  <div class="total">{{ 'cart_page.total' | t }}: ${{ cart.total }}</div>
  <button>{{ 'cart_page.checkout' | t }}</button>
</div>

Assets

Theme assets are stored in the theme's assets folder. These files are specific to the theme and support its functionality and appearance.

Asset Folder Structure

theme/
├── assets/
│   ├── custom.js
│   ├── banner.jpg
│   ├──logo.png
│   └──...
│

Note: For files that need to be accessed across multiple themes, you can use global files stored in Sidenav > Website > Files.

File Types

Assets can be categorized into two types:

  1. Binary Files

    • Can only be uploaded, not edited
    • Examples: images, fonts, videos
    • Upload only through file selection
  2. Non-Binary Files

    • Can be uploaded or created from scratch
    • Can be edited after creation
    • Examples:
      • CSS files
      • JavaScript files
      • JSON files
    • Creation options:
      • Upload existing file
      • Create blank file with proper extension

Referencing Assets

All files uploaded to the assets folder are automatically processed through Filestack. A CDN URL is generated for each file.These URLs can be referenced throughout your theme

To reference assets in your theme files, use the asset_url filter:

{{ 'filename.ext' | asset_url }}

Example

<link rel="stylesheet" href="{{ 'custom.css' | asset_url }}">
<script src="{{ 'custom.js' | asset_url }}"></script>
<img src="{{ 'banner.jpg' | asset_url }}" alt="Banner">

Best Practices

Performance Optimization

Image Optimization:

<!-- Responsive images with proper sizing -->
<img src="{{ image.url | img_url: '600x400' }}" 
     srcset="{{ image.url | img_url: '300x200' }} 300w,
             {{ image.url | img_url: '600x400' }} 600w,
             {{ image.url | img_url: '1200x800' }} 1200w"
     sizes="(max-width: 768px) 300px, (max-width: 1200px) 600px, 1200px"
     alt="{{ image.alt }}" 
     loading="lazy" />

CSS and JavaScript Loading:

<!-- Critical CSS inline, non-critical async -->
<style>
  /* Critical above-the-fold styles */
  .header, .hero { /* styles */ }
</style>

<link rel="preload" href="{{ 'theme.css' | asset_url }}" as="style" onload="this.onload=null;this.rel='stylesheet'">

<!-- Defer non-critical JavaScript -->
<script src="{{ 'theme.js' | asset_url }}" defer></script>

Accessibility

Semantic HTML:

<article class="product" role="main">
  <header>
    <h1>{{ product.name }}</h1>
  </header>
  
  <nav aria-label="Product images">
    <!-- Image gallery -->
  </nav>
  
  <section aria-label="Product information">
    <p>{{ product.description }}</p>
  </section>
</article>

ARIA Labels and Screen Reader Support:

<button class="btn-cart" 
        aria-label="{{ 'products.add_to_cart' | t }}: {{ product.name }}"
        data-product-id="{{ product.id }}">
  <span aria-hidden="true">🛒</span>
  {{ 'products.add_to_cart' | t }}
</button>

<div class="price" aria-label="{{ 'products.price' | t }}">
  <span class="sr-only">{{ 'products.price' | t }}: </span>
  {{ product.price | money }}
</div>

Mobile-First Design

<!-- Mobile-optimized navigation -->
<nav class="navbar">
  <div class="navbar-brand">
    <a href="/">{{ company.name }}</a>
  </div>
  
  <button class="navbar-toggle" 
          aria-label="{{ 'general.menu' | t }}"
          data-toggle="mobile-menu">
    <span class="hamburger-icon"></span>
  </button>
  
  <div class="navbar-menu" id="mobile-menu">
    <!-- Navigation items -->
  </div>
</nav>

Version Control

Theme Development Workflow:

  1. Create feature branches for template changes
  2. Test changes in preview mode before publishing
  3. Use version control for template content
  4. Maintain audit trails for customizations

Template Organization:

themes/
├── layouts/
│   ├── theme.liquid
│   └── minimal.liquid
├── templates/
│   ├── product.liquid
│   ├── home_page.json
│   └── cart_page.liquid
├── sections/
│   ├── product_header.liquid
│   ├── product_gallery.liquid
│   └── testimonials.liquid
└── config/
    └── settings_schema.json

Liquid Filters Reference

Fluid themes provide powerful Liquid filters for processing and formatting data:

Image Processing:

{{ image.url | img_url: '300x200' }}          <!-- Resize to 300x200 -->
{{ image.url | img_url: '300x200', crop: 'center' }} <!-- Crop from center -->

Text Processing:

{{ text | truncate: 150 }}                    <!-- Limit to 150 characters -->
{{ text | strip_html }}                       <!-- Remove HTML tags -->
{{ text | capitalize }}                       <!-- Capitalize first letter -->

Formatting:

{{ price | money }}                           <!-- Format as currency -->
{{ date | date: '%B %d, %Y' }}               <!-- Format date -->
{{ number | number }}                         <!-- Format number with commas -->

Arrays and Objects:

{{ array | join: ', ' }}                     <!-- Join array elements -->
{{ array | first }}                          <!-- Get first element -->
{{ array | size }}                           <!-- Get array length -->

Asset Management:

{{ 'theme.css' | asset_url }}                <!-- Get theme asset URL -->
{{ 'logo.png' | asset_url }}                 <!-- Get image asset URL -->

JSON:

{{ object | json }}                          <!-- Convert object to JSON string -->

Translation:

{{ 'general.welcome' | t }}                  <!-- Translate using locale file -->
{{ 'cart.items_count' | t: count: 3 }}       <!-- Pass variables to translation -->

See also