Knowledge Base

Browse our knowledge base articles to quickly solve your issue.

Creating Custom Document Templates


The unified.xsl template contains a lot of example template markup. Start by taking a sample template from GitHub.

Workbooks uses a templating language called XSLT to define how things are rendered into PDF. XSLT is very flexible and can produce a wide range of output. The XSL template is combined with any data from Workbooks to create the PDF. The data is in XML format. You can create your own XSL template from scratch, but often you will adapt an existing XSL template such as the supplied unified.xsl. To download a copy of a template click on its Filename in the list of PDF templates.

Depending on the age of your Database you might have one of several versions of unified.xsl available. We recommend that you begin by taking a copy of latest version published on GitHub at

Examining the XML-formatted data

When Workbooks generates a PDF document the web browser downloads it from a URL like this:

This URL includes the internal ID of the document and template together with the format of output which is required: pdf. Replace pdf with xml to see the XML which is available:

XML structure

The XML contains a lot of data, much of which will not be needed by the template.  A typical XML document generated by Workbooks looks like this in outline (fetch a real one using the technique above to find out more):

  <id type="integer">4612</id>
... lots of fields ...
  <document_currency_cost amount="145.84" code="GBP">&#163;145.84</document_currency_cost>
... lots more fields ...
  <order_line_items type="array">
      <imported type="boolean">false</imported>
    <Tax_Point_Date_Label>Tax Point</Tax_Point_Date_Label>

As you can see, there is an array of /hash/order_line_items and a set of settings under /hash/text: using the PDF Settings within Workbooks Configuration you can add additional settings which appear here. Other related fields and objects are also included within the XML.


As previously mentioned XSLT is used as the templating language for PDF output documents within Workbooks. Currently, we are using v1.0 of the XSL coding language. Various tutorials exist on the web and there are also several books available. We suggest you start with unified.xsl for examples, however our forums contain lots of useful code, here. A code snippet can be seen below from the unified template which iterates over each line item on your Workbooks record:

<xsl:value-of select="/hash/text/Line_Total_Label"/>
    <!-- extracts the setting called Line_Total_Label which is configured in the PDF Settings within Workbooks. -->
<xsl:for-each select="/hash/order_line_items/order_line_item[contains(./_preload_product_id, 'SHIPPING')=false()]">
    <!-- Specify the code to iterate over. Typically this would be a table with rows and cells -->


The above introduces a block which is processed for every line item where the Product ID does not contain the string "SHIPPING". The behaviour can be reversed by changing FALSE to TRUE. The code will then process for every line item that does contain the string "SHIPPING".

The example XSLT (unified.xsl) includes configuration which applies when the document is being produced in Landscape mode as opposed to in Portrait mode. Within the XSLT you can tell the mode by testing the setting /hash/test/Page_Orientation (which is set to 'Landscape' if the template's name ends in _landscape). 

In particular, note that XSLT is not forgiving with regard to the number of columns in a table. If there is a cell which should be put in a non-existent column then the template will fail to render and you an error will be visible.

An example XSL template

Because unified.xsl is used in a wide variety of contexts it is particularly complex and contains a lot of 'if' and 'case' statements. A custom template will often be much simpler.

For example, this template produces a page containing only an object_ref.

<!-- A very simple XSLT intended to be adapted for test purposes. -->
<xslt:stylesheet xmlns:date="" xmlns:str="" xmlns:xslt="" xmlns:fo="" xmlns:xsl="" version="1.0">
  <xslt:output indent="yes" encoding="utf-8"/>
  <xsl:template match="/">
        <fo:simple-page-master master-name="Letter Page" page-width="11.7in" page-height="8.3in">
          <fo:region-body region-name="xsl-region-body"/>
      <fo:page-sequence master-reference="Letter Page">
        <fo:flow flow-name="xsl-region-body">
              <xsl:value-of select="/hash/object_ref"/>