====== Templates, Caching, and Template Customization with HTML + CSS ======
===== Quick and Easy Customizations =====
==== Get Your Logo In There! ====
You can set your store logo in the Settings tab of your FoxyCart Store's Admin. There, you can add the url for your store's logo to the "logo url" field. We'll cache your logo to ensure it's served securely, so don't worry about your own SSL.
If you don't already have a copy of your logo someplace online, an alternate option is to add the logo to a Dropbox folder and [[https://www.dropbox.com/help/167|use the share link to paste into the FoxyCart admin]]. That's an easy and free way to get your logo hosted someplace that we can pull from.
==== Other Common Customizations ====
FoxyCart supports many common template customizations from the Template Configuration page in the admin. You can configure:
* Guest checkout settings (forcing guest, forcing account, allowing both but defaulting to one or the other).
* Terms of Service (TOS) checkbox and link.
* Newsletter opt-in checkbox.
* Some color settings to control the visual on the cart, checkout and receipt.
* Product option hiding. (Hide weight, code, category, or all options.)
* Credit card logos. (If you don't accept AmEx, uncheck that box. Note that this only changes the display, not what your payment gateway actually accepts.)
* Credit card security code requirements. (Required, optional, etc.)
* Checkout fields required and displayed. (Don't collect the address info if you aren't shipping. Require a phone field. Etc.)
* Custom content (HTML, JS) injection, for custom styles or tracking code.
* Debugging messaging.
* Receipt over SSL or not.
* Shipping and billing country/region whitelisting/blacklisting. If you only want to accept customers or to ship to certain countries, you can do that here.
==== Minor Styling Customizations ====
Using the custom code template setting, it's now possible to add CSS and javascript to your templates //without needing to modify the templates themselves//. If you just want to change the background, some colors or styling, or anything else you accomplish with CSS only, we strongly recommend taking this approach. If you want to really customize, read on!
===== Advanced and Thorough Customizations =====
==== What Are Templates and Why Do You Care? ====
Nearly every piece of HTML that FoxyCart presents to your customers is configurable in a template for your store. There are individual templates for:
* [[.:cart|The Cart]]
* [[.:checkout|The Checkout]]
* [[.:receipt|The Receipt]]
* [[.:emails|Email Receipts]] in plain text and HTML, for the store-wide as well as category-specific varieties.
While you can certainly use the [[#default_template_styles|default templates]], we will see just how easy it is to use your own site's design for your FoxyCart templates.
Description about Product 1 Cost: $25 Description about Product 1 Cost: $25 {{ description }} Cost: ${{ cost }} This is a product description Cost: $25
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:
Product 1
Then you'd add the javascript to watch the radio buttons:
Product 1
$( 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:
Now, we can just render the template by providing some JSON data that matches the variables:
{{ title }}
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:
Now all we have to do is listen for a click, and then rerender 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 ====
* ''.fc-*'' classes are for styling purposes only. They aren't required for functionality. (See more in the BEM section immediately below.)
* ''#fc-*'' IDs are for styling purposes. ''#fc-'' IDs are used sparingly, and mostly for namespacing CSS. (See more in the BEM section immediately below.) Our recommendation is to **not use these IDs for javascript selectors**. Use the ''data-fc-*'' attribute(s) instead and stick with our conventions.
* ''data-fc-*'' attributes are for functional purposes and template rendering.
* ''input'' elements (and ''select'' and other form elements) have some caveats:
* Their ''name'' attributes have underscores. These can't be changed without breaking serverside functionality, so don't change them in template customizations.
* Per HTML requirements, ''label'' elements operate based on the ''id'' attribute of the related input. For ease of implementation and because ''name'' and ''id'' values almost always match in most HTML, the ''id'' values for form inputs also have underscores, and are not prefixed with ''fc-''.
* Inputs should be selected (in javascript) using the ''name'' and ''value'' (if necessary) selectors, not the ''id'' attribute. Yes, theoretically IDs would be faster, but selector speed isn't really a concern at this point with modern browsers.
=== CSS Class and ID Naming Principles with BEM ===
To help make the base FoxyCart theme easily modifiable, we've adopted the [[http://bem.info/method/definitions/|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.
[[http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/|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:
A product
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.
This will not only add the ''show'' class on error, but it will also //remove// the ''hidden'' class as well. When the error is cleared, it will toggle ''show'' off and toggle ''hidden'' on.
=== 2. Error bar updating ===
Once the field markup has been updated, FoxyCart updates the notifier bar at the top of the page to alert the user that a field has an error on it. This only occurs if the notifier bar is present. The markup for the bar is very simple, here's what it looks like in the default checkout template:
The ''data-fc-error-notifier'' attribute needs no value. Adding it to an element tells FoxyCart that all error messages should be added to this element. The ''data-fc-notifier-text'' attribute is optional, by default the message will be appended as a '''' element, if you wish to use a different text element, use the ''data-fc-notifier-text'' attribute.
When a message is sent to the notifier bar, it checks the length of FC.JSON.messages.errors, and if there are errors present, the bar updates the count and adds the classes "alert alert-danger." All appearance and animations are handled with CSS and can be defined/overridden in your custom style sheets.
{% block checkout %}
{# stuff goes here #}
{% endblock checkout %}
If you haven't done any customizations inside the ''checkout'' block (like if you're using ''%%{{ block("checkout") }}%%''), this is already present. Unless you're doing major customizations, you won't have to worry about this.
* Twig filenames are ''partial.context.inc.twig'', like ''address.checkout.inc.twig''. The ''context'' piece is optional.
===== Making It Easy: AutoMagiCache =====
TODO: add detailed walkthrough for 2.0 customization path.
===== Caching Assets Manually =====
If for some reason you don't want to use AutoMagiCache to do things automatically, you can securely cache your ''http'' images on our server (''https'') by calling them like this:
https://YOURDOMAIN.foxycart.com/cache.php?url=http://example.com/path/to/image.gif
Please note that this will //only// work on your cart, checkout, and receipt pages. Again, this is done automatically if you cache your template using AutoMagiCache, so you only need to do this if you're not caching your template.
===== Getting Even More Advanced with Twig =====
If you'd like to customize your templates beyond what you can do with HTML, CSS, and JavaScript, FoxyCart allows you to use the [[http://twig.sensiolabs.org/|Twig template language]] as well. Twig is flexible template language that's either near identical or relatively similar to a variety of other template languages. This functionality is very advanced, and most users should be able to achieve very very seamless visual integrations without this. If you have super specific needs, however, you can dig into Twig.
==== Where Twig Is Used in FoxyCart ====
Twig is used in all FoxyCart templates:
* The cart in all forms (HTML cart on the cart page, on the checkout and receipt, and on both HTML and plain text emails)
* The checkout
* The receipt
* The email receipts (both HTML and plain text)
==== Using Twig with FoxyCart ====
=== Understanding Twig ===
The first step is to review the [[http://twig.sensiolabs.org/doc/templates.html|Twig for Template Designers]] at the official Twig site.
=== Twig + FoxyCart ===
By default, you won't see any Twig syntax if you select the normal templates to start from. If you'd like to see the details of what's going on you can select the "Twig" templates (with the radio buttons) for the template you're modifying. That will show you a bit more of Twig, like this (for the checkout):
{% include 'svg.inc.twig' %}
{% import "utils.inc.twig" as utils %}
{% use 'checkout.inc.twig' %}
{{ block('checkout') }}
{# etc... #}
That might look complicated, but the basic idea is that each of the ''%%{{ block('foo') }}%%'' tags loads a ''block'' from the ''checkout.inc.twig'' template, which is loaded via the ''use'' command. This view gives you the ability to move elements around pretty easily without needing to get //super// involved with giant chunks of HTML. It also allows you to override just specific portions of the HTML without needing to edit the entire massive template. (It's also really helpful for understanding the different elements and logic, even if you do end up using one of the full templates below.)
If, however, you do want more control, you don't have to use the ''block'' and ''use'' method, and you can instead just start with the underlying default template and customize from there. You can fork the Github repo here: https://github.com/FoxyCart/2.0-templates and include them directly in your website application. This will allow you to easily merge in any changes we make into your customizations, especially as you upgrade from one version to another.
If you use any of the above linked files as a starting point, you can insert that raw Twig+HTML directly into your FoxyCart template (either directly in the admin or in your own templates for use with AutoMagiCache).
=== Customizing the Cart ===
It's important to understand that there are two "cart" templates. There's the "full" cart template, which is what displays if you pull up ''your_store.foxycart.com/cart'', used for full-page cart displays as well as the iframe in the default Colorbox cart. But there's also the cart that's displayed on the checkout, the receipt, and the email receipts. The "full" cart uses the "cart include" cart, just as the other templates do. So if you want to make a change to the cart system-wide (across the full cart, checkout, receipt, and email templates), you can edit the "cart include."
=== Allowed Twig Tags and Functionality ===
At present, the only allowed functionality for Twig is as follows:
* Tags: ''if'', ''for'', ''include'', ''macro'', ''block'', ''set'', ''import''
* Filters: ''abs'', ''number_format'', ''escape'', ''raw'', ''length'', ''date_modify'', ''replace'', ''upper'', ''lower'', ''title'', ''trim'', ''date'', ''url_encode'', ''keys''
* Functions: ''block'', ''date'', ''template_from_string''
===== Default Template Styles =====
As of v2.0, We've included a full responsive default theme which works on desktops, mobile devices and tables. We recommend using this team for the best customer checkout experience possible.
===== AutoMagiCache Technical Details =====
==== What It Does ====
- Pulls in target URL.
- Strips any