Subbly Theme & Template Documentation


Introduction

Template Engine Version: 1.1.

This documentation explains how the Subbly themes and template engine works, and how to develop your own themes. What variables & functions are avaialble and more.

Change Log

2015-1-5 (1.1)

We added the css_url() function.

Overview

Themes on Subbly are comprised of 4 main components:

  1. Templates: HTML and CSS template files which are Twig enabled which allows utilising the available variables, arrays, objects and functions within your templates.
  2. Options: An editable HTML form which allows changing variables which are usable in the templates.
  3. Assets: You can upload and link to assets from within the template editor functions.
  4. Data arrays & objects: There are a number of open accessible variables within arrays and objects which can be accessed using Twig in the templates.

Twig Language

Subbly templates are powered by Twig. We thoroughly recommend referring to the Twig for Template Designers Documentation to fully understand the syntax and what you can do with the Twig language. It explains clearly the usage of variables, functions, filters, includes and more. The Twig language is very powerful and allows for a whole lot of flexibility for you to create impressive beautiful themes for your subscription shop.

How To Create A Theme

Creating a new blank theme is super easy. Just go to admin/themes/ and scroll to the "Create a Blank Theme" form and choose a name. A default boilerplate theme will be created under this name for your shop and you will see it appear in the list of themes which you can then edit and activate.

Requirements

There are a few necessary requirements for a fully functional and working Subbly Theme:

  1. The theme must have the following files & pages:
    • Home page - index.html
    • Product page - product.html
    • Blog - blog.html
    • Blog post - blog-single.html
    • Page - page.html (default)
      • Please note you can create more custom page templates by using the prefix "page-" for the html file name.
    • Styles - style.css
  2. If using forms to submit the product to the checkout, form must include the form_token() function in the form html. This function produces a CSRF token for security. Without it your product submission form won't work. Please note: A form for buying a product is only necessary if you're wanting to submit options to the checkout to keep the product options / customisation experience on the merchants own site (if the product has options) rather than in the checkout. Please refer to the function documentation.
  3. We strongly encourage you to use the asset_url() function to link to uploaded assets, this will prevent your asset links from breaking if we change the files destination which could happen. Please refer to the function documentation.
  4. Your HTML of course must be valid.

Blank Page Templates

Subbly allows merchants to publish static pages. The default page template for this is page.html however you can give the choice of multiple templates to the merchant / admin. To register a page as a recognised page template simply append the file name with "page-" and use dashes for spaces.

Assets

