<ProTOM/>


Ready to help, versatile and powerful. That is ProTOM.
Develop you own theme using HTML, CSS, Javascript & Smarty.

Use smart code fragments, implement your own settings and start developing
unequalled layout themes today.
Get started with ProTom!
But first things first.
 

General

This module enables you to develop a template made-to-measure based on your own HTML, CSS and Javascript. It allows you to leave out traditional themes and widget layouts and develop a unique, conversion upgraded theme. Using this module will help you understand the phrases doctype declaration, semantics and cross browser compability . If you do not know what is meant by these phrases, it might be better to opt for the layout theme Enoza. .

Using your own HTML, CSS and Javascript
By allowing you to use your own HTML, CSS and Javascript you will be responsible yourself for the correct rendering of your webshop. Besides we are giving you a free hand to fit in the elements from the traditional widgets in a position where you want them. This makes you responsible for the correct implementation and functioning of these widgets.

Attention! In order to make sure your webshop will continue to function correctly after each update, it is vital that the content is not adapted by means of CSS and Javascript.

Implementation of webshop logic

Webshop logic? By this expression the technical functioning of ( certain parts of) the webshop is meant. For example the display of a bestseller list.

Webshoplogic can be implemented in various ways:

  • Variables (see tab List of variables).
  • Objects (see tab List of objects).
  • End user settings (see tab End user settings)
  • Multilingual variables (see tab Multilingual support)
  • AJAX widgets (see tab AJAX widgets)

All logic you will be able to use is Smarty-logic. Smarty is the underlying template system this module was built on. You can also consult the Smarty-website documentation for creating foreach-loops, sections and e.g. cycles. Besides you can adapt variable modifiers on variables containing textual content.

Code fragments

As stated, it is possible to implement logic yourself. To simplify this process, a number of code fragments are available. Code fragments can be found on the left in the middle of the module. By clicking on the code fragment, this fragment will be positioned in the code of the file Index.tpl on the spot where your cursor is or was the last time you moved it.

The documentation List of objects specifies for each object in which code fragment a specific object is available and in which variable.

Coding standard

OIn order to help you recognize the type of data your are dealing with in a variable, a certain coding standard was used. All variables have a batch character that specifies the data type of that variable. If you are using the code fragments, you will see that batch characters are also used to inform you which data type is implemented in a certain variable. Below list gives you an overview of the different batch characters and informs you which data type the variable contains.

Batch character Description
_ Logics, adapted for including files.
a Array.
b Boolean.
f Float.
i Integer.
m Mixed, the variable may contain several data types, depending on a result.
o Object.
s String.

Use of prefixes

In order to guarantee the compability with existing webshop logic, CSS-declarations and Javascript functionalities, the use of prefixes for all HTML-elements, CSS-declarations and Javascript functionality is strongly advised. A prefix may consist of any characters or letters you wish, e.g. the abbreviation of your company name combined with a year. This will prevent accidental double declarations. An example: Your company name is “Jansen Jeweler's “ : if you create your theme in 2013, your structure including prefixes may look like this:

<!DOCTYPE>
<html>
<head>
</head>
<body>
<div id="jj2013-header">
<img id="jj2013-logo" src="/logo.jpg"/>
</div>
</body>
</html>

Theme validiation system

This module has an automatic theme validation system. Every time the theme is filed, it is tested first by the validation system. Alterations will only be filed if the validation system does not detect fatal syntax errors. A ny syntax error is reported by the validation system so that the error can be solved. If the validation system does not discover any fatal syntax errors, the alterations will be filed.

As the validation system approaches the webshop invisibly, these tests will be included in your statistics. Each time the template is filed, the validation system will be activated.

Developing themes
Everything within reach, including example code.
 

Javascript functionalities

To keep the code clean, compact and orderly a number of javascript functions were made available. Naturally it is possible to add an extra functionality such as javascript functions and event handlers to Scripts.js or in the file Index.tpl.

EnterPressed()

Function that will check if the key pressed is indeed the “enter” key.

Get(string sDOMId)

Function that will select the value of an input field.

Parameter Datatype Description
sDOMId String The ID of the input field. E.g. <input type="text" id="SearchField" value=""/>

GoTo(string sLocation)

Function that forwards user to location indicated.

Parameter Datatype Description
Location String Location to which user is forwarded.

SubscribeToNewsletter(event)

Signing on a visitor to the newsletter by means of this method is outdated. Use the action hook SubscribeToNewsletter..

CSS declarations

PredefinedButton

To simply add a button in the selected style and colour, a span element with the declaration PredefinedButton should be implemented. This span is automatically converted to a stylized button.

Example
<span class="PredefinedButton" onclick="javascript:GoTo('{$sBasketPageDeeplink}');">shoppingcart</span>

List of variables

Variables are small pieces of code with a specific name ( the variable name) that represent a specific functionality. This functionality may vary from displaying a piece of text to loading the content modules of the webshops. Below you will find the available variables and their description.

Variables that load files

Variable Description
{$_IncludeHead} Include of global head data, Template.css and Scripts.js.
{$_IncludeContent} Include of the contentpage in question (homepage, category, guestbook, productdetails, order route etc. etc.).
{$_IncludeTail} Include of global tail-data, such as measuring pixels and statistics.

Variables in relation to URLS and file locations

