Magic Smoke ODT Templates

This text describes how ODT templates are generated and which ones exist. ODT templates always use the suffix ".odtt".

Creating a Template

Open Document Files (*.od?, usually *.odt) are basically zipped XML files. Magic Smoke ODF Templates are ODF files in which the "content.xml" file contains some special markup that is replaced by Magic Smoke before the file is used as a normal OD file.

This process needs some knowledge in XML.

  1. Write an OD file that meets your expectations for what you want to template. It is recommended that you already put all variables (@VAR@, see below) into the file to make it easier to find each location.
  2. Unzip it into a clean directory - make sure the directory structure of the ODT-ZIP-file is kept intact.
    Eg. under Linux to extract example.odt: mkdir example; cd example; unzip ../example.odt
  3. Reformat content.xml to make it readable for yourself. You can use any XML tool that suits your need.
    Eg. xmllint --format content.xml >content2.xml; mv content2.xml content.xml
  4. Enter all missing variables and loops. Note that the Template language is line based, while XML is not.
  5. Zip the result into a template file.
    Eg.: cd example; zip -r ../example.odtt .
  6. Upload the template file to the server

Syntax

Variables

Variable names are enclosed in two "@" signs and contain only upper-case letters. Any syntax violation results in the template parser interpreting the text as simple non-variable text and dumping it as is. To create a single "@" you can simply enter "@@".

If a variable exists it is replaced by the value that Magic Smoke intended for it. If it does not exist it is replaced by an empty string.

If a value contains special characters they are replaced by the correct XML sequences (eg. < by &lt;).

Loops and Loop Variables

Some templates use repeating elements. These are expressed as loops. Loops are sections of text that are repeated for every iteration of the internal loop, eg.:
#LOOP:EXAMPLE
<markup>this value changes with each iteration: @EXAMPLE:VAR@</markup>
#ENDLOOP
Each loop begins with a line that starts "#LOOP:" and finishes with the loop name. It ends with a line that contains only "#ENDLOOP". If a loop does not exist this deletes the content in between, if it does exist the content is replicated as often as the loop iterates.

Loop variable names are enclosed in "@", and contain the loop name and the variable name separated by a colon. In each iteration the loop variables are set to the current iterations value. Variables from different loops are handled like unknown variables: they are replaced by empty strings.

Loops cannot be nested.

Conditional Output

The output of parsed lines can be suppressed:
#IF:MYVAR < 66
output if the value is smaller than 66
#ELSE
output otherwise
#ENDIF
A condition consists of exactly two values (both may be variables) and an operator. More complex expressions are not possible at the moment. If the condition evaluates to false, then the output and calculation of all lines until #ELSE or #ENDIF is suppressed.

At the moment the #ELSE statement reverses the output suppression between #IF and #ENDIF. Multiple #ELSEs are possible at the moment, but should not be relied upon in case the logic changes in subsequent versions.

Conditions cannot be nested, but conditions can be embedded in loops or be put around loops. If a condition is put around a loop, it does not prevent the processor from evaluating the loop, only the output and internal calculations are suppressed.

OperatorDescription
<lighter than
<=lighter or equal
>greater than
>=greater or equal
<>not equal
!=not equal
=equal
==equal

Calculations

Numeric variables allow some very simple calculations in place:
@VARONE+11@
@VARTWO-77@
In the above example the first line will be replaced by the amount of VARONE plus 11 and the second line by the amount of VARTWO minus 77.

For integer variables this works on the plain integer value. For money values it adds/subtracts cents.

More complex calculations can be done with the #CALC statement:

#CALC:TVAR/MONEY:VAR1 * VAR2 + 4
The above creates the temporary variable "@#TVAR@" that is the product of @VAR1@ and @VAR2@'s content plus 4. It is marked as a monetary value. Please note that the variables are not enclosed in "@".

Calculations are restricted to the operators below and are always done from left to right - more complex formulas require several lines. Tokens must be space separated. If no type or a non-existing type is requested INT is assumed. All calculations are done using 64bit signed integers. If the processor comes across an illegal token it sets the variable to "error".

Literals (above: "4") must be integers.

OperatorDescription
+adding
-subtracting
*multiplication
/division
%modulo
TypeDescription
INTinteger number
MONEYmonetary value (the number is interpreted as cents)
DATEa unix timestamp to be shown as date
TIMEa unix timestamp to be shown as its time component
DATETIMEa unix timestamp to be shown as date plus time

Newline Replacement

The #SETNEWLINE statement can be used to create a macro that will replace newline in variables:
#SETNEWLINE:</text:p><text:p text:style-name="Text_20_body">
The default is a single space character, which can be restored by using "#SETNEWLINE:" without parameters.

Generic Variables

There are a few variables that always exist:
VariableDescription
@TODAY@the current date
@NOW@the current time
@anyloop:ITERATION@for an active loop ("anyloop") the current iteration (0..n)

Localization

Per default all variables are localized before they get inserted into the document. To suppress localization prefix the variable with a "$"-sign (eg. @$TODAY@ instead of @TODAY@).

Event Summary

File name: eventsummary.odtt

Loops:
TICKETS - this loop iterates over the ticket price categories.
ORDERS - this loop iterates over all orders that contain tickets for this event.

