Table of Contents

FoxyCart Templates and Caching Primer

Working with FoxyCart Templates

Below, you'll find our best attempt at explaining each aspect of our templates and how you can override, hook into, or remove the aspects that you're interested in. If you have questions, post on our forum and let us know what is confusing, or email support if you have a suggestion on how this documentation can be more helpful.

Looking to customise your templates? Take a look at the Advanced Customisations page.

Introduction to Templating

If you've used a template language before, you can probably skip this section. If you haven't, it's probably useful to go through this section to understand how and why templating works the way it does.

FoxyCart 2.0 takes advantage of Twig javascript templates to allow you the freedom to customize all aspects of the eCommerce experience. Templates allow you to quickly and fairly easily add dynamic aspects to your HTML pages. Here's a quick example of how templates will make your life easier. With a simple HTML page, you'd have this:

<h1 class="product-title">Product 1</h1>
<p class="description">Description about Product 1</p>
<p class="cost">Cost: $25</p>
<a href="#" class="add-link">Add to Cart</a>

The classes make it really easy to style the presentation of the different elements with CSS, but CSS and HTML alone do not allow you to change dynamically update the contents of the HTML. That's why web developers use Javascript, to add interactivity to the sites they design. Commonly this is done with jQuery, so let's examine how that might work. Perhaps you want a product that has two options, and the second option adds 10% to the cost. First, you'd start with your HTML:

<h1 class="product-title">Product 1</h1>
<p class="description">Description about Product 1</p>
<ul class="options">
  <li class="option1"><input type="radio" value="default">Default</input></li>
  <li class="option2"><input type="radio" value="premium">Premium</input></li>
</ul>
<p class="cost">Cost: $<span class="number">25</span></p>
<a href="#" class="add-link">Add to Cart</a>

Then you'd add the javascript to watch the radio buttons:

$( document ).ready( function () {
  $('.options').click( function () {
    var option2 = $('.option2:checked').length;
    if (option2 > 0) {
      $('.number').text('35');
     } else {
      $('.number').text('25');
  });
});

That's potentially ok for one or two products, but it doesn't scale well. That's why smarter engineers than us have created worked on building Javascript templates that help abstract some of this work. The basic concept is you take some JSON data, insert it into a Javascript template, and then insert the combined output into the client document. It works like this. First, you create a template. In this example we're using Twig syntax:

<h1 class="product-title">{{ title }}</h1>
<p class="description">{{ description }}</p>
<ul class="options">
  {% for option in options %}
  <li><input type="radio" value="{{ name }}">{{ name }}</input></li>
  {% endfor %}
</ul>
<p class="cost">Cost: ${{ cost }}</p>
<a href="#" class="add-link">Add to Cart</a>

Now, we can just render the template by providing some JSON data that matches the variables:

var templateData = {
  title: "A product",
  description: "This is a product description",
  options: {[
    option1: {
      cost: 25,
      name: "Default"
    },
    option2: {    
      cost: 35,
      name: "Premium
    }
  ]}
}

No longer do we need to write custom Javascript for each product option. Now we can just let the template rendering engine handle it. The default HTML output of this code looks like this:

<h1 class="product-title">A product</h1>
<p class="description">This is a product description</p>
<ul class="options">
  <li><input type="radio" value="default">default</input></li>
  <li><input type="radio" value="premium">premium</input></li>
</ul>
<p class="cost">Cost: $25</p>
<a href="#" class="add-link">Add to Cart</a>

Now all we have to do is listen for a click, and then re-render the template with the current context. This makes it much easier to scale our code - now we can have as many options as we need. We could also pass in products as data and add new products easily, which it turns out is exactly what happens in FoxyCart templates.

Class, ID, and Data Conventions

CSS Class and ID Naming Principles with BEM

To help make the base FoxyCart theme easily modifiable, we've adopted the BEM methodology for element naming. BEM stands for Block, Element, Modifier and it introduces a funky identifier scheme that we've tried to apply consistently in our templates.

This article will give you an extensive background on the BEM philosophy we used. Basically, Blocks are defined as distinct elements of a template, Elements are the individual HTML elements that make up the Block, and Modifiers are variations of the Elements. They are represented like so:

block--element__modifier

And they can be strung together:

block--block--element__modifier

FoxyCart templates now have as much separation of concerns as possible, which means all classes are only used for presentation styling and have no impact on actual functionality. The goal with BEM styling is that all elements can be custom styled with a the #fc namespace selector plus at most two class names. Custom CSS can be added to the Admin, or you can hook into the BEM naming to easily apply your own styles.

Specific IDs and Data Attributes

Frameworks & Extending

FoxyCart 2.0 has an underlying foundation of Bootstrap - but you can't tell by looking at the HTML. Our Bootstrap CSS is custom compiled with an #fc namespace and then applied to the DOM via Sass's @extend functionality. CSS Tricks covers the basics of Extending in this article. In the FoxyCart Sass, we provide a partial called _fc-to-bootstrap.scss that maps Bootstrap classes on to the correlating FoxyCart classes. If you are building off of the default responsive theme for your customization, it would behoove you to look in that file to see grid classes applied to elements for responsiveness.

This dependency should not be considered permanent. Future updates to FoxyCart may remove Bootstrap for lighter CSS, thus the reason it is not exposed in templates.

Twig Templates & Conventions

All our templates are available (and automatically kept up-to-date) at GitHub: https://github.com/FoxyCart/2.0-templates You'll notice some conventions in those templates, and you'll need to be aware of those as you do your own customization.