Variable Description
{$sProtocol} Gives 'http://' or'https://' back depending on the reserved page.
{$sAbsoluteMediaLocation} Absolute path to the map to which the files were uploaded. HTP or HTPS is automatically specified depending on the reserved page.
{$sRelativeMediaLocation} Relative path to the map to which files were uploaded. This variable is meant for usage in the file Template.css to prevent security conflicts.
{$sCustomerLoginPageDeeplink} Link to the login page.
{$sCustomerLogoutPageDeeplink} Link that provides log-out if customer presses the “log-out” button.
{$sCustomerRegistrationPageDeeplink} Link to the registration page. This link is only available if the choice for the login system is switched on and registration is possible.
{$sCurrentPage} Gives back what type of page is reserved. Based on this several layout pages can be developed. This variable may contain following values:
  • HomePage, the welcome page.
  • TextPage, a textual page.
  • CategoryPage, a category page.
  • ProductPage, the product detail page.
  • NewsPage, the news page.
{$sSearchPageDeeplink} The URL to the search page. This variable should be used to forward your own search functionality to the right page. The search words entered should be added to this variable. The construction of SearchPageDeeplink} consists of {$sProtocol} + website main domain + '/website/index.php?Show=Search&KeyWord='.
{$sBasketPageDeeplink} The URL to the shopping basket. This variable should be used to forward a shopping cart overview developed by yourself to the correct page.

Settings

Variable Setting
{$bShowPricesToGuests} Setting: Show prices to guests
Location: Starting point/My webshop/Settings/ Loginsystems
Value: true of false.
{$bCustomerLoginActive} Setting: Users Login
Location: Startingpoint/My webshop/ Settings/ Loginsystems
Value: false if 'off', otherwise true.
{$sCustomerLoginSystemType} Setting: Users Login
Location: Startingpoint/My webshop/ Settings/ Loginsystems
Value:
- Inactive, loginsystem is off.
- ActiveWithRegistration, loginsysteem staat aan met de mogelijkheid tot registreren.
- ActiveNoRegistration, loginsysteem is on but no option of registering. Attentention {$sCustomerRegistrationPageDeeplink} does not contain a value.
- ActiveAutomaticRegistration, loginsysteem is on , after placing an order an account is created automatically.
{$sCurrency} Setting: Valuta
Location: Startingpoint/My webshop/Settings/ Order proces settings.
Value:
- USA, American Dollar
- CAD, Canadian Dollar
- DKK, Danish Crowns
- EU, Euro
- UK, English Pound
- RON, Romanian Lei
- SRD, Surinam Dollar
- TL, Turkish Lira
- SEK, Swedish Crown
- CHF, Swiss Franc

Ambient variables

Variable Description
{$sBodyLogic} Adds logic to the <body>-tag for processing the electronic payments . This variable should be used as follows: <body {$sBodyLogic}>.
{$sPageTitleH1} <h1>-tag for the current page. This variable structures the crumb path within the category structure and product detail page.
{$iSelectedCategoryId} Gives back the ID of the selected product category.
{$iSelectedSubCategoryId} Gives back the ID of the selected product subcategory.
{$iSelectedPageId} Gives back the ID of the selected page.
{$sResellerName} Gives back the name of the reseller.
{$sResellerDeeplink} Gives back the link of the reseller's website.
{$sPoweredBy} Gives back the reseller's HTML-code 'Powered by'.
{$bCustomerLoggedIn} Geeft aan met true of false of de klant is ingelogd.
{$sCustomerName} Gives back the customer name of the logged in customer.
{$fCustomerDiscount} Indicates the discount percentage of the customergroup of the customer. This variable only contains a value if the customer in question is in a customergroup.

List of objects

Blog

Objectproperties
Property Description
Title Title of blog item.
Content Textual content of blog item.
ImageDeeplink Link to the image that was added to the blog item.
Deeplink Link to the blog item.
CreateDate Date when blog item was created.
Author Author of blog item.
AuthorWebsiteDeeplink Link to author's website.
CommentCount Number of reactions to blog item.

Available in code fragment
Code fragment Variable Description
Last blogs {$aBlogs} An array of Blog-objects ( last 10).

Brand

Objectproperties
Property Description
Name Brand name.

Available in code fragment
Codefragment Variable Description
List of brands {$aBrands} An array of Brand-objects.

Crumb

Objectproperties
Property Description
Title Title of category or page.
Deeplink Deeplink to the category or page in question. Value of the last crumb is empty.

Available in code fragment
Codefragment Variable Description
Crumb path {$aCrumbs} An array of Crumb-objects.

Language

Objectproperties
Property Description
FlagIcon Deeplink to the standard flag icon, to be used in <img />.
Code Country code, two digits (ISO 3166-1).
Domain Domain of the language.

Available in code fragment
Codefragment Variable Description
Language flags {$aLanguages} An array of Language-objects.

NewsItem

Objectproperties
Property Description
Title Title of newsitem.
Content Content of newsitem.
Date Date of precessing.
Deeplink Link to news item.

Available in code fragment
Codefragment Variable Description
List of newsitems {$aNewsItems} An array of NewsItem-objects.

OrderRow

