- Creating Custom Document Templates

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 an 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.

Examining the XML-formatted data

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

https://secure.workbooks.com/accounting/quotations/4612.pdf?template=218

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:

https://secure.workbooks.com/accounting/quotations/4612.xml?template=218

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):

 

<hash>

  <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">

    <order_line_item>

      <type>Private::Accounting::QuotationLineItem</type>

... 

      <product>

        <refcode>PROD-1</refcode>

...

      </product>

      <imported type="boolean">false</imported>

    </order_line_item>

  </order_line_items>

...

  <text>

    <Tax_Point_Date_Label>Tax Point</Tax_Point_Date_Label>

    <Header_Text_Colour>rgb(0,0,0)</Header_Text_Colour>

    <website>http://www.mywebsite.com/</website>

...

  </text>

...

</hash>

 

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.

XSLT

As previously mentioned XSLT is used as the templating language for PDF output documents within Workbooks. Various tutorials exist on the web and there are also several books available. We suggest you start with this tutorial and also take a look within unified.xsl.

A couple of examples:

<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()]">

... introduces a block which is processed for every line item which does not have a _preload_product_id set to 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 is 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="http://exslt.org/dates-and-times" xmlns:str="http://exslt.org/strings" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xslt:output indent="yes" encoding="utf-8"/>

  <xsl:template match="/">

    <fo:root>

      <fo:layout-master-set>

        <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:simple-page-master>

      </fo:layout-master-set>

      <fo:page-sequence master-reference="Letter Page">

        

        <fo:flow flow-name="xsl-region-body">

          <fo:block>

            <fo:inline>

              <xsl:value-of select="/hash/object_ref"/>

            </fo:inline>

          </fo:block>

 

        </fo:flow>

        

      </fo:page-sequence>

    </fo:root>

  </xsl:template>