Templates (HTX)

The Template system controls all display and presentation of data. The templates together with the configuration data (System Manager) controls what data is displayed and the format of that data. The template system allows a high degree of flexibility, but also a high degree of responsibility.

The flexibility gives you the possibility to do almost everything with the template system, but at the cost of complexity and costly upgrades. All the possibilites of the template system should be used with care.

Remember: Default templates should be treated as read only, and you must upload new versions of templates if you want to customize them. All default templates are overwritten upon upgrade.

General Syntax

A HTML Template is an HTML file containing:

  • Zpider Tags
  • Zpider if-tags
  • Zpider Entities
  • Comments

A template is processed on the server side. The result of this processing is an html file which is returned to the client (response). The strategy is that all display of data to the client is done by the template system. The templates are first parsed and a parsed version of the template is used for processing. Once the template has been parsed, the parsed version will be used lateer. This enables quick processing of the templates.


The main purpose of the zpider tags is to select the data to be display, control repetions, including new templates, and so on, although there are tags that actually writes data as the text and write tags.

There are two kinds of zpider tags non-repeating and repeating.

A Non-repeating tag does not have a closing tag and is on the format:

<z:tag name="value" name="value" ...>

name=value defines a property for tag. Any number of properties may be defined for each tag.

A Repeating tag does have a closing tag and is on the format:

<z:tag name="value" name="value" ...>
....tag body...

The tag body of a repeating tag will be executed the number of repetitions defined by the repeating tag. A webattributes tag will repeate for each webattribute. A loop tag will repeate the number of times defined in the start, until and step properties.


The main purpose of the entity is to write data to the response html. The entity has the general syntax:


Where left.right is used, the left part typically refers to an object (an alias or name for a stored object), and the right part refers to a keyword or field within that object. To illustrate left and right, an entity could look like this: $z:value[article.price], here value is the name of the entity, article is the left part of the specifyer, which is an alias for a dataclass. Price is the right part of the specifyer which is a value from the article dataclass. Where just specifyer is used, it normally refers to an object.

The html-template may contain comments. The comments starts with: ##, as in this example:

<td class="$z:value[attribute.contentstyle]" colspan="99" align="left">
## -------------------------
## Attribute type (1) TEXT
## -------------------------

Everything right of ## is ignored when the template is parsed. Comments may be on a line by itself, or to the right of code.


All data retrieved from Zpider or the ERP system must be retrieved from Dataclasses. Dataclasses are created in the templates using the prepare tag. A dataclass is either a collection of datarows (a table), or a tree structure containing tree nodes. You may iterate a dataset using the foreach tag. Individual dataelements, or columns, are retrieved using entities.

Available dataclasses

maingroupA tree dataclass of Product Groups; fetched from Zpider
menuA tree dataclass of a menu; fetched from Zpider
articleCollection of products; fetched from the ERP system
supportContains some global data like the stylesheet; fetched from Zpider
quickorderContains quickorders; fetched from Zpider
webuserContains webuser data; fetched from Zpider
documentContains documents; fetched from Zpider
orderContains orders; fetched from ERP system
orderlineContains orderlines; fetched from ERP system
customerContains customer info; fetched from ERP system (Actor in Business; Customer in Global)
zpiderorderContains orders from Zpider
zpiderorderlineContains orderlines from Zpider
freightContains freight information; fetched from Zpider
creditcardCredit Card info, communicates with the Payment Server; fetched from Zpider
clientadministratorConfiguration data for the client; fetched from Zpider
shoppingcartShoppingcart data; fetched from Zpider


Dataclasses and attributes are stored in one of three storage areas, called Scope:

pageSurvives the processing of a page, which currently is the same as request.
requestAll data received from the client is placed here. All data placed here survives the current request.
sessionData placed here exists between requests and lives until the user logs off or the session times out.

The default scope is page. Where a scope property may be defined, and is omitted, page is automatically selected. A data element (attribute or dataclass) may only exists in one of the scopes. This means for example that existing elements are deleted when new elements are added with an existing name.

