Help & Documentation

 

Template Language


 

Introduction

The Solid template language is the language you will be using to quickly build custom templates for your store. There is no need to learn or know PHP, Ruby or any other programming language, although you will be using simple programming concepts like "loops" in your templates.

For those that already are familiar with simple PHP, ASP.NET, Ruby or any other programming language, our syntax will be super simple. For those new to programming we have kept everything as simple as possible and we are keeping documentation up to date at any time to make building templates a fun and easy to learn process.

If you need help, shoot us a message on Twitter, Facebook or via email.

back to top

 

How themes are structured

You'll be up in running in no time once you know the basics of how themes are structured. Take a look at any of the available themes under the "Design" tab of your store. You will see a list of available template files once you click "customize" on a theme.

We have structured our documentation in the same way that your themes are structured. The following template files can be found in any theme. When searching for help for a specific template, you can find the necessary information grouped in the same way in these help files.

Template File Usage
cartYour shopping cart
categoryShow products by category
indexThis is the homepage of your store
pageTemplate to display page details
productTemplate to display details about a product
searchSearch results

back to top

 

Syntax

The best way to start building custom themes for your store is by skimming through our syntax examples.

This example will render an unordered list with all categories you have in your webshop like "dvd series", "movies", "dvd-r", ... We can use this same loop technique whenever we want to display multiple items like products or pages.

back to top

 

Comments

