Answers to all of your Big Cartel questions.

Creating a custom theme

Last Updated: Jul 24, 2013 11:22AM MDT

Big Cartel’s flexible Theme API lets you customize your store using the same powerful tools we used to create the default themes.


Changing your theme's code requires a decent understanding of HTML, CSS, and JavaScript. Once you start customizing your theme code so that it’s different from the defaults that we’ve created and tested, it’s up to you to maintain it. We can’t provide too much support on all the custom design changes you make. If you need assistance, try these resources and designers.



To output a value to your HTML, you surround a variable with two curly brackets.

      My store is called {{ }}

      This image is {{ image.width }} pixels wide

      <a href="{{ page.url }}">My Page</a>

Filters are simple methods to format or manipulate output. The first parameter is your starting value, and it runs from left to right through one or more filters separated by bars.

      {{ product.price | money_with_sign }}

      {{ | capitalize | truncate }}

      {{ cart.item_count | pluralize: 'item', 'items' }}

Tags are the logic in your HTML. You surround a tag with a curly bracket and a percent.

      {% if product.on_sale %}

      {% for item in cart.items %}

      {% cycle 'odd', 'even' %}
If / Else / Elsif

These tags let you show different output for different conditions. The opposite of if is unless. You can use and and or to combine conditions.

      {% if != blank %}
        <a href="{{ }}">Back to Site</a>
      {% endif %}

      {% if product.on_sale %}
        On Sale!
      {% else %}
        Regular price
      {% endif %}

      {% if product.images == empty %}
        Just use your imagination
      {% endif %}

      {% if product.price > 100 %}
        This is pretty expensive
      {% elsif product.price > 50 %}
        This is a little expensive
      {% endif %}

      {% if cart.shipping.enabled %}
        Shipping: {{ cart.shipping.amount | money_with_sign }}
      {% endif %}

      {% unless cart.item_count == 0 }
        Start shopping!
      {% endunless %}

      # colors = ['red','blue','green']
      {% if colors contains 'blue' %} 
         It's blue!
      {% endif %}

      {% if page.full_url contains '/category/mens' %} 
         Men's wear!
      {% endif %}
Case Statement

These tags let you handle multiple conditions.

      {% case product.status %}

      {% when 'active' %}
        Buy me!
      {% when 'coming-soon' %}
        Buy me soon!
      {% when 'sold-out' %}
        You already bought me!
      {% endcase %}
For Loops

These tags allow you to loop over collections.

      {% for product in products.featured %}
        Product: {{ }}
      {% endfor %}

      {% for item in cart.items %}
        Item: {{ }}
      {% endfor %}

During every for loop there are a few helper variables available.

      forloop.length  # => length of the entire for loop
      forloop.index   # => index of the current iteration 
      forloop.index0  # => index of the current iteration (zero based) 
      forloop.rindex  # => how many items are still left?
      forloop.rindex0 # => how many items are still left? (zero based)
      forloop.first   # => is this the first iteration?
      forloop.last    # => is this the last iteration?

Refine which items are in your loop by using limit and offest.

      {% for image in product.images limit:2 %}
        Show two images: {{ image.url }}
      {% endfor %}

      {% for product in products offset:1 %}
        Skip first product: {{ }}
      {% endfor %}

Loop over a range of both literal or variable numbers.

      {% for i in (1..cart.item_count) %}
        Item number {{ i }}
      {% endfor %}

These tags let alternate between a set of values. Commonly used to alternate between colors to zebra stripe rows.

      {% cycle 'one', 'two', 'three' %} 

      {% for item in cart.items %}
        <li class="{% cycle 'odd', 'even' %}">
      {% endfor %}
Variable Assignment

These tags let you store data in your own variables to be used in output or other tags. The easiest way is with the assign tag.

      {% assign looking_for = 'Tees' %} 

      {% for category in categories.all %}
        {% if == looking_for %}
        {% endif %}
      {% endfor %}

Combine a number of strings into one variable by using the capture tag. These are blocks that "capture" whatever is rendered inside and assign it to the given variable.

      {% for category in categories %}
        {% capture css_id %}category_{{ category.permalink }}_{{ forloop.index }}{% endcapture %}
        <li id="{{ css_id }}" class="{{ css_id }}">{{ }}</li>
      {% endfor %}

This tag breaks your products up into multiple pages. There can be only one paginate tag per page.

    {% paginate [variable] from products.all by [number] limit:[number] order:[order] inner_window:[number] outer_window:[number] %}
      {{ paginate | default_pagination }}
    {% endpaginate %}
  • variable (required) — a variable name for the products that are returned. Ex: products or featured_products
  • by (required) — sets how many products per page. This can be a number or variable, and defaults to the number of products per page setting in your theme options. The maximum number is 100.
  • limit (optional) — how many products to fetch. This can be a number or variable. The maximum number is 100.
  • order (optional) — can be one of 'newest', 'sales' or 'views' and will take a variable. Defaults to the order your products are listed on your Products admin page.
  • inner_window (optional) — sets the number of page links displayed on either side of the current page. Defaults to 3.
  • outer_window (optional) — sets the number of links at the start and end of the list of page links. Defaults to 1.
Basic usage

The easiest way to display the page links when using paginate is to use the default_pagination filter.

    {% paginate products from products.all by 10 %}
      <p>{{ }}</p>
      {{ paginate | default_pagination }}
    {% endpaginate %}
Advanced usage

Instead of using the default_pagination filter, you can create create your own pagination links. Within the paginate tag you have access to a paginate object which provides the following information:

  • paginate.page_size — number of products on the page
  • paginate.current_page — current page number
  • paginate.current_offset — sum of total products in previous pages
  • paginate.pages — total number of pages
  • paginate.items — total number of paginated products
  • paginate.previous — if there is a previous page, this provides the link details
    • paginate.previous.title — title of the previous page link
    • paginate.previous.url — URL of the previous page link
  • — if there is a next page, this provides the link details
    • — title of the next page link
    • — URL of the next page link
  • — array of all the parts necessary for pagination
  • part.is_link — is this a link?
  • part.title — link title
  • part.url — link URL

Here is an example of how to use the paginate object to make {{ paginate | default_pagination }}:


This tag fetches a limited number of products in a specific order.

      {% get [variable] in products.all limit:[number] order:[order] %}
      {% endget %}
  • variable (required) — a variable name for the products that are returned. Ex: products or featured_products
  • limit (optional) — how many products to fetch. This can be a number or variable, and the max is 100.
  • order (optional) — can be one of 'newest', 'sales' or 'views' and will take a variable. Defaults to the order your products are listed on your Products admin page.
Basic usage

Top 5 Sellers
{% get top_products from products.all limit:5 order:'sales' %} <p>{{ }}</p> {% endget %}
Alternative syntax
      {% get [limit] [variable] in products.all order:[order] %}
      {% endget %}

Which would make the above example look like this:

Top 5 Sellers
{% get 5 top_products in products.all order:'sales' %} <p>{{ }}</p> {% endget %}
seconds ago
a minute ago
minutes ago
an hour ago
hours ago
a day ago
days ago
Invalid characters found