When an attribute or dataclass is to be retrieved, the system will search the scopes in this sequence:

  1. page
  2. request
  3. session

Mathematical functions

Mathematical functions may be used in all tags within a property value and in the condition part of the if and elseif tags. The z:write tag was created with mathematical functions in mind. It will write the value property to the responding html. The simplest form of using mathematical functions is like this:

<z:write value=1+1>

This will write "2" to the html at the same position as the z:write tag. Instead of using numbers directly, entities may be used as in this example:

<z:write value=$z:value[article.price] * 1.25>

This will add vat to the price.

In Zpider these mathematical functions are available:

+ - * / %

Entities and constants may be mixed in any way and with any levels of parenthesis, as in this example:

<z:write value=($z:value[cart.price] - ($z:value[cart.price] *
$z:value[cart.discountprc] / 100)) * $z:value[cart.amount] >

This will calculate the sum for an article on the shoppingcart including the discount in %.

Note! The precedense order of the functions are: * / + -

Mathematical functions may also be used in the condition part of the if-tag and elseif-tag, as in this example:

<z:if $z:value[cart.price] * $z:value[cart.amount] * 1.25 gt 100000>
The sum is too large


The structure of the if-tag:

<z:if condition..>
<z:elseif condition..>

The condition may use any combination of these operators/values:

ANDa AND ba and b must both be true
ORa OR ba or b must be true
NOTa NOT ba must be true and b must be false
EQa EQ ba must be equal to b
NEa NE ba must NOT be equal to b
GEa GE ba must be greater than or equal to b
GTa GT ba must be greater than b
LEa LE ba must be less than or equal to b
LTa LT ba must be less than b
hasa has ba must contain the substring b
startwitha startwith ba must start with the substring b
endswitha endswith ba must end with the substring b
%a % 2 EQ 0modulus
(...)any levels of parenthesis may be used
truea EQ true
falsea EQ false

Any string must be in quotes: "this is a string"; however if the string is only one word it will be interpreted as a string. If quotes are missing, and the word contains digits, it is assumed to be a number for example:

<z:if $z:value[attr.price] GT 100.00>
The price is higher than 100

Operators are case insensitive, so writing and or AND, eq or EQ is the same.

Here are some more examples:

<z:if $z:request[page] EQ "orderstep1">
The page is orderstep 1

If-statements may be nested, a new if may be started within an if as in this example:

<z:if $z:value[attribute.attributetype] eq 1 or $z:value[attribute.attributetype] eq 0 or $z:value[attribute.attributetype] eq "">
<z:if $z:value[attribute.keyword] eq "zpiderorder.refcontact">
##-- The refcontact name will be displayed instead of this webuser number.
<z:prepare scope=page dataclass=webuser alias=mycontact ActorNo=$z:value[zpiderorder.refcontact] disabled=0>
## -------------------------
## Attribute type (2)
## -------------------------
<z:elseif $z:value[attribute.attributetype] eq "2">


The include tag will include another module. This means, it will fetch the HTX-file for the specified module which is specific for the user's primary usergroup. There is one speciality about this: if the module is not defined it will fetch the htx-file articlelist.htx; that is the specified module name, with the .htx extension.

v12: Properties passed when including a module is accessible using $z:config[attribute_name].

User defined ASP.NET controls can be included and rendered by using control="control-path" property where control-path is an absolute or relative web path to the user defined control (.ascx). An absolute path always begins with "~/" (eg. ~/Controls/SimpleControl.ascx) and is relative to the application root folder. A relative path may be prefixed with "/" (eg. /Controls/SimpleControl.ascx or Controls/SimpleControl.ascx). In this case Zpider will attempt to fetch the control from either from the Theme folder (eg. ~/Themes/Controls/SimpleControl.ascx) or from application's root folder (~/Controls/SimpleControl.ascx). When the relative path is used controls must be placed either in ~/Controls/ or ~/Themes/Controls/ folder.