Objectproperties
Property Description
ProductNumber Product number/Article number.
ProductName Name of products.
Count Number of products. E.g. 2 if two identical products are in the shopping cart.
Tax VAT-value as integer. E.g. 0,6 or 21.
Unit Product unit.
Price Selling price (if a discount is applicable, it is deducted ) Examples values: 10, 10.1 and 10.95.
FromPrice The original price (if discount is applicable is will differ from Price) Example values: 10, 10.1 en 10.95.
Discount Discount on a product (if applicable) . Value contains discountvalue. Example values: 10, 10.1 en 10.95.
TotalPrice Total price of this product (Count * Price). Example values: 10, 10.1 en 10.95.
PriceFormatted Formatted selling price (if a discount is applicable is is deducted). Example values: 10,00, 10,10 en 10,95.
FromPriceFormatted Formatted original price (if a discount is applicable it differs from Price ). Example values: 10,00, 10,10 en 10,95.
DiscountFormatted Formatted discount on a product (if applicable). Example values: 10,00, 10,10 en 10,95.
TotalPriceFormatted Formatted total price of this product (Count * Price). Example values: 10,00, 10,10 en 10,95.
Deeplink Deeplink to product detail page.
MainImageDeeplink Deeplink to main image of product.
MainImageThumbnailDeeplink Deeplink to thumbnail of main image of product.

Available in code fragment
Codefragment Variable Description
Small shopping basket {$aOrderRows} An array of OrderRow-objects.

Page

Objectproperties
Property Description
Id Unique page ID.
Title Page title (also used as link name).
PageType Page type of the page. Optional page types:
  • HomePage
  • About
  • AgreementTerms
  • BannerPage
  • Calendar
  • ContactPage
  • DownloadPage
  • EnumeratePage
  • FAQPage
  • GuestbookReview
  • HomePage
  • LinkPage
  • MailingList
  • MailingPage
  • NewHomePage
  • NewsPage
  • PageBlog
  • Poll
  • PresentationPage
  • PriceListPage
  • RedirectPage
  • ReservePage
  • RoutePage
  • ShowMailings
  • StandardPage
  • UserAccount
Deeplink Link to linked page.

Available in code fragment
Codefragment Variable Description
Pages {$aPages} An array of Page-objects.

Product