The assets section is relatively straight forward. You simple choose a file (providing it's allowed) and then you can delete as well.

Activating a Theme

The admin / merchant can activate and deactivate a theme at anytime. This is very easy to do in the /admin/themes section. This could be used to allow version control of themes or simply by creating a maintenance theme if you wanted to make changes and not show the live site.

Theme Options

Theme options allow the admin / merchant to change variables that are used in the theme & templates without needing any programming or HTML/CSS/JS knowledge.

There are 2 main components to the theme options:

  1. There is an HTML form which defines the variables by the input element names accessed via the Design > Theme Options link in the navigation.
  2. Options object is accessible in the template engine through Twig.

Options Form HTML

This form can only be HTML and include only the following elements: <input><select><option><textarea><br><table><tr><td>
<thead><th><tbody><tfoot><p><b><strong>
<h1><h2><h3><h4><h5><i><hr>
<div><label>

We recommend using a <table> to make the form easy to view for the merchant. Bonus: You can use the Bootstrap class names as we use Bootstrap in the admin interface.

Please ensure that whatever approach you use, that the form is easy to use and cross browser friendly

Options Variables

The variable names of options are accessed in the options object via Twig. For example: You have an input <input name="header_color" value="" /> this can be accessed in the template as {{ options.header_color }} but please note you may need to handle default values, See Twig Default Docs.


{{ options.foo|default('foo item on var is not defined') }}
          

Changing Options

Please note deleting options inputs / variables from the form will not delete them from the object. They will still be accessible. We're looking into improving this but you simply don't need to call the variable.

Variables in CSS

Yes! We have enabled the access of Twig functions and variables in any .css file (not uploaded as an asset). This means you can use Theme Options and even product variables as class names etc. Please Note that the syntax highlighting when Twig is used in style.css displays the Twig syntax as incorrect but it still saves and compiles correctly. The array of objects available in .css files are the same as those in index.html.

Please note: Any additional CSS files (Not the default style.css) that you have created (and not uploaded to assets) must be linked to via the {{ css_url('file.css') }} function.

Arrays And Objects

Index

Here is an example array you will be able to access via Twig for index.html

This will be the same object that all other pages will receive as the basic Array.

Because it's so big we won't repeat it for the other pages. Instead we will list the differences for each of the other pages.

The array in PHP would look like this:


    array(
          "shop" => $shop, 
          "products" => $products, 
          "navigation" => $navigation, 
          "options" => $options, //Theme Options
          "theme_stylesheet" => $theme_stylesheet, 
          "domain" => $domain, 
          …
          );

[
  {
      "shop": {
          "name": "Test Shop",
          "country": {
              "name": "United States",
              "code": "US",
              "currency_name": "US Dollars",
              "currency_symbol": "$",
              "currency_code": "USD",
              "currency_html": "&#36;"
          },
          "theme": "1"
      },
      "products": [
          {
              "id": "1",
              "price": "00.00",
              "name": "Product Sample",
              "description": "This is a product description",
              "options": [
                  {
                      "id": "opt_9354597c1d67b63",
                      "name": "This is a select option",
                      "type": "select",
                      "required": true,
                      "values": [
                          "Option 1",
                          "Option 2",
                          "Option 3"
                                ]
                  },
                  {
                      "id": "opt_1554597c1d6997f",
                      "name": "Multiple Choice",
                      "type": "multiple",
                      "values": [
                          "Option 1",
                          "Option 2",
                          "Option 3",
                          "Option 4",
                          "Option 5"
                      ],
                      "required": true,
                      "limit": "4"
                  },
                  {
                      "id": "opt_1354597ed4e19af",
                      "name": "Text Input",
                      "type": "text",
                      "required": false,
                      "more_info": "More info about the text input"
                  }
              ],
              "images": [
                  "/path/to/product/image.jpg"
              ],
              "billing_frequency": {
                  "name": "Weekly"
              },
              "delivery_frequency": {
                  "name": "Monthly"
              },
              "url": "http://domain.com/product/product-slug",
              "checkout_url": "https://www.subbly.co/checkout/buy/1"
          },
          {...},
          {...}
      ],
      "theme_stylesheet": "http://domain.com/assets/themes/css/rendered/8/style.css",
      "shop_domain": "http://domain.com",
      "login_url": "https://www.subbly.co/checkout/login",
      "options": {
          "color_of_header": "#fff",
          "footer_copyright": "Copyright",
          "img": "2014-03-28_09.38_.58_.jpg",
          "checkbox_array": [
              "option_1",
              "option_2"
          ]
      },
      "navigation": [
          {
              "title": "Home",
              "url": "http://domain.com/",
              "current": true
          },
          {
              "title": "Blog",
              "url": "http://domain.com/blog",
              "current": false
          },
          {
              "title": "Test Page",
              "url": "http://domain.com/this-is-a-test-page",
              "current": false
          },
          {
              "title": "Test product",
              "url": "http://domain.com/product/test-product",
              "current": false
          }
      ]
  }
]

Product

Same as index but in addition, the product object for the current page is not included in the array of products but is instead an object in the main array accessed through product as it's the current product.

Example:

        
  "products": […],
        "product":{
                "id": "1",
                "price": "00.00",
                "name": "Product Sample",
                "description": "This is a product description",
                "options": [
                    {
                        "id": "opt_9354597c1d67b63",
                        "name": "This is a select option",
                        "type": "select",
                        "required": true,
                        "values": [
                            "Option 1",
                            "Option 2",
                            "Option 3"
                                  ]
                    },
                    {
                        "id": "opt_1554597c1d6997f",
                        "name": "Multiple Choice",
                        "type": "multiple",
                        "values": [
                            "Option 1",
                            "Option 2",
                            "Option 3",
                            "Option 4",
                            "Option 5"
                        ],
                        "required": true,
                        "limit": "4"
                    },
                    {
                        "id": "opt_1354597ed4e19af",
                        "name": "Text Input",
                        "type": "text",
                        "required": false,
                        "more_info": "More info about the text input"
                    }
                ],
                "images": [
                    "/path/to/product/image.jpg"
                ],
                "billing_frequency": {
                    "name": "Weekly"
                },
                "delivery_frequency": {
                    "name": "Monthly"
                },
                "url": "http://domain.com/product/product-slug",
                "checkout_url": "https://www.subbly.co/checkout/buy/1"
            }
        }