Variables:
VariableDescription
@TITLE@title of the event
@ARTIST@artist of the event
@ROOM@room of the event
@START@start date and time in the currently active locale
@CAPACITY@maximum amount of tickets that can be sold
@RESERVED@tickets that are currently reserved for a seller
@BOUGHT@tickets that have been bought (used+unused)
@USED@tickets that have been used
@UNUSED@tickets that are still unused
@CANCELLED@tickets that were cancelled
@TOTALMONEY@the total amount of income for this event
@EVENTPRICE@the default price for this event
@TICKETS@the amount of ticket lines in the overview
@TICKETS:PRICE@the price of this category
@TICKETS:BOUGHT@used+unused
@TICKETS:USED@tickets from this category that have been used
@TICKETS:UNUSED@tickets from this category that were not used
@COMMENTS@the amount of (non-empty) comments attached to this event
@COMMENTS:ORDERID@the order-ID of this comment
@COMMENTS:CUSTOMERID@the ID of the customer this comment is attached to
@COMMENTS:CUSTOMER@the name of the customer this comment is attached to
@COMMENTS:TEXT@the text of the comment
@ORDERS@the amount of orders connected to this event
@ORDERS:ORDERID@the order-ID of this comment
@ORDERS:CUSTOMERID@the ID of the customer this comment is attached to
@ORDERS:CUSTOMER@the name of the customer this comment is attached to
@ORDERS:NUMTICKETS@number of tickets in the order that are for this event
@ORDERS:TICKETPRICE@the accumulated price of all tickets in that order for this event
@ORDERS:FULLPRICE@the full price of this order
@ORDERS:SHIPPING@description of the shipping method of this order
@ORDERS:SHIPPINGCOST@the full shipping costs for this order
@ORDERS:SHIPPINGCOSTWEIGHTED@the weighted shipping costs of this order (costs * ticketsforthisevent / ticketsintotal) - Warning: this may not add up correctly!
@ORDERS:SHIPPINGCOSTIFFIRST@contains the shipping costs if this event is the earliest in the order, zero otherwise
@ORDERS:SHIPPINGCOSTIFLAST@contains the shipping costs if this event is the last in the order, zero otherwise

Order Bills

File name: bill.odtt

Loops:
TICKETS - this loop iterates over each ticket in the order.
ACCTICKETS - this loop iterates over ticket categories in the order. Each category contains tickets for the same event with the same price.
ADDRESSLINES - this loop iterates over the lines of the address. (obsolete)
VOUCHERS - this loop iterates over all vouchers of the order.

Variables:
VariableDescription
@ORDERDATE@the date when this order has been generated
@ORDERDATETIME@the date and time when this order has been generated
@SENTDATE@the date when this order has been shipped
@SENTDATETIME@the date and time when this order has been shipped
@CUSTOMERID@the ID of the customer
@ORDERID@the ID of the order
@ADDRESS@the address of the customer
@FULLADDRESS@the name and address of the customer
@NAME@the name of the customer
@DELIVERYADDRESS@the address it is shipped to, if different from the customers address
@FINALADDRESS@equals DELIVERYADDRESS if it is non-empty, otherwise FULLADDRESS
@TOTALPRICE@the total price of the order
@AMOUNTPAID@the amount that has already been paid
@SELLER@the login ID of the seller (it is not recommended to use this)
@COMMENT@the comment in the order (it is not recommended to use this)
@AMOUNTTOPAY@the amount that still needs to be paid
@AMOUNTTOREFUND@the amount that has to be refunded
@SHIPPING@description of the shipping method used or empty string
@SHIPPINGPRICE@the costs for shipping
@TICKETS@the amount of tickets in the order
@TICKETS:PRICE@the price of this ticket
@TICKETS:ID@the ID of this ticket (barcode-string)
@TICKETS:TITLE@the title of the event for this ticket
@TICKETS:ARTIST@the artist of the event for this ticket
@TICKETS:DATE@the date of the event for this ticket
@TICKETS:STARTTIME@the date and start time of the event for this ticket
@TICKETS:ENDTIME@the end date and time of the event for this ticket
@TICKETS:ROOM@the room/place of the event for this ticket
@ACCTICKETS@the amount of distinct ticket types in the order
@ACCTICKETS:PRICE@the price of one ticket of this type
@ACCTICKETS:FULLPRICE@the accumulated price of all tickets of this type (PRICE*AMOUNT)
@ACCTICKETS:AMOUNT@the amount of tickets in this type
@ACCTICKETS:TITLE@the title of the event for this ticket type
@ACCTICKETS:ARTIST@the artist of the event for this ticket type
@ACCTICKETS:DATE@the date of the event for this ticket type
@ACCTICKETS:STARTTIME@the date and start time of the event for this ticket type
@ACCTICKETS:ENDTIME@the end date and time of the event for this ticket type
@ACCTICKETS:ROOM@the room/place of the event for this ticket type
@ADDRESSLINES@amount of lines that the address has (obsolete)
@ADDRESSLINES:LINE@current line in the address loop (obsolete)
@VOUCHERS@the amount of vouchers in the order
@VOUCHERS:PRICE@the price of this voucher
@VOUCHERS:VALUE@the (remaining) value of this voucher
@VOUCHERS:ID@the ID of this voucher