In addition to the control path, control properties might be specified. The properties will be set to the user control if the property is marked as public and is writable.



The Webattributes tag is a repeating tag which fetches all Webattributes for a given module limited to the users access rights and in the defined sortorder. Use for example $z:value[artattr.headerstyle] for retrieveing properties of the webattributes itself. Use $z:valueof[artattr] to fetch the value of the keyword defined by the webattribute.

<z:webattributes alias="artattr" module="article">

moduleSet the name of the module
aliasDefine the dataclass which will hold the webattributes


The prepare tag is used create a dataclass. A dataclass represents zero, one or more datarows. You may fetch individual values of the datarow by using the $z:value[alias.keyword] entity or the $z:valueof[webattributes-dataclass] entity. When the dataclass is created it must be "saved" to one of three storage areas, called scope. When a dataclass is saved to the request it is available for the request, and automatically deleted after the request is processed. When a dataclass is saved to a page, it is available A prepare tag may contain additional properties. Each of these properties defines a filter;


Note! After the execution of the prepare tag, the first record is the current record. Page is the default scope.

sortorder="{article.name} ASC"
filter="{article.name} >= B"
pagesize="20" ## New in v12

aliasdefines the storage name for the dataclass being prepared.
scopedefines the storage area (session, request or page) for the dataclass being prepared.
dataclassdefines the type of dataclass being prepared. See list of available dataclasses.
sortorderdefines the sortorder for the data produced by the dataclass
filterdefines additional elements to the where clause of the produced query.
startrecorddefine the startinc index of the collection. Zero based.
maxrowsdefines the maximum number of rows the dataclass should retrieve. Default: 200
pagesize (v12)defines the pagesize on PageControl.

Advanced filters

By combining <z:set and <z:prepare> you can create advanced filters. The following example will fetch TOP 10 active offers from Visma Global.

<z:set scope="page" name="filter">ART.ArticleNo IN (SELECT TOP 10 ArticleNo FROM Article A WHERE GETDATE() BETWEEN A.StartDateOfferPrice AND A.StopDateOfferPrice AND A.OfferPrice > 0 ORDER BY A.StartDateOfferPrice desc)</z:set>
<z:prepare alias="offers" dataclass="article" filter=$z:get[page.filter] maxrows="10" startrecord="0">
<z:if $z:iteration[offers.count] gt 0>
<hr />
<h3>Current offers</h3>
<z:subst alias=article use=offers>
... Here you'll need some code to present the offers.
<z:unsubst alias=article>

Custom query parameters

You can add custom query parameters to the database model by adding something like the following to the query definition.

<Query Name="qry_Article_Full">
<Description>Retrieve the article list</Description>
<QueryParam Name="@CustomerNo" SqlType="String" Description="Customer Number" DefaultValue="0" />

Then in order to use these in your <z:prepare-tag, you just use the prefix @ to signal that it's a query parameter. Remember to set DefaultValue on your query parameter or it will fail if you omit the parameter you've created.

<z:prepare alias="offers" dataclass="article" @CustomerNo=$z:value[webuser.customerno] filter=$z:get[page.filter] maxrows="10" startrecord="0" >


The unprepare will remove the dataclass from the storage area. A dataclass may only exists in one storagearea. It is not necessary to specify scope as the system will find the dataclass anyhow, but specifying scope will run slightly faster. If you specify scope, the system will only search in specified scope. It is good practice to specify scope as you always should be aware of the storageareas for the dataclasses.

Note! Dataclasses stored in Request or Page will automatically be deleted. It should only be necessary to uprepare dataclasses stored in Session scope.

<z:unprepare alias="article" scope="session">
alias is the dataclass to be removed.
scope is the storage area of the dataclass.


The refresh tag is similar in syntax to the prepare tag. The only difference is that refresh will use an existing dataclass and perform a new query on that dataclass.