Blog

Same as the index array, but there is also a new array of blog posts in the main array like the following:


  "posts": [
            {
                "title": "Blog Post",
                "description": "Description of post",
                "content": "Post content which can contain HTML",
                "created_on": "1414633604",
                "edited_on": "1414633604",
                "url": "http://domain.com/blog/blog-post"
            },
            {}
        ]

Blog Post

Same as the index array, but there is also a new object with the blog post information called post in the main array like the following:


  "post": {
            "title": "Blog Post",
            "description": "Description of post",
            "content": "Post content which can contain HTML",
            "created_on": "1414633604",
            "edited_on": "1414633604",
            "url": "http://domain.com/blog/blog-post"
        }

Page

Similar to the blog post array:


  "page": {
            "title": "This is a page",
            "template_name": "page-custom.html",
            "description": "Page description",
            "content": "<h2>Introduction</h2><p>This is a page</p>",
            "created_on": "1414023674",
            "edited_on": "1414632918",
            "url": "http://domain.com/this-is-a-page"
        }

Product Options

You may have noticed in the product object that there is a $array['options'][] array. This is important. Merchants can specify questions which their customers can ask or rather, customers can personalise their product. There are 3 types:

  1. Select: One choice is allowed use a <select> or radio.
  2. Multiple: This allows the customer to choose multiple options. Note the merchant can add a limit please honour this by using javascript to validate client side if this exists. We validate on the checkout as well. We recommend using <input type="checkbox">.
  3. Text: This allows the customer to input text to answer questions like "What is your hobbies?". We recommend a <textarea>.

The merchant can also specify if a field is required or not.

Submitting Product Options

As mentioned above in the requirements. You can simply link to the checkout for the product and it will ask for the customer to fill out their choices as the above rules. However for a better experience we recommend using a form to POST the options to the checkout.

Example <form>:

Coming soon... or look at an existing recent theme.
          

Requirements

  • The option inputs must be built as an array, e.g. <input type="checkbox" name="options[{{ product.options[1].id }}][values][]" value="{{ value }}" />.
  • There needs to be hidden fields for each option with the name and type for validation of the options submitted. See example.
  • The URL for the POST should point to the product URL e.g. https://www.subbly.co/checkout/buy/1.
  • Front end javascript validation for required and limit (only applies to multiple type option).

Navigation Array

You may have noticed there is an navigation array in the array shown for index.

The admin/merchant has the ability to choose the pages, posts, products and core pages which are shown on the navigation of their subscription shop. This is passed as navigation and can be looped and you can use this to produce the navigation.

Subbly Functions

Function Name Parameters Returns
asset_url() (string) $filename (string) $url
css_url() (string) $filename (string) $url

Questions

If you have any questions please ask support, we want to make the process of making themes as easy as possible.

Copyright

Copyright © 2015 Subbly