You can use comments within the template language, to clarify the code you have written. Use {# ... #} for that.

back to top

 

Variables

The SolidShops template language makes a difference between setting a variable and getting the contents from a variable. In the example below, we first declare a variable named "myname" and put the value 'Earl' in it (the quotes are just there to mark the variable as being a string.

On the second line, we print the value of variable myname by using curly braces. Note the difference in syntax when declaring a variable and when reading it out.

If you want, you can also put whole chunks of HTML in a variable.

A variable can also contain attributes, just like an array in any programming language. To access attributes of a variable use a dot (.).

As we said earlier, the curly braces in the example above are only there to print out the variable, they are not part of the variable name itself.

back to top

 

Arrays

Arrays can be created as follows:

If you want to create a multi-dimensional array, you can do that as well:

back to top

 

Control Structures (for, if, else)

To control the flow of your templates, you can use conditionals or loops. Control structures are always placed inside {% ... %} blocks.

To loop over each item in a collection or array, use a for loop.

Example: loop over numbers

Example: loop over letters

Inside a for loop, you can make use of special variables if you need them. The following variables are available:

Variable Description
loop.index The current iteration of the loop. (1 indexed)
loop.index0 The current iteration of the loop. (0 indexed)
loop.revindex The number of iterations from the end of the loop (1 indexed))
loop.revindex0 The number of iterations from the end of the loop (0 indexed)
loop.first True if first iteration
loop.last True if last iteration
loop.length The number of items in the sequence
loop.parent The parent context

If there are no elements to loop over, you can show alternative content by using an "else" block.

Use the "if" structure to check a variable against a given value.

Use "if" to check if a variable is available, not empty or not false.

back to top

 

Logic

You can combine multiple expressions in if statements or for structures:

  • and: Returns true if the left and the right operands are both true.
  • or: Returns true if the left or the right operand is true.
  • not: Negates a statement.

back to top

 

Built-in Tests

The following is a list of built-in tests that you can use:

  • divisibleby: checks if a variable is divisible by a number
  • even: checks if a variable is an even number
  • odd: checks if a variable is an odd number
  • defined: checks if a variable is defined
  • empty: checks if a variable is null, false or an empty string

back to top

 

Expressions

Expressions can be used just like you would use them in PHP or similar languages. The following expressions are available:

 

Filters & Functions

Filters and functions are useful when you want to manipulate variables or values in a certain way. Examples can be converting text to UPPERCASE or formatting a date to a certain format. The following filters can be used in your templates:

capitalize

Convert the first letter of the string to uppercase. All other letters are lowercase.

char_limit

Limit the number of characters to print from a given variable.

currency

Format a number to a currency format of your liking.

The currency filter has several formats that you can use:

cycle

Use the cycle function to cycle between values in an array, based on a counter.

The array can contain as much values as you like:

Note that it can be easier to just loop over an array the standard way:

date

Format a date to a given format.

escape, e

The escape or e filter converts occurences of characters &, <, >, ', and " in strings to their HTML-safe equivalents.

explode

Convert a string into an array based on a delimiter

excerpt

If a user has used the "insert more break" button to define an excerpt in a product or page description, we can show only the excerpt instead of the full description by using the excerpt filter.

json

Convert a data object into Javascript Object Notation (JSON)

length

Returns the length of a string or the number of items in a sequence or collection (of products for example).

You can use this in many situations such as counting the number of images a product has in an IF-statement:

lower

Convert the string to lowercase.

random_number

Generate a random number (between two numbers).

reverse

Revert an array.

sort

Sorts an array.

string_replace

The string_replace function replaces all occurences of a string with a new string.

strip_tags

Strips the html and xml tags from a string.

strip_whitespace

Strips all excess whitespace (new lines, tabs, double spaces) from a string.

title

Convert the first letter of every word to uppercase. All other letters are lowercase.

upper

Convert the string to uppercase.

url_encode

Encode a given URL

weight

Format a weight to a format of your liking.

trim

returns a string without the whitespaces at the beginning and end

 

URL Segments

The Solid template language lets you access all data segments in a given URL. Let's take a look at the following URL:

By segments we mean everything that appears after your domain name, in this case "category" and "computers". Accessing these segments can be done as follows:

That will get you "category", the first segment after the domain name. To grab "computers" from the url, you simply do the following:

 

Loading CSS Files

First, create a CSS file by clicking on the "add new file" button.

Once you have created and populated a CSS file, you can link it in your theme by using solid.css() as follows:

The function above will generate the following result in your template:

The solid.css() function takes two arguments:

Argument Value Description
1 filename(s) the filename(s) you are loading
2 media standard css media types like "screen" or "print"

Example 1: generate stylesheet link for screen.css.

Example 2: load file reset.css and screen.css (in that order) and put the media attribute to "screen"

An alternative way to link CSS files is by uploading them with the "assets manager" and just linking them with normal CSS code as you would normally do in HTML.

If you want to upload CSS files (or other files) e.g. when using a jQuery plugin that has a uses a number of files, you can do so like this:

After clicking the "manage my assets" button on the right side of your screen, you can organize your assets in any way you want. Create subfolders for CSS, Js, images, ... if you want and upload the files to the location of your preference. In this example, we'll just upload a CSS file in a folder called CSS.


Now that you have uploaded an asset to your assets folder, you can link to it in the same way you are used to build html templates. Just make sure you include a reference to your assets folder {{ solid.assets_url }}.

back to top

 

Loading JavaScript files

Loading JavaScript files works in a similar way as loading css files. Call the function solid.js() and pass in the name of the file you want to load as a parameter, like this:

Argument Value Description
1 filename(s) the filename(s) you are loading

This will result in the following in your template:

Example: load multiple js-files at once

This will output two links to your javascript files:

If you rather want to upload your JavaScript files to your assets folder and link to them, please read the section above about loading CSS-files. The process for linking JavaScript (or any other file) is the same as described above.

back to top

 

Including/embedding partials

When you are creating templates, you will probably be repeating yourself over time. For example, it's common to have the same footer or header on every template. You can save yourself some work by creating an include file for pieces of your code that are repeated in more than one template.

If you want to create a footer and include it in your templates, do the following:

First, create a partial called "footer", which will include a little copyright notice that we want to reuse in all our templates.

Next, put some content in the footer partial and save the file.


Now you have created a partial that you can re-use anywhere in your templates. For example, we'll want to re-use the footer in our index template, our homepage.

At the bottom of our index page, we'll load or include the partial we just created.

You are not limited to use this for footers or header. We use the embed() method to embed the same CSS file in all templates or to use the Google Font API in all our pages. Be creative!

back to top

 

Products

The products template can be used to display details about a single product. The product tag can be used to access all information about your products or about one single product.

You can get the following data from any product in your store:

Attribute Description
always_available returns true if you have indicated that users can buy this product when it's out of stock, otherwise false. Also returns true if you are not tracking stock
id the unique ID of your product
description the product description
date_modified the date you last saved a product
name the name/title of your product
nicename the unique name of your product
price the price of the product
stock the actual stock count for this product, empty if stock tracking is disabled
tags the tags your entered for a product
thumbnail the thumbnail image of your product
track_stock returns 0 if you have disabled stock tracking , 1 if stock is tracked on product level, 2 when stock is tracked on variant level
url the url to point to the detail page of this one product (system template "product")
weight the weight your entered for a product
categories a loopable collection of all categories that are linked to a product
Each category contains the following attributes:
Attribute Description
name name of the category
url url to the category page
id the id of the category
nicename nicename of the category
variants a loopable collection of all variants that are linked to a product
Each variant contains the following attributes:
Attribute Description
id id of the variant
name name of the variant
options
Attribute Description
id id of the option
name name of the option
variant_combinations a loopable collection of all variants combinations that are used in the product
Each variant combination contains the following attributes:
Attribute Description
id id of the variant combination
name name of the variant combination
price price of the variant combination
stock stock of the variant combination
images a loopable collection of all images for the current product
Each image object contains the following attributes:
Attribute Description
thumbnail cropped thumbnail of the image (200pxx200px)
full the original image, compressed and optimized
original the original image, not compressed

back to top

 

Loop over multiple products

Take a look at the following example. product.getList() will load all your products, after which you can loop over them.

Note the use of {{product.url}} in the example above. When displaying a listing of products in your store, you can use the "url" property to get a URL in the following format: http://www.myshop.com/product/46/ipad/. This will link a product to its detail page. See the next chapter for more about loading a single product.

back to top

 

Load a single product

To display the details of a single product, you need to edit the "product" template and get the current product details. This can easily be accomplished as follows:

Instead of .name, you can now use any of the available product attributes.

Please note that the product.get() function normally requires a "nicename" parameter. When you are on the product template, on a url like http://demostore.solidshops.com/product/productname, we will automatically read out the nicename "productname" from your url.

If you want to, you can pass in the nicename of a product in the function product.get(nicename) like so:

back to top

 

Filter parameters

It's possible to limit the products that are loaded, to only products that are e.g. in a certain category or that have a specific id. You can define filters or options like this:

Then call the getProducts() function as usual, but pass the options, like this:

Available filter attributes

Filter Description
cat filter by category name or nicename - example: "cat":"apple" or "cat":"apples|bananas"
count the number of products on your screen or per page (if pagination is set to true) - example: "count":"10"
id get one or more products by id: example: "id":"1" or "id":"1|5|3"
nicename filter by product nicename - example: "nicename":"coffeecup" or "nicename":"coffeecup|cappucinocup"
tag filter by product tags - example: "tag":"red" or "tag":"red|green|blue" or "tag":"red,green , blue"
order id, name, price, datemodified, random - example: "order":"name", "order":"name:asc|datemodified:desc" or "order":"random"
pagination whether you want pagination or not - example: "pagination":"true" or "pagination":"false"
search filter by any give search term - example: "search":"pizza"

back to top

 

Custom fields

You can add custom fields to your products. See our documentation here for details on how to easily add custom fields to your products.

To read out custom product data in your store templates, you can do the following. Please note that the examples below will only work if you already have a field group with custom fields linked to your products.

Load a product, just like you would normally do. Then, you can loop over all custom fields that are linked to a product, like so:

This will loop over all available custom fields and fields in a standard Key-Value array loop. The following screenshot gives you a visual representation of how the custom fields are structured.

If you don't want to loop over all your custom fields but need quick access to just one of your custom product fields, you can do the following:

If you don't want the value but the field label, use .label:

back to top

 

Pagination

If you have e.g. 50 products in your store and want to show them per 10 on a page you can use the pagination object. For pagination to work, you need to set the "pagination" parameter to "true" when you load products. See the getProducts() function just above for that.

The pagination object has the following attributes that you can use.

Attribute Description
pagination.pages A loopable collection of all pages in the pagination object. This collection contains the following attributes:
Attribute Description
page.number the number of the page
page.url the url for this page
pagination.previous The number of the previous page. This variable is empty if there is no previous page.
pagination.previous_url The url to link to the previous page
pagination.next The number of the next page. This variable is empty if there is no next page.
pagination.next_url The url to link to the next page

back to top

 

Add product to cart

To add a product to your shopping cart, we need to create a small form tag with a submit button, per product. This concept can be used in the "page" system template for one product or even in a list of products.

The following is necessary to add a product to a shopping cart:

1. form with action="/cart/add/{{product.id}}
2. a submit button within that form

Please notice the reference to the product id you want to add to the cart. In the following example we have added a text field named 'quantity' to allow a user to select the quantity to add. If you don't add the quantity text field, 1 will be the default quantity to add to the cart.

The product id is available when loading products using either the product.getList() or the product.get() method.

When adding products that contain variants to your cart, you have to make sure you give your users the chance to select a certain variant. You could build select boxes automatically for your products variants using the following code:

The name of your select box is important. The name value should be in the format variant_1 where 1 is the id of the variant type.

back to top

 

Pages

The pages tag can be used to access all information about your pages or about one single page. You can get the following data from any page in your store:

Attribute Description
id the unique ID of your page
nicename the unique name of your product, often used in url's
name the name/title of your page
content the content of your page
date_modified the date you last saved a page
url the url to point to the detail page of this one page (system template "page")

back to top

 

Loop over multiple pages

Take a look at the following example. page.getList() will load all your pages, after which you can loop over them.

Note the use of {{page.url}} in the example above. When linking to a page, you can use the "url" property to get a URL in the following format: http://www.myshop.com/pages/46/my-page-title/. This will link a page to its detail page. See the next chapter for more about loading a single page.

back to top

 

Load a single page

To display the details of a single page, you need to edit the "page" template and get the current page details. This can easily be accomplished as follows:

Instead of .name, you can now use any of the available page attributes.

Please note that the page.get() function normally requires a "nicename" parameter. When you are on the page template, on a url like http://demostore.solidshops.com/page/pagename, we will automatically read out the nicename "pagename" from your url. If you want to, you can pass in the nicename of a page in the function page.get(nicename), like so:

back to top

 

Filter parameters

Filter attributes It's possible to limit the pages that are loaded, by limiting the amount of pages loaded or by limiting them by ID. You can define filters or options like this:

Then call the getPages() function as usual, but pass the options, like this:

Available filter attributes

Filter Description
nicename limit the pages you load based on nicename(s): "nicename": "about" or "nicename":"about|contactus"
count limit the number of pages you want to load: "count":"5"
order id, name, datemodified, random- example: "order":"name", "order":"name:asc|datemodified:desc" or "order":"random"
id get one or more pages by id: example: "id":"1" or "id":"1|5|3"

back to top

 

Categories

Attribute Description
id the id of your category
parent_id the id of the higher category
name the name of your category
nicename the url friendly nicename of the category
url the url to point to the detail page of this one category (system template "category")
subcategories a loopable collection of "category" objects

Available filter attributes

Filter Description
id limit the categories you load based on id(s): "id": "1" or "id":"1|4"
nicename limit the categories you load based on nicename(s): "nicename": "about" or "nicename":"about|contactus"
order id, name, random - example: "order":"name", "order":"name:asc|id:desc" or "order":"random"

Here's an example to get you on your feet quickly when looping over all your existing product categories. The following example could be useful when building a navigation menu.

If you are using subcategories, you can render these out as well, like so:

A much used technique is the following: image you have a "category" template where you show an overview of products in a certain category or subcategory. You can load the current category your user is browsing by adding the following line to your template:

We will automatically populate the category object with the details of that category, even when it's a subcategory. When you are browsing a subcategory "shirts", you can easily print out something like:

That's great, but for search engine rankings it can be a good idea to show the breadcrumb structure with the parent category info added to it as well, like this:

back to top

 

Load a single category

To display the details of a single category, you need to edit the "category" template and get the current category details. This can easily be accomplished as follows:

Instead of .name, you can now use any of the available category attributes.

Please note that the category.get() function normally requires a "nicename" parameter. When you are on the category template, on a url like http://demostore.solidshops.com/category/categoryname, we will automatically read out the nicename "categoryname" from your url. If you want to, you can pass in the nicename of a category in the function category.get(nicename)

back to top

 

Orders

The order variables are mostly used when customizing email templates to send out with every new order that comes in. See the code sample below for an example of how to use these variables.

Attribute Description
id the order ID
date_created the date at which the order was created
date_paid the date at which the order was paid, empty if the order is not paid yet
items_quantity the number of products in the order
items_subtotal sum of all product prices, excluding shipping and taxes
items_tax total taxes
items_total sum of all product prices, including taxes, excluding shipping
shipping_cost shipping cost for the order, excluding taxes on shipping costs
shipping_tax taxes charged on the shipping cost (if set in settings)
shipping_total total shipping costs, including taxes on shipping costs (if set in settings)
total order total, including all taxes and shipping costs
payment_text if you have added custom payment messages in your checkout settings page, we will load them up here, depending on the selected payment method your client has selected. If they have paid online and there is not custom payment text, we will leave this variable empty.
pdf_invoice the url of the pdf invoice document.
coupon object containing information about the used coupon
Attribute Description
code the used coupon
type the type of the coupon("cart_total" or "shipping")
discount the discount amount
attributes
Attribute: Description
thenameoftheattribute custom name of the attribute e.g. "note"
items a loopable collection of all items in the order
Each item contains the following attributes:
Attribute Description
id id of the order line item
product_id the id of the product
name name of the item
tax_percentage tax percentage linked to this item
price price per piece
quantity amount bought
subtotal quanity * price
tax taxes charged on subtotal
total total price for this item, including taxes
variants A loopable collection of all variants linked to an order item. This loop has to exist in the items loop.
Attribute Description
name name of the variant
value name of the variant
attributes
Attribute: Description
thenameoftheattribute custom name of the attribute e.g. "engraving"
customer object containing information about the customer that placed the order
Attribute Description
email customer email address
mailinglist contains 1 if user wants to receive promotional emails, 0 if not
billing
Attribute Description
first_name customer first name
last_name customer last name
address customer address
address2 customer address part 2 (empty if not entered)
city customer city
postal_code customer postal/zip code
country_code customer country code (e.g. CA, US, GB, ...)
region state or province
company company name (empty if not entered)
vat company VAT number (empty if not entered)
phone customer phone number (empty if not entered)
shipping
Attribute Description
first_name customer first name
last_name customer last name
address customer address
address2 customer address part 2 (empty if not entered)
city customer city
postal_code customer postal/zip code
country_code customer country code (e.g. CA, US, GB, ...)
region state or province
company company name (empty if not entered)
phone customer phone number (empty if not entered)

Here's an example of how you can build up a custom confirmation email by using the available variables for an order that a customer places in your store.

back to top

 

Shop

You can get general information such as the current currency, the home url, ... from you shop. There is no object "shop" so the syntax is a bit different than what you are used to. The following variables are available:

Attribute Description
shop_name the name of your shop
currency the selected currency for your shop
currency_decimal the decimal separator ( . or , )
currency_thousand the decimal separator ( . or , )
currency_symbol the symbol of the currency that is set in the backend
shop_url the url of you store, http://yourdomain.solidshops.com or www.customdomain.com depending on your settings
assets_url the url to your assets (images, files, ...). You can use this to build <img> tags, or in CSS to link to background images
products_count the total number of active products in your store

Example: create a home link

This will output:

Example: link to images and backgrounds in your assets folder

In HTML:

In CSS:

back to top

 

Cart

Just like you can loop over products, categories and pages, you can also render your shopping cart in any layout you want. Call the shopping cart data like this:

As you might have notice you can write anything you want instead of "cart". That's just a variable name. The cart will be filled with items, once somebody has added a product to the cart.

To loop over all items in your cart, you could do something like this:

Attribute Description
cart.items_quantity the total number of items in your cart
cart.items_subtotal cost for all items in your cart, not including taxes
cart.taxsetting "incl" or "excl" depending on your shop settings
cart.items_tax total taxes for the items in your cart
cart.items_total total cost for all items in the cart, including taxes
cart.shipping_cost shipping cost for the items in your cart, not including taxes on shipping (if set)
cart.shipping_tax taxes charged on shipping costs (if set)
cart.shipping_total total shipping cost for the items in your cart, including taxes
cart.total grand total of your shopping cart, including taxes and total shipping cost
cart.coupon_code If you accept discount coupons, this is the code a user has entered
cart.coupon_type If a user has entered a coupon code, this contains the type of discount e.g. "cart_total" or "shipping"
cart.coupon_discount If a valid discount coupon has been entered, this contains the actual discount value.
cart.attributes
Attribute: Description
thenameoftheattribute custom name of the attribute e.g. "note"
cart.items
Attribute Description
item.id the id of the item in the basket
item.name the name of the item/product
item.price item price (including/excluding tax depending on your settings)
item.quantity quantity added to basket for the current item
item.subtotal item price * quantity in basket
item.track_stock returns true if you have enabled stock tracking, false if you have disabled stock tracking
item.always_available returns true if you have indicated that users can buy this product when it's out of stock, otherwise false. Also returns true if you are not tracking stock
item.stock the actual stock count for this item, empty if stock tracking is disabled
item.url the url to your product
item.thumbnail the thumbnail of your items first image
item.tax_percentage the tax percentage linked to this product
item.tax taxes charged on subtotal
item.tax_setting "incl" or "excl" depending on your store settings
item.total total cost for this item, including taxes
item.variants (if used) - a list of variants, loop thought them as follows: Every variant has the following attributes:
Attribute Description
variant.name name of the variant e.g. "Size"
variant.value selected value for the variant e.g. "XX-Large"
item.attributes
Attribute: Description
thenameoftheattribute custom name of the attribute e.g. "engraving"

Here's a complete shopping cart example to get you started:

Please note the line where we have added a field with name="quantity_{{ item.id }}". When you name the field that way, SolidShops can automatically detect what product (and variant if you used one) you are changing the amount for.

If you want to give the user the opportunity to select his ship-to country, you can do this by calling the method solid.htmlShippingCountries(). This will roll out a list of available destinations to ship to, based on your shipping preferences.

back to top

 

Remove item from cart

Sometimes or even most of the times you may want to provide a "remove item" option in your shopping cart. We will need a form that posts the correct product ID that has to be removed, like so:

This link (or it can be an image, as long as it links to the correct url) needs to be available next to every item in your shopping basket, so you can e.g. put it in a table within your {% for item in cart.items %} loop.

back to top

 

Custom cart attributes

You can add up to 5 attributes to each cart item and 5 to the cart itself. These attributes are used to add some extra customer fields to the cart. Some implementations are fields like "customer engraving","cartnote","deliverydate".

item attributes:

For each item in your shopping cart you can define up to 5 attributes.

product / add to cart:

cart template:

cart attributes:

For each item in your shopping cart you can define up to 5 attributes.

cart template:

back to top

 

Search form

The search template file can be used to display search results in your store. Building a basic search form for your online store can be done as follows:

You can place this form anywhere in your store. It's important to use the correct action "/search" as we will post your query to your search template through the URL. Also make sure that your search text field has the attribute name="query" in it. That way we know where to get your search term.

When somebody searches for e.g. "apples" by submitting the search form above, the user will be redirected to e.g. http://yourstore.solidshops.com/search/computers

Now we need to build up the search results page, in the same consistent way we build up the products, pages and categories pages. You can find the "search" template in your theme files.

To build up a list of products that match the search term, first we need to get the search term from the url by using url segments. Take a look at the following example:

The example above gets url segment number 2 from our url http://yourstore.solidshops.com/search/computers. Now we have a search parameter "computers" which we pass to the products options.
If you want you can pass along more parameters to build in pagination or order products in a certain way. See here for more product filter attributes.

back to top

 

Contact form

Some stores require a custom contact form. You can build a contact form in any of your templates. Below is a fully working example of a contact form. Let's take a look at how it's been built and how it works.

You wil need the following to create a custom contact form:

  1. form action="/sendmail" method="post": this will process the form and mail it to your store's contact email address.
  2. input fields: use whatever and as much input fields as you need. Just make sure you give them a clear name tag.
  3. captcha tags: these are required to prevent spam robots from sending fake emails to you.

If you want to make some fields required, you can do so by using javascript.

In the example above, you can see that we check url segment 3 against the word "false". When a users submits your form, we check whether or not the captcha was correct. When correct, we send and email to the contact email address you provided in your general store settings and we will create a URL like http://yourstore.solidshops.com/contact/status/true. This way you can detect if your form was sent and inform your user about this action. If the form submission fails (because of a bad captcha), we will return a URL http://yourstore.solidshops.com/contact/status/false

back to top

The Solid template language uses parts of the Twig library.
Parts of this documentation page are based on the original Twig documentation and are attributed to them.