Objectproperties
Property Description
ProductName Name of product.
ProductNumber Productnumber/article number.
ShortDescription Short description (max. 200 characters).
Description Full description.
Unit Unity of product.
Tax VAT-value as integer. E.g. 0, 6 of 21.
Stock Current stock.
Price Selling price (if a discount is applicable, it is deducted). Example values: 10, 10.1 en 10.95.
FromPrice Original price (if discount is applicable it will differ from Price. Example values: 10, 10.1 en 10.95
Discount Discount on a product (if applicable). Value contains discount value. Example values: 10, 10.1 en 10.95.
PriceFormatted Formatted selling price (if a discount is applicable, it is deducted). Example values: 10,00, 10,10 en 10,95.
FromPriceFormatted Formatted original price (if discount is applicable it differs from Price). Example values: 10,00, 10,10 en 10,95.
DiscountFormatted Formatted discount on a product (if applicable). Example values: 10,00, 10,10 en 10,95
Deeplink Deeplink to product page.
MainImageDeeplink Deeplink to main image of product.

As standard a measurement of 500px wide with matching space. The platform offers a render farm that allows you to scale to any measure you desire. This may make quite a difference in bandwidth. To scale an mage ( and automatically saving it, following code is used:

{$oProduct->MainImageDeeplink|replace:'/Large':'/150'}.

Using this code that normally was served as 500 px width – the image will be served as an image of 150px width. If the image of 150px width did not exist as yet, it is automatically created. Images cannot be made larger than the orginal uploaded file.
MainImageThumbnailDeeplink Deeplink to the thumbnail of the main image of the product.
CreateDate Y-m-d H:i:s Date when product was created.
OrderButtonType Type of button that was advised in product management:
- OrderButton, orderbutton (consult hook_AddProductToCart for implementation documentation).
- OfferButton, offerbutton
- NoButton, no button
ShowOrderButton true of false

Determine true of false for property ShowOrderButton
The property ShowOrderButton contains the value true or false depending on several combinations of settings and product properties. Factors that should be taken into account are:

Setting Location
Show prices to guest Starting point/My webshop/Settings/General/Login systems
Hide orderbutton if no more stock is available Starting point / My webshop / Settings / Orderprocess and stock / Stockmanagement / Stock options
Product has stock Starting point / My products/Product management / product in question/Tab Stock
Stocktype Starting point / My products / Product management / Product in question / Tab Stock
Stock Starting point / My products / Product management / Product in question / Tab stock
Show order / offer button at product Starting point / My products / Productmanagement / Product in question / Tab Options

The propertyShowOrderButton is only true for following combinations:
  1. Show prices to guests [=Yes]and also
    Hide orderbutton if no stock is available[=checked]and also
    Product has stock [=Yes] and also
    Stock is [=Bigger than 0] and also
    Show order/offerbutton with product[=Orderbutton]
  2. Show prices to guests[=Yes]and also
    Hide orderbutton if no stock is available [=Unchecked]and also
    Show order/offerbutton with product[=Orderbutton]
  3. Show prices to guests[=Yes] and also
    Product has stock [=Unchecked] and also
    Show order/offerbutton with product[=Orderbutton]
  4. Show prices to guests[=Yes] and also
    Product type [=Attribute] and also
    Show order/offerbutton with product [=Orderbutton]
  5. Show prices to guests [=No] and also
    Customer logged in [=No] and also
    Hide order button if there is no stock available [=Checked] and also
    Product has stock [=Checked] and also
    Stock [=Bigger than 0] and also
    Show order/offerbutton with product[=Orderbutton]
  6. Show prices to guests [=No] and also
    Customer logged in [=Yes] and also
    Hide orderbutton if no stock is available [=Unchecked]and also
    Show order/offer button with product [=Orderbutton]
  7. Show prices to guests [=No] and also
    Customer logged in [=Yes] and also
    Product has stock [=Unchecked] and also
    Show order/offer button with product [=Orderbutton]
  8. Show prices to guests [=No] and also
    Customer logged in [=Ja] and also
    Stocktype [=Attribute] and also
    Show order/offer button with product [=Orderbutton]

Available in code fragment
Codefragment Variable Description
BestSellers {$aBestSellers} An array of Product-object maximum 25.
Product on offer {$oSpecialOffer} A Product-object
Example product category image {$aProductCategoryProducts} An array of Product-objects. This code fragment is available in the filesProductCategory1.sub.tpl, ProductCategory2.sub.tpl, ProductCategory3.sub.tpl and ProductCategory4.sub.tpl and be used as layout for category pages and certain elements on the modular page.

ProductCategory

Within the platform, product categories can be used in several places , however, it depends on the location what object properties a ProductCategory-object has. ProductCategory-objects are available in following places:

  • - Index.tpl
  • - ProductCategory1.sub.tpl
  • - ProductCategory2.sub.tpl
  • - ProductCategory3.sub.tpl
  • - ProductCategory4.sub.tpl
  • - SubCategory1.sub.tpl
  • - SubCategory2.sub.tpl

ProductCategory in Index.tpl

ProductCategory-objects in the file Index.tpl are usually used to build the navigation structure within the theme. In below tables the object properties are named and it is mentioned in which code fragments these object properties are available.

Objectproperties
Property Description
Id Unique ID of product category.
ParentId ID of upper category.
Name Name of category.
Description Description of category
ShowOrderButton true of false.This attribute may be used to determine if an order button should be shown or not. This depends on the setting chosen for the category in question in the catalogue module.
ApplyPhotoEnlargement true of false.This attribute may be used to determine if a large picture should be shown or not. This depends on the setting chosen for the category in question in the catalogue module.
ApplyPhotoCanvas true of false.This attribute may be used to determine if a canvas image shoud be used or not. This depends on the setting chosen for the category in question in the catalogue module.
ProductsPerPage Number of products that is shown per page within the category in question. This depends on the setting chosen for the category in question in the catalogue module.
Deeplink Link to the product category page.
SubCategories An array of ProductCategory-objects, within the main category if the main category contains sub categories.

Available in code fragment
Codefragment Variable Description
Catalogue (with subcategories) {$aCategories} An array of ProductCategory- objects.
Catalogue (without subcategories) {$aCategories} An array of ProductCategory- objects.

ProductCategory in ProductCategory(1|2|3|4).sub.tpl

ProductCategory-objects within the files ProductCategory1.sub.tpl, ProductCategory2.sub.tpl, ProductCategory3.sub.tpl and productCategory4.sub.tpl are used to give supplementary information within a product category description. In below tables the object properties are mentioned as well as the code fragments in which the object properties are available.

Object properties
Property Description
ProductCount Total number of products in the product category.
CurrentSubPage Currently active subpage.
ProductsPerPage The number of products that can be displayed for each page.
ShowOrderButton true of false. This attribute can be used to determine if an order button should be shown or not. This depends on the chosen setting for the category in question in the catalogue module.
ApplyPhotoEnlargement true of false. This attribute can be used to determine if a large picture should be shown or not. This depends on the setting chosen for the category in question in the catalogue module.
ApplyPhotoCanvas true of false. This attribute can be used to determine if a canvas image should be used or not. This depends on the setting chosen for the category in question in the catalogue module.

Available in code fragment
Codefragment Variable Description
Example product category image {$oProductCategory} A Productcategory-object.

ProductCategory in SubCategory(1|2).sub.tpl

ProductCategory-objects in the files SubCategory1.sub.tpl and SubCategory2.sub.tpl are used to show the subcategories within a product category image. In below tables the object properties are named. and also in which code fragments these object properties are available.

Objectproperties
Property Description
Name Name of subcategory.
Description Description of subcategory.
ShowOrderButton true of false. This attribute can be used to determine if an order button should be shown or not. This depends on the chosen setting for the category in question in the catalogue module true of false.
ApplyPhotoEnlargement true of false. This attribute can be used to determine if a large picture should be shown or not. This depends on the setting chosen for the category in question in the catalogue module.
ApplyPhotoCanvas true of false. This attribute can be used to determine if a canvas image should be used or not. This depends on the setting chosen for the category in question in the catalogue module.
Deeplink Link to the product category page.
MainImageDeeplink Link to the image of the product category.

Beschikbaar in codefragment
Codefragment Variable Description
Example subcategories within category {$aProductCategorySubCategories} An array of ProductCategory-objects.

RSSFeed

Object properties
Property Description
Name Name of feed:
  • Latest product.
  • Most popular offers.
  • Latest news.
Deeplink Link to RSS feed in question.

Available in codefragement
Codefragment Variable Description
List of RSS feeds {$aRSSFeeds} An array of RSSFeed-objects

SocialMediaAccount

Object properties
Property Description
Platform Name of platform:
  • Facebook.
  • Google.
  • Hyves.
  • Instagram.
  • LinkedIN.
  • Pinterest.
  • Twitter.
  • Youtube.
AccountName Accountnaam on platform
Deeplink Link to account in question.

Available in codefragment
Codefragment Variable Description
Social Media Accounts {$aSocialMediaAccounts} An array van SocialMediaAccount-objects.

End user settings

If you develop a theme for an end user who does not have any knowledge of web development, you can add end user settings to your theme. End user settings are managed through the dialogue window “End user settings”. A minimum of one end user category setting should be created to be able to create end user settings. The end user himself does not need to make any changes in the source code of the theme, but is shown a dialogue window based on the categories and settings, where these settings can be given values. Every category created is presented as a separate tab for the end user.

In order to create structure and overview end user settings should be distinguished into categories. Each category is represented as a separate tab for the end user, where for each tab/category the settings created for the end user can be represented. Examples of categories may be: “General”, “Colours”, Main page” etc.

An end user setting

Inputfield Description
Label Label of the setting. This is the naming of the setting in the dialogue window for the end user.
Variable name Name of the variable the value can be read out with. The chosen variable name should be unique for each separate theme. In order to print the value of a variable the entering {$oEndUserSetting->VariableName} is used, 'VariableName' being the chosen variable name. The variable name may exclusively contain alfa numeric characters.
Type
  • Text, an input field for a text line.
  • Tekstbox, a text field.
  • Tekstbox with layout and textfield provided with layout options.
  • Menu, a selection box containing a minimum of two choices. As many choices a desired may be added.
  • Upload field for an image. The end user may select and upload a file.
  • Colour option box, a field that allows the end user to select a colour by using a colour palette.
  • Numeric value, an input field for a numeric value.
Standard value The standard value for the setting if end user has not selected a a value.

Implementing an end user setting.

The end user settings that were created are shown in the item “Code fragments” as a special item. By clicking an end user setting it is placed in the active editor. If the work field layout “Theme file as well as separate CSS window” is used, this means that the implementation code is placed in the editor for theme file or CSS file. The end user settings may be used in the theme files Index.tpl, Template.css and Scrtipts.js.

Multilingual support

If your webshop uses multilingual spport you may want to include multiligual variables in the theme you develop. E.g. a shoppingcart image you developed yourself. You may wish to show “Shopping basket”, but to your English visitors you may like to show “Shoppingcart”. Following documentation and examples will teach you how to realise this.

If you do not specify a translation for a certain language ( read following syntax-structure) , and the webshop is represented in that language, the translation you specified first will be shown automatically. It makes no difference in which order the translations are placed.

Each text you wish to present multilangually, should get a multilingual definition.
The syntax of such a definition consists of a number of elements:

Syntax structure

Syntax Description
{* ml This indicates that a multilingual translation will start. Attention: spacing at the end is obligatory!.
sPlaceHolderName Name of the variable that is defined.
:nl[Vertaling]
:en[Translation]
:de[Uebersetzung]
:fr[Traduction]
:tr[Çeviri]
Here the translation is given for each language. A language starts with a semicolon followed by the language code. The translation per language is represented by square brackets.
/ml *} This indicates the end of a multilingual translation.

Available languages

Language code Language
nl Dutch.
en English.
de German.
fr French.
tr Turkish.

Examples

Extensive notation: {* ml
  sHelloWorld
    :nl[Hallo wereld]
    :en[Hello world]
    :de[Hallo Welt]
    :fr[Bonjour monde]
/ml *}
My multilingual variable: {$sHelloWorld}

Shortened notation: {* ml sHelloWorld:nl[Hallo wereld]:en[Hello world]:de[Hallo Welt]:fr[Bonjour monde]/ml *}
My shortened notation multilingual variable: {$sHelloWorld}

No translation for every language:
Note: In this example the active language of the webshop is Dutch, the English language will be shown. {* ml
  sHelloWorld
    :en[Hello world]
    :de[Hallo Welt]
/ml *}
My multilingual variable: {$sHelloWorld}

AJAX widgets

AJAX Widgets are widgets that can contain a certain content and can be restored “below water” (showing formatting and styles) without the page the visitor is on at that moment having to be loaded again. AJAX stands for Asynchronous Javascript And XML meaning that the data will be retrieved asynchronously from the webserver. This is a technique that allows you to make pages interactive without having to restore a whole page. Below is described how to recognize and apply an AJAX Widget, followed by the description of AJAX Widgets available.

Syntax structure

Syntax Description
{* plugin *} This indicates the start of an AJAX Widget.
<div id=""> The div in which the AJAX Widget-code is placed. The ID of the div should be a valid AJAX Widget-name (see available AJAX Widgets). If no valid ID is specified and the syntax is correct, the theme is filed but there is no callback-function in the webshop that will trigger this AJAX Widget.
</div> The closing tag of the div in which the AJAZX widget-code is placed.
{* /plugin *} This indicates that an AJAX Widget ends.

Example: {* plugin *}
  <div id="SmallBasket">
    // Widget code
  </div>
{* /plugin *}

Available AJEX widgets

Following AJAX Widgets are available:

  • Shopping basket

Shopping basket

The shopping basket is a typical example of anAJAX Widget. It is often an item that you wish to present clean-cut, well-organized and well-considered. A shopping basket as AJAX Widget is very user friendly because the option “Show dialogue window shopping cart”( My webshop/Settings/Orderproces and stock/Order proces settings) is available. The shopping basket information is automatically updated as soon as a visitor places a product in the shopping basket, without the page reloading again.


Basic code {* plugin *}
  <div id="SmallBasket">
  
  </div>
{* /plugin *}
Available variables within this widget
Variable Content and data type of variable
{$aOrderRows} An array of OrderRow-objects (see 'List of objects')

Example: {* plugin *}
  <div id="SmallBasket">
    {if $aOrderRows|@count eq 0}
      {* ml
        sBasketLine
          :nl[Er zijn nog geen producten in uw winkelmand geplaatst.]
          :en[There are no products in your shopping cart yet.]
          :de[Es gibt keine Produkte in Ihrem Warenkorb.]
          :fr[Il n'y a aucun produit dans votre panier pour le moment.]
      /ml *}
      {$sBasketLine}
    {else}
              
      <table cellpadding="0" cellspacing="0" width="100%">
        {$fTotal = 0}
        {foreach from=$aOrderRows item=oOrderRow}
          {$fTotal = $fTotal + $oOrderRow->TotalPrice}
          <tr>
            <td style="width:30px; text-align:center;">{$oOrderRow->Count}</td>
            <td style="width:15px;"> × </td>
            <td>{$oOrderRow->ProductName|middle_truncate:50:3}</td>
            <td style="width:15px; text-align:center;"> {$sCurrency} </td>
            <td style="width:50px; text-align:right;">{$oOrderRow->PriceFormatted}</td>
          </tr>
        {/foreach}
        <tr>
          <td colspan="3"></td>
          <td style="width:15px; text-align:center;"> {$sCurrency} </td>
          <td style="width:50px; text-align:right;">{$fTotal|number_format:'2':',':'.'}</td>
        </tr>
      </table>
              
      {* ml
        sPayButton
          :nl[Afrekenen]
          :en[Checkout]
          :de[Abrechnen]
          :fr[Régler]
      /ml *}
      <input type="button" value="{$sPayButton}" onclick="window.location = '{$sBasketPageDeeplink}';"/>
              
    {/if}
  </div>
{* /plugin *}

Action Hooks

Action Hooks are the link between your Pro-Tom design and the internal functionality of the webshop platform. Action Hooks are marked out because they are hooked via the class-attribute.

hook_AddProductToCart

Adds a product to the visitor's shopping basket.

Conditional functioning based on settings.
Settings “Functioning order button & shoppingcart'
Location Startingpoint / My webshop / Settings / Order proces settings
Behaviour based on value
  • To shopping cart-page - visitor is forwarded to the shopping basket page.
  • Show dialogue window shopping cart - visitor remains on current page and is shown a dialogue window showing the added product including quantity.

Data-attributes
Attribute Obligatory Description
data-product-id Yes Unique product id (Product::Id)
data-quantity No Quantity ordered. The action hook only accepts an integer-value, all other values are converted to '1'.

Example
<span class="hook_AddProductToCart PredefinedButton" data-product-id="123">
  Bestellen
</span>

Example with order quantity input field
<script type="text/javascript">
  $(document).ready(function() {
    $('.change-quantity').keyup(function() {
      // Controleren op een integer-invoerwaarde, anders de waarde 1 toekennen
      var iNewQuantity = Math.floor($(this).val()) == $(this).val() && $.isNumeric($(this).val())
        ? $(this).val()
        : 1;
        
      $(this)
        .parent()
        .find('.hook_AddProductToCart')
        .attr(
          'data-quantity',
          iNewQuantity
        );
    });
  });
</script>
<div>
  <input type="text" class="change-quantity" value="1"/>
  <span class="hook_AddProductToCart PredefinedButton" data-product-id="123" data-quantity="1">
    Bestellen
  </span>
</div>

hook_SubscribeToNewsletter

Sign on a visitor for the newsletter on the mailing list “Logged on via website”. In input-elements the action hook will check if enter was pressed and will try to sign on the visitor. The action hook reacts on click-events on all other element types. A succesful log on ensues if a name and valid email address have been entered.

Attention: the implementation code should be nested in an element with the id NewsMailRegistration, otherwise the action hook logic required will not be loaded!

DOM-elements
Element Obligatory Description
input#NewsEmailEmail Yes Mail address of the subschriber.
input#NewsEmailName No Name of subscriber.
input#NewsEmailBName No Company name of subscriber.

Result shown
Element Description
#NewsLetterEmailError Is filled with the result of the logon:
- You were succesfully signed on for the newsletter
- This email address was added to the list
- This is an invalid email address

Example
<div id="NewsMailRegistration">
  <div id="NewsLetterEmailError"></div>
  <input type="text" id="NewsMailName" class="hook_SubscribeToNewsletter" placeholder="Uw naam"/><br/>
  <input type="text" id="NewsMailEmail" class="hook_SubscribeToNewsletter" placeholder="Uw e-mailadres"/><br/>
  <a href="#" class="hook_SubscribeToNewsletter PredefinedButton">
    Aanmelden
  </span>
</div>
Examples
Een paar voorbeelden om je op weg te helpen!
 

Deviating start page

Using below code it is easy to create a deviating start page. <!DOCTYPE html>
<html>
  <head>
    {$_IncludeHead}
  </head>
  <body {$sBodyLogic}>    
    {if $sCurrentPage == 'HomePage'}
      // Homepage opmaak
      {$_IncludeContent}
    {else}
      // Andere pagina opmaak
      {$_IncludeContent}
    {/if}
    {$_IncludeTail}
  </body>
</html>

Bestseller styles

Using the code below it is easy to style your own bestsellers. Have a look at the object documentation of the Product-object to see every possible property. <!DOCTYPE html>
<html>
  <head>
    {$_IncludeHead}
    <style type="text/css">
      ol {
        list-style:none;
        margin:0;
        padding:0;}
      
      ol li {
        display:block;
        float:left;
        margin-right:10px;}
        
      .bestseller {
        border:1px solid #ccc;
        padding:10px;
        background:#ededed;}
      
      .bestseller img {
        width:200px;
        padding-bottom:5px;
        margin-bottom:5px;
        border-bottom:1px solid #ccc;}
      
      .bestseller a {
        display:block;
        padding:8px;
        background:#2ecc71;
        text-decoration:none;
        color:#fff;
        font-weight:bold;}
      
      .bestseller a:hover {
        background:#27ae60;}
    </style>
  </head>
  <body {$sBodyLogic}>    
    ...
    
    <ol>
    {section loop=$aBestSellers name=i max=25}
      {$oBestSeller = $aBestSellers[i]}
      <li>
        <div class="bestseller">
          <img src="{$oBestSeller->MainImageDeeplink}"/>          
          <a href="{$oBestSeller->Deeplink}">{$oBestSeller->ProductName}</a>
        </div>
      </li>
    {/section}
    </ol>
    
    ...    
  </body>
</html>

Your own logon screen

Using below code your can create your login window within your theme. For more information on the variables used in this example, please have a look at the documentation, part list of variables. <!DOCTYPE html>
<html>
  <head>
    {$_IncludeHead}
    <style type="text/css">
      
    </style>
  </head>
  <body {$sBodyLogic}>    
    ...
    
    {if $bCustomerLoginActive == true}
      {if $bCustomerLoggedIn == false}
        <form id="UL_Login" method="post" action="{$sCustomerLoginPageDeeplink}">          
          <input type="text" name="UL_USERNAME" placeholder="Je gebruikersnaam"/><br/>
          <input type="text" name="UL_PASSWORD" placeholder="Je wachtwoord"/><br/>
          <span class="PredefinedButton" onclick="$('#UL_Login').submit();">Inloggen</span>
          
          {if $sCustomerLoginSystemType != 'ActiveNoRegistration'}
            Nog geen klant? Klik hieronder om een account aan te maken.
            <span class="PredefinedButton" onclick="GA_link('{$sCustomerRegistrationPageDeeplink}');">Registreren</span>
          {/if}
        </form>
      {else}
        Welkom {$sCustomerName},<br/><br/>
        
        {if $fCustomerDiscount > 0}
          Jouw standaardkorting: {$fCustomerDiscount}%.<br/><br/>
        {/if}
        
        <span class="PredefinedButton" onclick="window.location = '{$sCustomerLogoutPageDeeplink}';">Uitloggen</span>
      {/if}
    {/if}
    
    ...    
  </body>
</html>

Shopping basket with automatic update

Using below code you can create your own shoppingbasket window that updates automatically if a visitor “continues shopping”. <!DOCTYPE html>
<html>
  <head>
    {$_IncludeHead}
    <style type="text/css">
      
    </style>
  </head>
  <body {$sBodyLogic}>    
    ...
    
    {* plugin *}
      <div id="SmallBasket">
        {if $aOrderRows|@count eq 0}
          {* ml
            sBasketLine
              :nl[Er zijn nog geen producten in uw winkelmand geplaatst.]
              :en[There are no products in your shopping cart yet.]
              :de[Es gibt keine Produkte in Ihrem Warenkorb.]
              :fr[Il n'y a aucun produit dans votre panier pour le moment.]
          /ml *}
          {$sBasketLine}
        {else}
                  
          <table cellpadding="0" cellspacing="0" width="100%">
            {$fTotal = 0}
            {foreach from=$aOrderRows item=oOrderRow}
              {$fTotal = $fTotal + $oOrderRow->TotalPrice}
              <tr>
                <td style="width:30px; text-align:center;">{$oOrderRow->Count}</td>
                <td style="width:15px;"> × </td>
                <td>{$oOrderRow->ProductName|middle_truncate:50:3}</td>
                <td style="width:15px; text-align:center;"> {$sCurrency} </td>
                <td style="width:50px; text-align:right;">{$oOrderRow->PriceFormatted}</td>
              </tr>
            {/foreach}
            <tr>
              <td colspan="3"></td>
              <td style="width:15px; text-align:center;"> {$sCurrency} </td>
              <td style="width:50px; text-align:right;">{$fTotal|number_format:'2':',':'.'}</td>
            </tr>
          </table>
                  
          {* ml
            sPayButton
              :nl[Afrekenen]
              :en[Checkout]
              :de[Abrechnen]
              :fr[Régler]
          /ml *}
          <input type="button" value="{$sPayButton}" onclick="window.location = '{$sBasketPageDeeplink}';"/>
                  
        {/if}
      </div>
    {* /plugin *}
      
    ...    
  </body>
</html>

A category display of your own

A category display can be chosen in category management and for certain elements on the modular page. {if $aProductCategoryProducts|@count > 0}
  <style type="text/css">
    /*
    * Because of the code snippet CSS-code is provided within the snippet.
    * You can move these CSS-declarations to Template.css if you like.
    */
    .customlayout-category-container {
      width:100%;
      padding-top:15px;
      padding-bottom:15px;}
    
    .customlayout-category-breaker {
      clear:both;
      padding-top:10px;
      padding-bottom:10px;
      width:100%;}
    
    .customlayout-category-product-col {
      position:relative;
      -moz-box-sizing:border-box;
      box-sizing:border-box;
      float:left;
      width:25%;
      padding-left:10px;
      padding-right:10px;}
    
    .customlayout-category-product-item-border {
      border:1px solid #ededed;}
    
    .customlayout-category-product-item {
      padding:10px;
      background:#fff;
      border-top:1px solid #f9f9f9;}
    
    .customlayout-category-product-item-productname {
      height:70px;}
    
    .customlayout-category-product-item-image img {
      width:100%;
      vertical-align:bottom;
      background:#fff;
      padding-top:10px;}
    
    .customlayout-category-product-item-price {
      display:inline-block;
      padding:10px;
      font-weight:bold;
      font-size:14px;}
    
    .customlayout-category-product-item-fromprice {
      text-decoration:line-through;
      font-weight:normal;
      color:#999;}
    
    .customlayout-category-product-item-buttonbar {
      overflow:auto;}
    
    .customlayout-category-product-item-buttonbar-col {
      float:left;
      width:50%;}
    
    .customlayout-category-flagged {
      position:absolute;
      z-index:10;
      line-height:25px;
      text-align:center;
      font-weight:bold;
      color:#fff;}
    
    .customlayout-category-flagged-new {   
      right:0px;
      top:10px;
      height:25px;
      width:50px;
      background:#f1c40f;
      border:2px solid #f39c12;}
    
    .customlayout-category-flagged-offer {
      top:44px;
      right:0px;
      height:25px;
      width:50px;
      background:#e74c3c;
      border:2px solid #c0392b;}
    
    .text-center {
      text-align:center;}
    
    .text-right {
      text-align:right;}
  </style>

  <div class="customlayout-category-container">
    {section name=i loop=$aProductCategoryProducts}
      {$oProduct = $aProductCategoryProducts[i]}
      
      {if $smarty.section.i.index % 4 == 0 && $smarty.section.i.index > 0}
        <div class="customlayout-category-breaker"></div>
      {/if}
      
      <div class="customlayout-category-product-col">
        <div class="customlayout-category-product-item-border">
        {$iFlagAsNewProductIfCreatedWithinDays = 10}
        {if ($smarty.now - strtotime($oProduct->CreateDate)) / 86400 < $iFlagAsNewProductIfCreatedWithinDays}
          {* ml
            sProductFlagNewLabel
              :nl[Nieuw!]
              :en[New!]
              :de[Neu!]
              :fr[Nouveau!]
              :tr[Yeni!]
          /ml *}
          <div class="customlayout-category-flagged customlayout-category-flagged-new">{$sProductFlagNewLabel}</div>
        {/if}
        {if $oProduct->IsOffer == true}
          <div class="customlayout-category-flagged customlayout-category-flagged-offer">
            -{math equation="100 - x / y * 100" x=$oProduct->Price y=$oProduct->FromPrice format="%.0f"}%
            </div>
        {/if}
      
        <div class="customlayout-category-product-item-image">
          <img src="{$oProduct->MainImageDeeplink}"/>
          </div>
          <div class="customlayout-category-product-item">   
            <div class="customlayout-category-product-item-productname">
              {$oProduct->ProductName}<br/>
            </div>  
      
            {if in_array($oProduct->OrderButtonType, array('OrderButton', 'NoButton'))}
              {if $bShowPricesToGuests == true}
                <div class="text-center">
                  <span class="customlayout-category-product-item-price">
                    {if $oProduct->IsOffer == true}
                      <span class="customlayout-category-product-item-fromprice">{$sCurrency} {$oProduct->FromPriceFormatted}</span>
                    {/if}
                    {$sCurrency} {$oProduct->PriceFormatted} p/{$oProduct->Unit}
                  </span>
                </div>
              {/if}
            {else}
              {* ml
                sProductBasedOnOfferLabel
                  :nl[Op basis van offerte]
                  :en[On the basis of offer]
                  :de[Auf der Grundlage des Angebots]
                  :fr[Sur la base de l'offre]
                  :tr[Teklif temelinde]
              /ml *}
              <div class="text-center">
                <span class="customlayout-category-product-item-price">
                  {$sProductBasedOnOfferLabel}
                </span>
              </div>
            {/if}
      
            <div class="customlayout-category-product-item-buttonbar">
              <div class="customlayout-category-product-item-buttonbar-col">
                {* ml
                  sProductDetailsLinkLabel
                    :nl[Meer informatie]
                    :en[More information]
                    :de[Mehr Informationen]
                    :fr[Plus d'information]
                    :tr[Daha fazla bilgi]
                /ml *}
                <small>
                  <a href="{$oProduct->Deeplink}">{$sProductDetailsLinkLabel}</a>
                </small>
              </div>
              {if $oProductCategory->ShowOrderButton == true && $oProduct->ShowOrderButton == true}   
                <div class="customlayout-category-product-item-buttonbar-col text-right">
                  <span class="hook_AddProductToCart PredefinedButton" data-product-id="{$oProduct->Id}">
                    {* ml
                      sOrderButtonLabel
                        :nl[Bestellen]
                        :en[Order]
                        :de[Bestellen]
                        :fr[Ordre]
                        :tr[Satın almak]
                    /ml *}
                    {$sOrderButtonLabel}
                  </span>
                </div>
              {/if}
            </div>
          </div>
        </div>
      </div>
    {/section}
  </div>
{/if}