sortorder="{article.name} ASC"
filter="{article.name} >= B"
alias defines the storage name for the dataclass being prepared.
scope defines the storage area (session, request or page) for the dataclass being prepared.
dataclass defines the type of dataclass being prepared. See list of available dataclasses.
sortorder defines the sortorder for the data produced by the dataclass
filter defines additional elements to the where clause of the produced query.
startrecord define the startinc index of the collection. Zero based.
maxrows defines the maximum number of rows the dataclass should retrieve.


The foreach tag is a repeating tag to run through a dataset's row collection. The purpose of setting pagesize, startpage, startoffset and maxpages is to use the iteration entity to control paging. This makes it easy to tell the user which page he is on and to browse through pages.


aliasdefines the storage name for the dataclass being prepared.
scopedefines the storage area (session, request or page) for the dataclass being prepared.
pagesizedefines the number of rows on each page. Default: 20
maxrowsdefines the maximum number of rows the dataclass should retrieve.
maxpagesdefines the maximum number of pages needed
startpagedefines the starting page
startoffsetdefines the starting offset (index) in the rows collection. Zero based.


The Loadtree tag is a repeating tag and is used to browse through a tree dataclass. A tree dataclass is a dataclass which is represented as a tree structure. You may use the $z:node[] entity to read tree node properties of the current node in the dataclass.

Note! The dataclass must first be prepared before using loadtree.

<z:loadtree alias="artgrp" scope="session" counter="1">

aliasdefines the storage name for the dataclass being prepared.
scopedefines the storage area (session, request or page) for the dataclass being prepared.
counterdefines the starting value for the unique number of the node.


The Set tag is a Non-repeating tag for setting an attribute in one of the three storageareas (scopes): page, request or session. This tag may be used if you need to save some values between requests or between pages being processed.

<z:set name="myname" scope="request" value="myvalue">
<z:set name="name" scope="scope">value</z:set>

nameThe name of the attribute
scopeThe storage location (session, request or page). Default: page.
valueThe value of the attribute. Use this only if you are evaluating mathematical functions. Use the 'inner set' for everything else.


Removes an attribute which was earlier stored by the set-tag.

Note! All Request and Page attributes are automatically removed when the request is processed.

<z:unset name="myname" scope="request">

nameThe name of the attribute.
scopeThe storage location (session, request or page).


The loop tag is a repeating tag (requires a closing </z:loop> tag). The repeation goes on until the current index is greater than the until-value.

<z:loop alias="pg" start="1" until=$z:iteration[article.pagecount]>
<a href="main.aspx?page=articlelist&startpage=$z:index[pg]&query=no">

aliasThe alias for the loop attribute. This may be used to fetch the current index as an entity (index-entity).
startThe starting index. Default: 1.
stepThe stepping value. Default: 1.
untilThe ending value.


This tag is mostly used when including new modules. Subst defines a new alias for an alias. If an includemodule uses article as the alias for the dataclass, but in this situation we want our included module to use the art alias for dataclass, you must the subst tag to change from article to art. The substitute is valid until unsubst is called or the request has been processed.

Note! The substitution does only live within a request.

<z:subst alias="article" use="art">

aliasThe name of the attribute.
useThe storage location (session, request or page).


Removes a substitution for an alias.

<z:unsubst alias="article">

aliasThe name of the attribute


The selectlist tag will produce a combo-box holding a list of items to be displayed. It works in two ways: either by specifying a keyword where a list of values for that keyword is displayed, or if keyword is omitted, a default selection list for that dataclass is displayed.

<z:selectlist alias="payterm" scope="request" keyword="name">

aliasThe alias for the dataclass
scopeThe storage space for the dataclass
keywordThe keyword which we want to display. If this keyword is missing, a default selection list is displayed for the dataclass.
includeblanktrue or blanks may be displayed
currentThe value of the current

Additional filters may be added using the name=value notation.


