Customizing your template is easier than you might think. If there's one takeaway from this page, it should be that FoxyCart's AutoMagiCache makes getting a customized template easy. Really, we promise. No template language to learn. Just your own HTML and CSS, securely cached. So don't be afraid, and do customize your template!
Setting up a customized checkout template in FoxyCart is about as easy as it can get, thanks to AutoMagiCache. But it's also radically different than you're probably expecting. Here's a quick guide to setting up your template to seamlessly integrate FoxyCart into your existing site design.
The idea here is that you're going to create a page on your site with “placeholders” where the FoxyCart functionality will go. You should know enough HTML and CSS to be comfortable editing code in order to make this happen, though if you're still learning and are using a WYSIWYG like Dreamweaver the basic ideas still apply. Once this page is created and uploaded/published on your site, you'll enter that URL into your FoxyCart admin, and FoxyCart will grab your code, work some magic (seriously), you'll be good to go.
Nearly every piece of HTML that FoxyCart presents to your customers is configurable in a template for your store. There are individual templates for:
While you can certainly use the default templates, we will see just how easy it is to use your own site's design for your FoxyCart templates.
If you don't want to bother with the technical details yet, take four and a half minutes to watch an explanation of AutoMagiCache in action. (Thanks to our good friend at My619.com for the screencast.)
<flashplayer width=962 height=721>file=http://static.www.foxycart.com/video/screencasts/checkout_template_creation2.flv</flashplayer>
cart
placeholder before the checkout
placeholder, but you don't need to display the cart
on your checkout page if you don't want to. (It's probably a good idea though.)^^cart^^
^^checkout^^
</head>
tag:<link rel="stylesheet" href="https://^^store_domain^^/themes/standard/styles.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="https://^^store_domain^^/themes/text/styles.css" type="text/css" media="screen" charset="utf-8" />
http://YOURDOMAIN.foxycart.com/cart?name=blah&price=10&cart=checkout
What follows is a brief recommended approach to advanced template customizations, followed by a two part screencast series illustrating the technique.
This tutorial requires:
foxycart.com
will automatically be updated when you change versions.Watch the screencasts below to see this approach in action. Even if you're a CSS Ninja, you may pick up a trick or two. And if you have additional tips or tricks feel free to add a comment. (This is a publicly editable wiki because we value the feedback of our users.) Click the links below to load the video.
http://static.www.foxycart.com/video/screencasts/FoxyCart_Modifying_the_checkout_page_part1.flv 997,764 noAutoPlay
http://static.www.foxycart.com/video/screencasts/FoxyCart_Modifying_the_checkout_page_part2.flv 997,764 noAutoPlay
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.
If you'd like to customize your templates beyond what you can do with HTML, CSS, and JavaScript, FoxyCart allows you to use the 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.
Twig is used in all FoxyCart templates:
The first step is to review the Twig for Template Designers at the official Twig site.
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):
{% if error_codes|length > 0 %} {% include 'checkout_error_template.twig' %} {% else %} {% if not is_updateinfo %} <div id="fc_checkout_cart"> {% include 'cart_template.twig' %} </div> {% endif %} {% use 'checkout_template.twig' %} {% block checkout %} <div id="fc_checkout_container">{{ html_messages|raw }} <form id="fc_form_checkout" method="post" action="{{ post_url }}" onsubmit="return false;"> {{ block('checkout_error') }} {{ block('required_hidden_fields') }} {{ block('continue_shopping') }} {{ block('noscript_warning') }} {{ block('login_register') }} {% if not is_subscription_cancel %} <div id="fc_data_entry_container"> <div id="fc_customer_info_container"> {{ block('customer_billing') }} {% if not has_multiship %} {{ block('customer_shipping') }} {% else %} {{ block('multiship_shipping') }} {% endif %} </div><!-- #fc_customer_info_container --> {# etc... #}
That might look complicated, but the basic idea is that each of the {{ block('foo') }}
tags loads a block
from the checkout_template.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. These links will show you the Twig templates from which you can start from:
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).
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 “partial” 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 “include” cart. There's an extra checkbox on the “cart” template page in your FoxyCart admin now, and if you'd like to use that (in any of your other templates) you can access your customized cart via {{ custom_cart }}
instead of the normal {% include 'cart_template.twig' %}
syntax.
This would allow you to use the default cart HTML in some situations, and your custom cart in others (like on a minimalist email receipt, etc.).
At present, the only allowed functionality for Twig is as follows:
if
, for
, include
, macro
, block
, set
escape
, raw
, length
, money_format
, pad
, replace
, upper
, lower
, title
, trim
, date
, date_modify
block
, date
As of v1.1, there are two included themes.
*.jpg
, *.jpeg
, *.png
, *.gif
) to use FoxyCart image caching./ /
with \/\/
when not preceded by a space or line break.</
with <\/
.<img>
paths to use FoxyCart image caching.<a>
paths to point to the correct locations.<form>
actions to point to correct locations.rel
attribute is after the href
attribute. This one is weird, and shouldn't be a problem (the regex is perfect), but if you have <link>
elements that aren't being cached, switch the order of the attributes and put the rel=“stylesheet”
before the href
attribute.src=“foo/bar”
or src='foo/bar
'.<meta http-equiv=“Content-Type” content=“text/html; charset=utf-8”/>
.swf
file, there's no good way to ensure that additional necessary files (like xml
, flv
, etc.) are cached along with the swf
file itself.../foo/bar.ext
) more than one level deep are not supported. ../foo/bar.ext
will work, but ../../foo/bar.ext
will not. If you have a legitimate need for more than one level deep, let us know.@IMPORT
rules more than one level deep are not supported. An import will work just fine, but an import inside an import won't be cached. If you have a legitimate need for more than one level deep, let us know.*.foxycart.com
subdomain.Google fonts work great because they can be referenced via https. The cacher doesn't download font files, though, so if you really need a custom font, it will have to be embedded manually in the page. FontSquirrel can help with this. (ref)
Twig has a hard time with some Javascript files (Modernizr in particular) because of some characters inside the parsed JS file that Twig reads as actual twig comments. To fix this, you can either put
{% raw %}
and
{% endraw %}
around your javascript includes or you can simply edit the file in particular to change
{#
to
{ #
and
{{
to
{ {
For some reason, Firefox and Internet Explorer may have problems when you have the ampersand (“&”) character inside of code comments:
<!-- Some text & more -->
This issue may be related to your doctype, so if you encounter this please let us know.
If you utilise conditional style blocks to target just a particular browser (like Internet Explorer), AutoMagiCache will currently trip over if that is the last style tag included in your <head>
section. Simply including a style tag after it will correct this issue:
<!--[if IE 6]> <style type="text/css> /* IE specific css */ </style> <![endif]--> <style type="text/css> /* Blank style */ </style>
The following placeholders will be replaced with “spaced” placeholders in cached CSS and JS, to prevent problems with parsing placeholders that shouldn't be parsed.
^^cart^^
→ ^^ cart ^^
^^checkout^^
→ ^^ checkout ^^
^^receipt^^
→ ^^ receipt ^^
^^analytics_google^^
→ ^^ analytics_google ^^
^^cart^^
^^store_domain^^
mystore
then ^^store_domain^^
will be replaced with mystore.foxycart.com
. For stores with custom subdomains, it returns the entire custom subdomain, such as secure.example.com
.^^store_name^^
^^checkout^^
^^cart^^
^^store_domain^^
^^store_name^^
^^custom_begin^^
^^custom_end^^
^^multiship_custom_begin^^
^^multiship_custom_end^^
^^custom_begin^^
and _end
placeholders above, but are used for per shipto custom fields, when using multi-ship.Note: the entire receipt template is optional. You can just use the checkout template if you like.
^^receipt^^
^^checkout^^
may also be used, and behaves identically to ^^receipt^^
.^^cart^^
^^store_domain^^
^^store_name^^
All analytics and order tracking scripts should be placed inside of ^^receipt_only_begin^^
and ^^receipt_only_end^^
tags. If tracking scripts are not placed within these tags they could be loaded multiple times, causing the data collected to be inaccurate.
^^receipt_only_begin^^
^^receipt_only_end^^
^^order_id^^
^^subtotal^^
^^subtotal_with_tax^^
^^order_total^^
^^analytics_google_ga_async^^
_addTrans()
, _addItem()
, and _trackTrans()
for the asynchronous Google Analytics approach, outlined here.^^analytics_google_ga^^
^^analytics_google_urchin^^
All of the following placeholders have separate outputs for HTML and text based emails. Some of what these placeholders output can be modified in the “language” section of your FoxyCart admin.
^^receipt^^
^^checkout^^
may also be used, and behaves identically.^^cart^^
^^order_id^^
^^receipt_url^^
^^store_domain^^
^^store_name^^
^^store_logo^^
^^order_begin^^
^^order_end^^
update_info
or sub_cancel
(subscription cancellation).^^subscription_cancel_begin^^
^^subscription_cancel_end^^
sub_cancel=true
).^^subscription_modification_begin^^
^^subscription_modification_end^^
sub_token
is used in a manually processed transaction.^^sub_token_url^^
sub_token
URL.^^updateinfo_begin^^
^^updateinfo_end^^
update_info
request (and not a normal transaction or a subscription cancellation).