The text tag may be used to fetch text from a physical file or from http. The text from the file or html returned by the http is inserted into the resulting at text-tag position. The full path will be constructed by joining: path\dir\name. The joining of the tree name will checking duplicated backslashes ().


pathThe physical path to the file (location = file or config), or a http-url (location=http).
dirA directory may be specified (valid for file and config)
nameA filename may be added (valid for file and config)
locationThis is one of:
file - A physical file on the web server.
config - A physical file on the application server (System Manager Server).
http - Content from an http request.


Any additional properties used by the <img> tag may be specified. The full path will be constructed by joining: path\dir\name.

The <z:img> tag will map to a normal <img> tag, but will use showdoc as it's src. In addition, it will check the existence of the image. This is useful for displaying article picture. If the article picture does not exists, nothing is displayed instead of the standard error display.

The processing is done in this priority order:

  1. Picture (pictureID) displayed using Showdoc
  2. Path, dir and/or name using Showdoc
  3. Src, checking existence of physical file

picture This is the PictureID as defined in System Manager: Images; corresponds to the name of the image.
path The image path.
dir The image directory.
name The image name.
returnsrc If true it will only returns the url for the image, not a full <img...> tag, for example: Showdoc.aspx?PICTURE=logo.
location This is the same property used for the text tag. It is one of:
file - A physical file on the web server.
config - A physical file on the application server (System Manager Server).
http - Content from an http request.


The write tag will insert the calculation of the value tag into the resulting html. It was especially created to handle mathematical functions, although mathematical functions may exist in any attribute of any tag.

<z:write value=($z:get[request.myattr] * 25) / 100>

valueAny value, also including mathematical functions.
format (v12).Net formatting string like {0:0.00} etc.
transform (v12)Available transformations are uppercase, lowercase, ucfirst or ucwords
trim (v12)Trim output of the function


This works like <z:write, but it will escape the value you pass it.

<z:set scope="page" name="html_value"><b>This text could be bold</b></z:set>
<z:esc mode="html" value=$z:get[page.html_value]>

This will actually print &gt;b&lt;This text could be bold&gt;/b&lt;.


Set meta tags in head.

nameSet ordinary meta tags like <meta name=[name]. Special handing for title, description and keywords. All others will be set raw.
propertySet open graph meta tags like <meta property=[property].


This sets the open graph meta tag og:image to the full URL of the product image

<z:meta name="og:image">
<z:img path=$z:value[support.erpfilepath] dir="Images" name=$z:value[article.picturefile] absolute="true" returnsrc="true" location="config">


The redirect tag has been developed to replace the old javascript redirect method (document.location = url) used for redirection in template system. The customer browser will be redirected immediately after the tag processing is finished, any other tags present after <z:redirect> tag being omitted. The following example will redirect the user to ~/main.aspx?page=...&refresh=false:

<z:redirect (url="" | page="" ) [property="value" | …]>

urlwill redirect the browser to the specified url
pagewill redirect the browser to main.aspx?page=…

Other properties will be added to the redirection url as &property=value

<z:redirect page=$z:get[request.senderpage] refresh="false">


Entities are used to fetch text or values from dataclasses or attributes. The syntax is simpler than the tag syntext. The general syntax of an entity is:


The left will normally be a dataclass and the right will be a column of that dataclass. The right may be omitted ($z:name[left]).


The value entity will fetch a keyword value from a dataclass. Alias and Keyword must be specified. The resulting string is inserted at the position of the entity.


aliasThe alias for a dataclass.
keywordA keyword supported by the dataclass.


The valueof entity uses a webattribute dataclass and fetches the value of the keyword defined by the current webattribute ($z:valueof[alias]) or it will fetch a specific keyword using the webattribute formatting ($z:valueof[alias.keyword]). The valueof entity is normally used together with the webattributes tag.


aliasThe alias for a dataclass.
keywordA keyword supported by the dataclass.


Get a value set in a scope.


myattrThe name of the attribute, this may already be defined by the <z:set name=myattr value="abc"> Url or form attributes may be retrieved by specifying request as storage
scopeas in the example above.

The set tag and get entity may work well together as in this example:

<z:set name="zipcode" scope="session" value=$z:get[request.zip]>

The set-tag will fetch zip from the request and save this on the session storage area, which will survive as long as the session lives. The get-entity will fetch the zipcode again.



aliasThe alias for the dataclass which is a treetype dataclass.

The available functions:

nameThe name of the current node
numberUniquely identifies the node
parentnumberThe unique number of the parent
parentnameThe name of the parent node
childcountThe number of children for the current node
listorderThe number of the node within all nodes, 0-based
childorderThe order of the current node within the parent, 0-based
levelThe level of the current node, 0-based
isrootY if the current node is the root node; meaning no parents
isleafY if the current node is the leaf node; meaning no children
counterThe counter for the current node

The node entity must work with tree type dataclasses to get treeinfo about the current node.


Every dataclass has a built in Pagecontrol. The iteration entity is used fetch data about from the pagecontrol. This is useful for displaying the page-info.


aliasThe alias for the dataclass

The available functions:

currentNumber of the current entry in the iteration, 0 based
currentonpageNumber of the current entry on the current page, 0 based
nextpagestartoffsetThe offset for the next page from the current page
currentpagestartoffsetThe offset for the current page
previouspagestartoffsetThe offset for the previous page from the current page
maxpagecountMaximum number of entries per page for this iteration
maxcountMaximum number of entries totally
countTotally number of entries. -1 if not available (undefined)
pagecountThe totally number of pages
islastentryY if the current entry is the last entry
islastonpageY if the current entry is the last of the current page
isfirstentryY if the current entry is the first entry
isfirstonpageY if the current entry is the first on the page
currentpageThe number of the current page, 0 based
isfirstpageY if the current page is the first page
islastpageY if the current page is the last page

<z:loop alias="pg" start="1" until=$z:iteration[article.pagecount]>
<a href="main.aspx?page=articlelist&gid=$z:get[request.gid]&gidlevel=$z:get[request.gidlevel]&startpage=$z:index[pg]&query=no">


Displays a text from the text-table of System Managet given it's textID. The text is displayed in the users current language and for the users usergroup. If there is no text for that combination, it will try to fetch a text for all usergroups on the users current language. If that is not found, it will fetch the text for language=999 (all languages).



This is the same as the $z:text entity, except that it will add a <span class=style>text...</span> The style is defined in the System Manager for the textid.



The index entity is used together with the loop tag to get the current index within the loop.

<z:loop alias="loopattr" start="1" until=$z:iteration[article.pagecount]>


This will check the given scope for an attribute or dataclass. Returns T if that attribute or dataclass exists



Displays the error for an alias of a dataclass or for a specific keyword on that dataclass.


For the error of a dataclass, these values are returned:

0NoneNo error
1GeneralA general, unspecified error
2ComponentWriteUnable to write to component
3AddFailureUnable to add data
4LoginFailedUnable to login
5InvalidDataInvalid data provided; illegal format and/or values
10SmtpErrorSmtp Error
11SendEmailUnable to send email
12MissingInfoSome fields are missing data
20MissingPaymentMethodMissing the payment method
21MissingPaymentObjectThe required payment class is missing
22TransactionFailedPayment transaction failed
30InvalidOrderMissing or invalid order

For the error of a specific keyword (field), these values are returned:

0NoneNo error
1MandatoryMissing mandatory data
2InputFormatWrong input format
3PasswordDontMatchInvalid password
4DataLengthTooShortThe input length is shorter than expected
5AlreadyExistThe field already exists
6NotFoundNot found
7InvalidDateTimeInvalid DateTime
8NotAllowedCharsNot allowed chars in password or username
9DataLengthTooLargeThe input length is larger than expected
10InvalidEmailFormatInvalid Email format


This will get a fielderror (see $z:error entity) from the current webattribute.