Teng Manual

Jan Adámek

Václav Blažek

Pavel Francírek

Ondřej Procházka

Štěpán Škrob


Table of Contents

Introduction
Description
Characterictics
Release Notes
1.0.13
Syntax
Basics
Comment
Types
Operators
Expression
Object
Dictionary
Variable
Conditions
Definition
Format
Fragment
Include
Debugging
Dictionary
Introduction
Structure
%disable
%enable
%expand
%maxincludedepth
Functions
date
escape
int
isnumber
len
nl2br
now
numformat
random
reorder
replace
round
sectotime
substr
unescape
urlescape
wordsubstr
C++ API
Requirements
Building
Compilation
FileWriter
Fragment
FragmentList
FragmentValue
StringWriter
Teng
Writer
Example
Python API
Requirements
Building
Types
Creating engine
Creating data root
Adding fragment
Generating page
Looking up dictionary
Examples
PHP API
Requirements
Building
Configuration
Types
teng_init
teng_release
teng_create_data_root
teng_release_data
teng_add_fragment
teng_page_string
teng_page_string_from_string
teng_dict_lookup
teng_list_content_types
Examples
Index

List of Tables

1. Operators overview
2. Date and time formating characters
3. PHP API configuration directives

List of Examples

1. Dictionary example
2. ‘date’ and ‘now’ functions example
3. ‘escape’ function example for ‘text/html’ content type
4. ‘int’ and ‘round’ functions example
5. ‘isnumber’ function example
6. ‘len’ function example
7. ‘nl2br’ function example
8. ‘numformat’ function example
9. ‘reorder’ function example
10. ‘replace’ function example
11. ‘sectotime’ function example
12. ‘substr’ function example
13. ‘unescape’ function example for ‘text/html’ content type
14. ‘urlescape’ function example
15. ‘wordsubstr’ function example
16. C++ API example
17. Python API example using Python built-in objects
18. Python API example using Teng native object
19. PHP API example using PHP native types
20. PHP API example using Teng native types (preferred)

Introduction

Description

Teng (Template Engine) is general purpose template tool. It’s primary C++ library but is also available as Python module and PHP extension. It composes result (web page, mail message, or any other text file) by combining input template with data supplied by application and optional configuration and localization (language) dictionary.

Characterictics

  • Separation of application code and design templates

  • Multiple templates inclusion

  • Content type independent

  • External dictionaries that can be language dependent

  • Caching of templates and dictionaries – automatic update on change

  • Possible data integrity control

  • API for C++, Python, and PHP

  • Binary library allowing simple creation of another API.

  • Easy to learn and easy to use

  • Well documented

  • And much more :-)

Release Notes

Table of Contents

1.0.13

1.0.13

What’s new

There were only a few changes since version 1.0.12, but three of them (the first three in the following list) was really important:

  • Teng now has lower memory footprint (and is faster) during compilation thanks to a very simple modification of ‘tengsyntax.yy’ file.

  • Written Manual that is up-to-date, vast, and in DocBook.

  • Created testing suite.

  • New operator ‘defined’ has been added.

  • New function ‘replace’ has been added.

  • New global Makefile.

  • New program ‘generate.py’ in ‘python’ directory for direct calling of ‘Teng::Teng_t::generatePage’ (resp. it’s Python counterpart).

  • Error reporting was changed:

    • Duplicate errors are suppressed.

    • Operator ‘exist’ does not raise an error when object does not exist.

Knowing issues

  • There are still some bugs that was not fixed

    • Reals with big exponents (over about 32) are converted to binary data (more).

    • Teng engine sometimes falls on SIGSEGV when out of memory and clearing cache.

    • Teng engine sometimes ommits reloading configuration (language independent) dictionary. This bug may be fixed and just hasn’t been marked as fixed.

  • Compilation and installation on Microsoft Windows was not tested and therefore may not work.

  • There is no description of testing suite files althrough the same files uses program ‘generate.py’.

Getting support

To report bugs and submit support and feature requests, use SourceForge.net Tracker.

[Important]Important

Before submitting support and/or feature request, think twice and read this Manual carefully. Maybe you will find the answer and/or feature you’re looking for there.

For more information see Teng Project web pages.

Syntax

Basics

Teng is case sensitive in all ways except for exactly specified exceptions.

Tags are enclosed by ‘<?teng’ and ‘?>’ marks.

[Tip]Tip

If you need to generate ‘<?teng’ tag, use ‘${"<?teng"}’. In SGML- or XML-based document use ‘&lt;?teng’ according to W3C’s recommendations.

Comment

<!-- comment -->
/* comment */

The first version is used outside teng commands, the second inside.

Comment will not be in output file.

If you want to make a SGML or XML comment, that will occure in output file, use <!--- comment ---> (with three dashes).

Types

Teng supports dynamic types, ie. every object can be used as if it has type of another one. Non-variable objects (fragments and dictionaries) cannot be converted from and to because there is no logical way how to do this.

If you try to convert an object from one type to another and this conversion is illogical (eg. converting string containing non-numeric characters to integer), an error is raised and a special type that can be converted to string "undefined" is returned.

The following definitions can be used to create objects:

"string"

Evalutes as string.

Strings can contain following escape characters:

\"

quote (‘"’)

\\

backslash (‘\’)

\n

line feed character (UNIX and POSIX line break)

\r

carriage return character (Apple through MacOS 9 and Commodore line break)

\r\n

carriage return and line feed character pair (DOS and Windows line break)

\t

a horizontal tab

\char

if ‘char’ is not one of above, it’s evaluted as itself

123

Evalutes as integer.

123.45

Evalutes as real (number with floating decimal point).

Integers and reals are called numerics. Every numeric is signed, ie. it can have negative value. However, there is no way how to define a numeric with negative value, because ‘-’ before number creates an expression and therefore is not a definition.

Strings and numerics are called variables.

fragment
dictionary

Fragment and dictionary types cannot be declared inside Teng scripts. Objects of these types are posted by calling application only.

Fragment and dictionary types are called non-variable objects.

Operators

Table 1. Operators overview

numericstringdescription
===~1 if equal, 0 otherwise
eq
!=!~1 if not equal, 0 otherwise
ne
>=none1 if greater or equal, 0 otherwise
ge
<=none1 if lesser or equal, 0 otherwise
le
>none1 if greater, 0 otherwise
gt
<none1 if lesser, 0 otherwise
lt
+++addition; string concatenation
-nonesubtraction
***multiplication; string repetition
/nonedivision
%nonemodulo
!!logical negation; 1 if false argument, 0 otherwise
&&&&logical AND; 1 if both arguments are true, 0 otherwise
||||logical OR; 1 if at least one argument is true, 0 otherwise
~nonebit negation (complement; each bit is set if argument has not the same bit set)
&nonebit AND (each bit is set if both arguments have the same bit set)
|nonebit OR (each bit is set if at least one argument has the same bit set)
^nonebit XOR (each bit is set if exactly one argument has the same bit set)

In logical operations, numeric 0, empty string and string "0" are false; other values are true.

integer defined(identifier identifier)

Checks whether object with identifier ‘identifier’ exists and has a value.

Returns 0 if object does not exist; is string or fragment and is empty; is numeric and is zero. Otehrwise returns 1.

[Important]Important

This operator is available since version 1.0.13 of Teng library.

integer exist(identifier identifier)

Checks whether object with identifier ‘identifier’ exists.

Returns one of following values:

0

such object does not exist or is an empty fragment

1

such object exists and is non-empty if a fragment

[Warning]Warning

Teng library version ≤ 1.0.12 also raises an error if such object does not exist; this is no more since version 1.0.13

Expression

<?teng expr expression ?>
${expression}

Evalutes ‘expression’ and prints evaluted value.

[Tip]Tip

If you need to generate ‘${’, use ‘${"${"}’.

Object

Object is a named data entity. It can be either variable or fragment or dictionary. Each object’s identifier must be unique in its dictionary.

Object’s identifier can contain numbers, letters and underscores. It cannot begin with number. It must be at least one character long. Maximal length of it is unlimited.

Object’s identifier can also contain dots. Dots in identifiers have special meaning:

name

unqualified object identifier

Selects object in local context.

context.name

partialy qualified object identifier

Selects object in context of objectcontext’, which is in local context.

.context.name

fully qualified object identifier

Selects object in context of objectcontext’, which is in global (ie. top-most) context.

[Note]Note

If fragment is used for specifying context, it’s first dictionary (‘iteration’) is used.

Dictionary

Dictionary is a set of objects and their identifiers. Dictionary can contain another dictionary only as an automatic object.

Each context is a dictionary, each fragment is an array of dictionaries.

For more information on specifying dictionaries, see API documentation and preface ‘dictionary’.

Variable

<?teng expr $variable?>
${variable}
$variable

Prints value of variable with identifier ‘variable’. If this identifier is either undefined or belongs to non-variable object, an error is raised.

<?teng expr #variable?>
#{variable}
#variable

Prints value of variable from external dictionary with identifier ‘variable’. If this identifier is not defined in any dictionary, an error is raised.

<?teng expr @expression?>
${@expression}

Prints value of variable from external dictionary with identifier equal to evaluated ‘expression’. If this identifier is not defined in any dictionary, an error is raised.

For more information on identifiers see section ‘Object’.

[Tip]Tip

If you need to generate ‘$’ or ‘#’, use ‘${"$"}’ or ‘${"#"}’.

Conditions

<?teng if expression ?>

Begins ‘if’ conditional block and its first part.

This part is skipped if ‘expression’ is empty string, string "0", or numeric 0.

<?teng elseif expression ?>

Begins another part of ‘if’ condition block.

This part can be omitted and can occure multiple times in one conditional block.

This part is skipped if ‘expression’ is empty string, string "0", or numeric 0.

<?teng else ?>

Begins last part of ‘if’ conditional block.

This part can be omitted.

This part is executed if no other part was.

<?teng endif ?>

Terminates ‘if’ conditional block.

expression ? if_true : if_false

Returns ‘if_false’ if ‘expression’ is empty string, string "0", or numeric 0; otherwise returns ‘if_true’.

case(expression, key1, key2: value12, key3: value3, …, *: value_other)

Returns ‘value12’ if ‘expression’ has value ‘key1’ or ‘key2’, ‘vaule3’ if ‘expression’ has value ‘key3’, or ‘value_other’ if nothing before matches.

Case operator can have any number of keys and values. It can also contain at most one wildcard key (‘*’).

Key can be variable definition only. If the key is numeric, it can have one plus or minus sign before its definition to define negative or possitive number.

If a key is matched, a value after first following colon is returned and searching is terminated.

Any key can occure multiple times, however only the first match will be evaluted. Also if wildcard key is placed before some more keys, these keys are never evaluted.

expression’ and values after colons are never used as keys.

Definition

<?teng set variable=expression ?>

Defines a variable with value equal to evaluated ‘expression’.

If such variable already exists, reset its value to evaluated ‘expression’.

If an object with identifier equal to ‘variable’ was submitted by the calling application, its value remains and an error is raised.

If defined inside fragment block, this variable is available only in current fragment block’s iteration.

Format

<?teng format space="value" ?>

Begins whitespace formating block.

Child whitespace formating block overrides its parent whitespace formating block.

Outside any whitespace formating block is no whitespace formating at all like in whitespace formating block with ‘space’ equal to ‘noformat’.

Parameter ‘space’ sets its type. Possible values are one of the following:

nowhite

removes all whitespaces

onespace

collapse all whitespace characters into one space

striplines

removes all whitespaces at the beginning and end of each line except for line breaks

joinlines

removes all whitespaces at the beginning and end of each line including line breaks

nowhitelines

removes all empty lines

noformat

does no formating at all (useful when a part of formatting block should not be formated)

<?teng endformat ?>

Terminates whitespace formating block.

Fragment

<?teng frag identifier ?>

Begins fragment block.

Each fragment is an array of dictionaries.

The fragment block is executed once for each dictionary (this is called ‘iteration’).

There are some automatic objects defined for each fragment:

$_count

Total number of iterations (dictionaries in fragment array). This is an integer.

$_number

Actual count of iterations begining with 0. This is an integer.

0 ≤ $_number < $_count.

This object exists only in fragment block.

$_this

Actual fragment context, ie. ‘$_numberth dictionary of fragment array. This is a dictionary.

This object exists only in fragment block.

<?teng endfragment ?>

Terminates fragment block.

For more information on identifiers see section ‘Object’.

Include

<?teng include file="filename" ?>

Includes other template file.

The included file will be compiled and cached as it is used directly.

Maximal include (‘nesting’) depth is limited due to possible problems with infinite recursion (default limit is 10, can be changed by dictionary command ‘%maxincludedepth’).

Debugging

To debug Teng engine and templates, there are two commands beside error logging facility (as documented in function ‘Teng::Teng_t::generatePage’):

<?teng debug?>

If configuration flag ‘debug’ is enabled, prints debugging information; otherwise ignored.

<?teng bytecode?>

If configuration flag ‘bytecode’ is enabled, prints disassembled bytecode; otherwise ignored.

[Note]Note

This command is useful only when debugging Teng compiler and processor. Do not expect to get anything useful if debugging templates unless you know how Teng processor works.

Dictionary

This preface is about external dictionaries (dictionaries specified in files). For more information on dictionaries see ‘syntax’ preface.

Introduction

Dictionaries are powerful way how to specify static data for your templates that are independent on calling application. Therefore dictionaries are very easy way to alter generated pages’ content and your news team may be absolutely lames in programming (there will need only a text editor and next section).

Moreover dictionaries brings the possibility to use one template and one application for multiple languages. Simply make your application capable of dynamically selecting language code and than to create new language mutation, just create new dictionary. No recompilation, no server restart.

On top of that, dictionaries gained the possibility to control Teng configuration. Once more no recompilation, no server restart. And it can even configure things, that can be otherwise configured only by modifying source and recompilation of Teng library and APIs, or can’t be configure otherwise at all.

If there are both language dependent and language independent dictionaries specified, language dependent dictionary fields overrides language independent dictionary fields.

With Teng dictionaries, it’s easy and fast to create dynamic content, multilingual pages, and debug your templates.

Structure

Each dictionary line begins with either identifier or a command, separeted by space from other content. Identifier must be unqualified.

Commands begin with ‘%’ sign and are used to modify Teng configuration. Commands can be only in configuration (language independent) dictionary; commands in language dependent dictionary are ignored.

Identifiers begin with a letter or underscore. Everything after first space is taken as value of variable specified by the identifier.

Example 1. Dictionary example

house The United States House of Representatives
months |January|February|March|April|May|June|July|August|September|October|November|December|
%enable debug

%disable

%disable flag

Disables configuration flag ‘flag’. This command overrides configuration specified by calling application.

For list of available flags, see ‘%enable’.

%enable

%enable flag

Enables configuration flag ‘flag’. This command overrides configuration specified by calling application.

Following flags are defined:

bytecode

Enables printing disassembled bytecode on place specified by ‘bytecode’ command.

This flags is disabled by default.

debug

Enables printing debugging information on place specified by ‘debug’ command.

This flags is disabled by default.

errorfragment

Creates error fragment ‘._error’ that enables access to all errors generated during template processing.

Each iteration has the following variables:

integer status

Severity of the error.

string filename

Filename of template in which the error has occured.

integer line

Line on which the error occured.

integer column

Column in which the error occured.

string message

Description of the error.

This flags is disabled by default.

[Important]Important

Since version 1.0.13 of Teng library, duplicate error messages (ie. all their fields match) are supressed. Previous versions reported every occurence of every error.

logtooutput

Prints error log to output at the end of the document as comment.

This flags is disabled by default.

watchfiles

Watches for modifications of every files from which the template was compiled and recompiles it if any was modified.

This flags is enabled by default. Disabling this flag slightly increases performance.

%expand

%expand state

Enables or disables variable expansions inside dictionary, ie. replacing ‘#{identifier}’ by item from dictionary with identifier ‘identifier’.

state’ can be either ‘on’ or ‘off’.

Expansions are disabled by default.

%maxincludedepth

%maxincludedepth limit

Modifies maximal include (‘nesting’) depth to ‘limit’.

This command is very useful when including many templates.

Functions

date

string date(string  format,
 integer  timestamp,
 string  setup = "")

Formats ‘timestamp’ according to locale settings.

The following characters escaped by ‘%’ in ‘string’ are replaced:

Table 2. Date and time formating characters

characterdescriptionexample for Sunday January 2nd, 2005 16:05:06 CET
%%literal ‘%’%
%aabbreviated weekday nameSun
%Afull weekday nameSunday
%babbreviated month nameJan
%Bfull month nameJanuary
%dday of month with leading zero02
%eday of month without leading zero2
%halias for ‘%b’Jan
%Hhour with leading zero using a 24-hour clock16
%Ihour with leading zero using a 12-hour clock04
%jday of year with leading zeros002
%khour without leading zero using a 24-hour clock16
%lhour without leading zero using a 12-hour clock4
%mmonth with leading zero01
%Mminute with leading zero05
%nmonth without leading zero1
%p‘AM’ or ‘PM’ or corresponding string as defined in localesPM
%Psame as ‘%p’, but lower casepm
%r12-hour time; same as ‘%I:%M:%S %p’04:05:06 PM
%R24-hour time without seconds; same as ‘%H:%M’16:05
%Sseconds with leading zero06
%T24-hour time; same as ‘%H:%M:%S’16:05:06
%uweekday as number; starting with 1 from Monday7
%wnumber of weekday staring with 0 for Sunday0
%ytwo-digit year05
%Yfour-digit year2005

Any other character escaped by ‘%’ among the ones above is print as unescaped.

[Warning]Warning

Sun Solaris seems to start ‘%u’ from Sunday althrough ISO 9899:1999 (current ISO C standard) clearly specifies that is should be Monday.

setup’ can specify month and weekday names in this format:

|January|February|…|December|Jan|Feb|…|Dec|Sunday|Monday|…|Saturday|Sun|Mon|…|Sat|

If this argument is not set or the name was not found (there are not enough fields), default as specified by locale is used.

Because ‘timestamp’ is integer, its value can be negative (therefore it can provide dates before UNIX epoch); however on some platforms (at least Microsoft Windows and some old Unices) built-in formating functions do not support this.

Example 2. ‘date’ and ‘now’ functions example

${date("%a %b %d %T %Y", now())}
Wed Jun 28 19:06:52 2006

escape

string escape(string string)

Escapes ‘string’ according to current content type.

This function‘s inverse function is ‘unescape’ function.

Example 3. ‘escape’ function example for ‘text/html’ content type

${escape("<?teng")}
&lt;?teng

int

integer int(string number)

Returns ‘number’ with chopped decimal values.

If you want to round numeric, see round.

Example 4. ‘int’ and ‘round’ functions example

${int("12" ++ "3.6") + 4}
${round("12" ++ "3.6", 0) + 4}
${int(round("12" ++ "3.6", 0)) + 4}
127
128.0
128

isnumber

integer isnumber(integer value)

integer isnumber(real value)

integer isnumber(string value)

Returns 1 if ‘value’ is numeric; otherwise returns 0.

Example 5. ‘isnumber’ function example

${isnumber("12")}
${isnumber(12)}
0
1

len

integer len(string string)

Returns length of ‘string’ in characters.

Example 6. ‘len’ function example

${len("12")}
${len(12)}
2
2

nl2br

string nl2br(string string)

Inserts ‘<br />’ after each occurence of line feed character (UNIX and POSIX line break) in ‘string’.

Because DOS and Microsoft Windows uses carriage return and line feed character pair for line breaking, this function is also DOS and Microsoft Windows compatible. This is also the reason why ‘<br />’ is inserted after line feed character rather than before.

[Warning]Warning

Because operating systems from Apple Computers through MacOS 9 and Commodores uses carriage return character for line breaking, this function won’t work as expected on these platforms. Use function ‘replace’ to replace carriage return characters by line feed characters.

Example 7. ‘nl2br’ function example

${nl2br("a\nb")}
a
<br />b

now

real now()

Returns current time stamp with precission of microsecond.

For example see example of function ‘date’.

numformat

string numformat(real  number,
 integer  precision,
 string  decimal = ".",
 string  thousand = "")

Formats numeric using ‘decimal’ as decimal and ‘thousand’ as thousand separator. Numeric is rounded to precision of ‘precision’.

Example 8. ‘numformat’ function example

${numformat("12345.67", 1, ".", ",")}
${numformat(12345.67, 0) == int(12345.67)}
12,345.7
0

random

integer random(integer number)

Returns random integer from interval <0, ‘number’).

reorder

string reorder(string string, …)

Returns string with numbers escaped by ‘%’ replaced by numberth parameter.

Each escaped number can be used more than once. There can also be some numbers ommited.

If there are not enough parameters, an error is raised and all escaped numbers without corresponding parameters are left.

[Warning]Warning

If there are too many parameters, all escaped numbers are replaced and no error is raised, so if ‘reorder’ function does not what you expect, check whether all parameters are used.

Example 9. ‘reorder’ function example

${reorder("%2;%3;%1", 1, 2, 3)}
${reorder("%2;%1", 1)}
${reorder("%3;%1;%3", 1, 2, 3)}
2;3;1
%2;1
3;1;3

Runtime: reorder(): invalid or missing index in format '%2'. @ 2:22
Runtime: Function 'reorder()' call failed @ 2:22

replace

string replace(string  text,
 string  out,
 string  in)

Returns ‘text’ with all occurences of ‘out’ replaced with ‘in’.

[Important]Important

This function is available since version 1.0.13 of Teng library.

Example 10. ‘replace’ function example

${replace("aoutboutcdeoutfg", "out", "in")}
ainbincdeinfg

round

real round(real number, integer precision)

Returns ‘number’ rounded to precision of ‘precision’.

If you want to floor the number, see function ‘int’.

For example see example of function ‘int’.

sectotime

string sectotime(integer number)

Takes ‘number’ as seconds and returns ‘H:MM:SS’ formated string.

[Note]Note

This function was originally called ‘sec_to_time’. Althrough this name of this function still exists, it is deprecated and you should not use it.

Example 11. ‘sectotime’ function example

${sectotime(123)}
${sectotime(123456789)}
0:02:03
34293:33:09

substr

string substr(string  text,
 integer  from,
 integer  to,
 string  prefix = "",
 string  suffix = "")

Returns substring of stringtext’ beginning after ‘fromth and ending with ‘toth character.

If ‘from’ or ‘to’ are negative, they choose -‘fromth, resp. -‘toth character from the end of the ‘text’.

If the character specified by ‘to’ is before or the same character as specified by ‘from’, returns an empty string.

Appends ‘suffix’ at the end of the substring.

If ‘from’ does not choose first character, prepends ‘prefix’ at the beginning of the substring.

If you want to cut substring at whole worlds, see function ‘wordsubstr’.

[Warning]Warning

Compared to C++’s and PHP’s ‘substr’ functions, this function does not take length of substring as its third argument and has this argument required.

Example 12. ‘substr’ function example

${substr("abcdef", -5, 5, "gh", "ij")}
${substr(123456, 0, -1, "gh", "ij")}
${substr("abcdef", 1, 0, "gh", "ij")}
ghbcdeij
12345ij
ghij

unescape

string unescape(string string)

Replaces escape characters from ‘string’ with their values according to current content type.

This function is an inverse function of ‘escape’ function.

Example 13. ‘unescape’ function example for ‘text/html’ content type

${unescape("&lt;?teng")}
<?teng

urlescape

string urlescape(string string)

Escapes ‘string’ according to RFC 1738, so it can be used in URL.

Example 14. ‘urlescape’ function example

${urlescape("<?teng")}
%3C%3Fteng

wordsubstr

string wordsubstr(string  text,
 integer  from,
 integer  to,
 string  prefix = "",
 string  suffix = "")

Returns substring of stringtext’ beginning after ‘fromth and ending with ‘toth character. Leading and tailing whitespaces are removed. Incomplete words are completed.

[Note]Note

This function was originally called ‘substr_word’. Althrough this name of this function still exists, it is deprecated and you should not use it.

Basic whitespaces (space, tab, carriage return, and line feed characters) are recognized as word delimiters. A word must have at least one non-whitespace character.

If ‘from’ or ‘to’ are negative, they choose -‘fromth, resp. -‘toth character from the end of the ‘text’.

If the character specified by ‘to’ is before or the same character as specified by ‘from’, returns an empty string.

Appends ‘suffix’ at the end of the substring.

If ‘from’ does not choose first character, prepends ‘prefix’ at the beginning of the substring.

This function is quite similar to function ‘substr’.

Example 15. ‘wordsubstr’ function example

${wordsubstr("abc def", 0, 5)}
"${wordsubstr("   abc   def   ", 1, -1)}"
abc def
"abc   def"

C++ API

Requirements

To use Teng C++ API, you need woking POSIX-compatible C++ compiler compliant to ISO 14882:1998 (ISO C++) with STL. Moreover you need to build the Teng library.

The following compilers are known to work correctly:

  • GCC 3 from version 2.95

  • GCC 4 from version 4.0

[Note]Note

This library might work in Microsoft Windows under Cygwin or Mingw32, althrough this was never tested.

Building

To build Teng library you need woking POSIX-compatible C++ compiler compliant to ISO 14882:1998 (ISO C++) with STL, Bourne-compatible shell and POSIX-compatible make.

Follow this procedure to build Teng library and prepare Teng C++ API on your system:

Procedure 1. Building Teng library

  1. Unpack Teng library source into a build directory, eg. ‘/usr/local/src/teng’.

  2. Enter the C++ API build directory:

    $ cd <build_directory>/teng
  3. Configure Teng library Makefile:

    $ ./configure
    [Tip]Tip

    You can change installation root (defaults to ‘/usr/local’) by invoking:

    $ ./configure --prefix=<installation_root>
    [Warning]Warning

    If you use exotic path, your compiler may not find Teng library. If so, you’ll need typing its path manually.

    [Tip]Tip

    For list of all configurable settings type:

    $ ./configure --help
  4. Compile the library:

    $ make
    [Tip]Tip

    You may suppress printing commands as they are executed by invoking:

    $ make -s

    Errors are still reported and do terminate compiling. There will be no output if no error occures.

    Teng libraries will be built in ‘<build_directory>/teng/src/.libs/libteng.a’ and ‘<build_directory>/teng/src/.libs/libteng.so.<version>’.

  5. Install Teng library and its header files:

    $ su -c 'make install'
    [Note]Note

    If you’re already logged in as super user (usualy called ‘root’), type:

    # make install

Compilation

To compile programs using Teng C++ API, follow the following procedure:

Procedure 2. Compiling a program using Teng C++ API

  1. Build and install Teng library.

  2. Include Teng C++ API header file.

    #include <teng.h>
  3. Write your program.

  4. Compile your program modules using your favourite compiler. You should compile your program modules by the same or compatible compiler as you used to build the Teng library.

  5. Link your program using your favourite compiler compatible linker. Append to this linker a parameter specifying that you want to include Teng library (‘libteng’).

    [Note]Note

    When linking with GCC, the ‘lib’ prefix should be omitted, therefore specify Teng library as ‘teng’.

    $ g++ -o program -lteng module2.o module2.o module3.o
  6. Execute your program. You will need the Teng shared library (‘libteng.so.1’) on every computer you want to run your program if you specify you want to build dynamic version of Teng library when configuring compilation (default for POSIX systems).

    [Warning]Warning

    You should not use the same shared library and your program binary on machines with different major version of libstdc++, otherwise your program may terminate on segmentation fault.

    This applies on programs using static version of Teng library too.

FileWriter

class Teng::FileWriter_t: public Teng::Writer_t {
  public FileWriter_t(const std::string & filename);
  public FileWriter_t(FILE * file);
  public virtual ~FileWriter_t();
  public virtual int write(const std::string & str);
  public virtual int write(const char * str);
  public virtual int write(const std::string & str, std::pair<std::string::const_iterator, std::string::const_iterator> interval);
  public virtual int flush();
}
public Teng::FileWriter_t::FileWriter_t(const std::string & filename);public Teng::FileWriter_t::FileWriter_t(FILE * file);

Creates new ‘Teng::FileWriter_t’ instance. It can use either a filename ‘filename’ or an opened file ‘file’.

If the file is invalid or cannot be opened, an error is written to log and ‘write’ and ‘flush’ methods will return non-zero error code.

[Warning]Warning

The second version of this method does not check whether the opened file is opened for writing. However this will cause an error when calling the ’write‘ method.

public virtual Teng::FileWriter_t::~FileWriter_t();

Destroys ‘Teng::FileWriter_t’ instance. The output buffer is flushed and the file is closed if this instance was created by the first variant of constructor.

public virtual int Teng::FileWriter_t::write(const std::string & str);public virtual int Teng::FileWriter_t::write(const char * str);public virtual int Teng::FileWriter_t::write(const std::string & str, std::pair<std::string::const_iterator, std::string::const_iterator> interval);

Writes to the output file.

If the third version is called, the part of the string that is bounded by the iterators pair is written to output file.

Returns zero if no error, otherwise returns non-zero error code.

When the constructor either failed to open the output file or got an invalid file handler, an error occures every time this function is called.

public virtual int Teng::FileWriter_t::flush();

Flushes the output buffer.

Returns zero if no error, otherwise returns non-zero error code.

When the constructor either failed to open the output file or got an invalid file handler, an error occures every time this function is called.

Fragment

class Teng::Fragment_t: public std::map<std::string, Teng::FragmentValue_t *> {
  public Fragment_t();
  public ~Fragment_t();
  public void addVariable(const std::string & name, const std::string & value);
  public void addVariable(const std::string & name, const long int value);
  public void addVariable(const std::string & name, const double value);
  public Teng::Fragment_t & addFragment(const std::string & name);
  public Teng::FragmentList_t & addFragmentList(const std::string & name);
}
public Teng::Fragment_t::Fragment_t();

Creates new empty fragment.

public Teng::Fragment_t::~Fragment_t();

Destroys fragment and all of its entries.

public void Teng::Fragment_t::addVariable(const std::string & name, const std::string & value);public void Teng::Fragment_t::addVariable(const std::string & name, const long int value);public void Teng::Fragment_t::addVariable(const std::string & name, const double value);

Adds new variable ‘name’ with value ‘value’.

public Teng::Fragment_t & Teng::Fragment_t::addFragment(const std::string & name);

Creates new fragment in ‘Teng::FragmentList_t’ ‘name’. If this ‘Teng::FragmentList_t’ does not exist, it is created. If a value with name ‘name’ already exists, it’s changed to ‘Teng::FragmentList_t’.

public Teng::FragmentList_t & Teng::Fragment_t::addFragmentList(const std::string & name);

Creates new empty ‘Teng::FragmentList_tname and returns reference to it. If ‘Teng::FragmentList_t’ ‘name’ already exists, it’s returned the existing one instead of creating a new one. If a value with name ‘name’ already exists, it’s changed to ‘Teng::FragmentList_t’.

FragmentList

class Teng::FragmentList_t: public std::vector<Teng::Fragment_t *> {
  public FragmentList_t();
  public ~FragmentList_t();
  public Teng::Fragment_t & addFragment();
}
public Teng::FragmentList_t::FragmentList_t();

Creates new empty fragment list.

public Teng::FragmentList_t::~FragmentList_t();

Destroys fragment list and all of its fragments.

public Teng::Fragment_t & Teng::FragmentList_t::addFragment();

Adds new empty ‘Teng::Fragment_t’ and returns reference to it.

FragmentValue

class Teng::FragmentValue_t {
  public FragmentValue_t();
  public FragmentValue_t(const std::string & value);
  public FragmentValue_t(long int value);
  public FragmentValue_t(double value);
  public ~FragmentValue_t();
  public Teng::Fragment_t & addFragment();
  public std::string value;
  public Teng::FragmentList_t * nestedFragments;
}
public Teng::FragmentValue_t::FragmentValue_t();public Teng::FragmentValue_t::FragmentValue_t(const std::string & value);public Teng::FragmentValue_t::FragmentValue_t(long int value);public Teng::FragmentValue_t::FragmentValue_t(double value);

Creates new fragment value; either empty or with given ‘value’. It is converted to ‘std::string’ if not ‘std::string’.

public Teng::FragmentValue_t::~FragmentValue_t();

Destroys fragment value. If ‘nestedFragments’ is non-zero, destroys it.

public TengFragment_t & Teng::FragmentValue_t::addFragment();

Adds new ‘Teng::Fragment_t’ to ‘nestedFragments’. If ‘nestedFragments’ is zero, it is created and value type of this ‘Teng::FragmentValue_t’ instance is changed.

public std::string value;

If ‘nestedFragments’ is zero, value of this ‘Teng::FragmentValue_t’ instance; non-sense otherwise.

public Teng::FragmentList_t * nestedFragments;

If non-zero, pointer to ‘Teng::FragmentList_t’.

StringWriter

class Teng::StringWriter_t: public Teng::Writer_t {
  public StringWriter_t(std::string & str);
  public virtual int write(const std::string & str);
  public virtual int write(const char * str);
  public virtual int write(const std::string & str, std::pair<std::string::const_iterator, std::string::const_iterator> interval);
  public virtual inline int flush();
}
public Teng::StringWriter_t::StringWriter_t(std::string & str);

Creates new ‘Teng::StringWriter_t’ instance. The output will be written to string ‘str’.

public virtual int Teng::StringWriter_t::write(const std::string & str);public virtual int Teng::StringWriter_t::write(const char * str);public virtual int Teng::StringWriter_t::write(const std::string & str, std::pair<std::string::const_iterator, std::string::const_iterator> interval);

Writes to the output string.

If the third version is called, the part of the string that is bounded by the iterators pair is written to output string.

Returns zero.

public virtual inline int Teng::StringWriter_t::flush();

Does nothing and returns zero.

Teng

class Teng::Teng_t {
  public Teng_t(const std::string & root, int logMode= 0, bool validate= false);
  public ~Teng_t();
  public int generatePage(const std::string & templateFilename, const std::string & skin, const std::string & dataDefinition, const std::string & dictionary, const std::string & language, const std::string & configuration, const std::string & contentType, const std::string & encoding, const TengFragment_t & date, const TengWriter_t & writer, const Teng::Error_t & err);
  public int generatePage(const std::string & templateString, const std::string & dataDefinition, const std::string & dictionary, const std::string & language, const std::string & param, const std::string & contentType, const std::string & encoding, const TengFragment_t & date, const Teng::Writer_t & writer, const Teng::Error_t & err);
  public int dictionaryLookup(const std::string & dictionary, const std::string & language, const std::string & key, std::string & value);
  static voidlistSupportedContentTypes(std::vector<std::pair<std::string, std::string> > & supported);
}
public Teng::Teng_t::Teng_t(const std::string & root, int logMode= 0, bool validate= false);

Creates new Teng engine with its own template and directory cache.

root

Defines root for relative paths (ie. paths not starting with ‘/’).

logMode

Sets the mode of errors logging. It can be zero or OR-ed one or more of the following values:

Teng_t::LM_LOG_TO_OUTPUT

If this bit is set, the error log will be appended at the end of the generated page.

Teng_t::LM_ERROR_FRAGMENT

If this bit is set, the special fragment ‘._error‘ will be accesible from the template.

For description of this fragment see command ‘%enable errorfragment’ of dictionary.

[Important]Important

Specifying this flags in the Teng engine constructor is deprecated by dictionary command ‘%enable’.

validate

If true, the template and supplied data will be validated against data definition if supplied in ‘generatePage’.

[Important]Important

Data definition has been deprecated and is ignored.

public int Teng::Teng_t::generatePage(const std::string & templateFilename, const std::string & skin, const std::string & dataDefinition, const std::string & dictionary, const std::string & language, const std::string & configuration, const std::string & contentType, const std::string & encoding, const Teng::Fragment_t & date, const Teng::Writer_t & writer, const Teng::Error_t & err);public int Teng::Teng_t::generatePage(const std::string & templateString, const std::string & dataDefinition, const std::string & dictionary, const std::string & language, const std::string & param, const std::string & contentType, const std::string & encoding, const Teng::Fragment_t & date, const Teng::Writer_t & writer, const Teng::Error_t & err);

Launches page generation. First all dictionaries are read and parsed, then all templates are read, parsed and comipled, and finally the generated bytecode is executed.

If there is aleready a bytecode for the template, it is only checked whether the bytecode is fresh enough (ie. bytecode generation time is greater than template last modification time). This is performed only when executing template from external file.

Returns the highest level of encountered errors or zero if no errors.

templateFilename

Filename of an external template.

skin

Skin of the external template. If not empty, inserts the skin name delimited with a dot before last dot in template filename (works similar to ‘dictionary’ and ‘language’ pair).

[Important]Important

For HTML, XHTML, and XML, skinning is deprecated by CSS and XSLT.

templateString

Template supplied as string. This version is not recommended because the template is compiled every time it is called.

dataDefinition

Filename of an external data definition. It is used only when ‘validate’ supplied to ‘Teng::Teng_t::Teng_t’ is true. Otherwise it is ignored.

[Important]Important

Data definition has been deprecated and is ignored.

dictionary

Filename of dictionary without language code.

The following rules are used to select dictionary filename:

  • language’ is empty: ‘dictionary’ is used as searched dictionary filename.

  • language’ is non-empty and ‘dictionary’ contains dot in filename: ‘language’ is inserted after a dot which is inserted before the last dot in ‘dictionary’, eg. ‘dictionary’ ‘p.a.t.h/file.template.dict’ become ‘p.a.t.h/file.template.language.dict’ and is used as searched dictionary filename.

  • language’ is non-empty and ‘dictionary’ does not contain dot in filename: ‘language’ is inserted after a dot which is inserted at the end of ‘dictionary’, eg. ‘p.a.t.h/template’ become ‘p.a.t.h/template.language’ and is used as searched dictionary filename.

language

Language of dictionary. See ‘dictionary’ for more information.

configFilename

Filename of configuration file. It is language-independent dictionary.

contentType

Content type of the generated document. It is used for data escaping and comments.

encoding

Encoding of input data. It is used by string manipulating functions. If not ‘UTF-8’, strings are treat as octet strings with fixed character length (ie. one octet per one character).

data

Root fragment of objects data.

writer

Output character device. See class ‘Teng::Writer_t’.

err

Error log. Use currently undocumented class ‘Teng::Error_t’.

public int Teng::Teng_t::dictionaryLookup(const std::string & dictionary, const std::string & language, const std::string & key, std::string & value);

Search dictionary ‘dict’ of language ‘language’ for an entry with key ‘key’. The same progress as for ‘dictionary’ and ‘language’ pair in ‘Teng_t::Teng_t::generatePage’ are applied.

Returns zero if the entry was found, non-zero number otherwise.

If returned zero, ‘value’ will contain value of the entry.

static voidTeng::Teng_t::listSupportedContentTypes(std::vector<std::pair<std::string, std::string> > & supported);

Returns a list of supported content types in format ‘std::pair(content_type, comment)’.

Writer

class Teng::Writer_t {
  public inline Writer_t();
  public inline virtual ~Writer_t();
  public virtual int write(const std::string & str);
  public virtual int write(const char * str);
  public virtual int write(const std::string & str, std::pair<std::string::const_iterator, std::string::const_iterator> interval);
  public virtual int flush();
  public const const Teng::Error_t & getErrors();
  protected Teng::Error_t err;
}

This class is virtual; for practical use either derive this class or use ‘Teng::FileWriter_t’ or ‘Teng::StringWriter_t’.

public inline Teng::Writer_t::Writer_t();

Creates new ‘Teng::Writer_t’ instance. The derived class should open the output if this is necessary.

[Note]Note

This method should not raise an exception; it should add an error to its error log instead and return non-zero error code when calling ‘write’ or ‘flush’ methods.

public inline virtual Teng::Writer_t::~Writer_t();

Destroys ‘Teng::Writer_t’ instance. The derived class should call ‘flush’ method and close the output if this is necessary.

public virtual int Teng::Writer_t::write(const std::string & str);public virtual int Teng::Writer_t::write(const char * str);public virtual int Teng::Writer_t::write(const std::string & str, std::pair<std::string::const_iterator, std::string::const_iterator> interval);

Pure virtual methods for writing to output.

If the third version is called, the derived class should write to output the part of the string ‘str’ that is bounded by the iterators pair ‘interval’.

Returns zero if no error, otherwise returns non-zero error code.

public virtual int Teng::Writer_t::flush();

Pure virtual method for flushing the output buffer.

If there is no output buffer, the derived class should define flush as inline and with no effect.

Returns zero if no error, otherwise returns non-zero error code.

public const const Teng::Error_t & Teng::Writer_t::getErrors();

Returns writing error log.

This function is used when ‘write’ or ‘flush’ returns non-zero error code.

protected Teng::Error_t err;

Protected error log; it is returned as constant by ‘getErrors’ method.

Example

This is a simple Teng C++ API example:

Example 16. C++ API example

#include <teng.h>

#include <stdio.h>
#include <string>

int main(int argc, char * argv[]) {
    static std::string characters[2] = { "A", "B" };

    // Define some template
    std::string templ = "<html>\n\
    <head>\n\
        <title>Example page</title>\n\
    </head>\n\
    <body>\n\
        <?teng frag row?><p>${rnum}\n\
            <?teng frag col?>${cnum} <?teng endfrag?>\n\
        </p><?teng endfrag?>\n\
    </body>\n\
</html>\n";

    // Create Teng engine
    Teng::Teng_t teng("", Teng::Teng_t::LM_LOG_TO_OUTPUT);

    // Root data fragment
    Teng::Fragment_t root;

    // Rows fragment list
    Teng::FragmentList_t &rowList = root.addFragmentList("row");

    // Create two rows
    for(int i = 0; i < 2; i++) {
        Teng::Fragment_t &row = rowList.addFragment();
        // Add variable ‘rnum’ (‘A’ or ‘B’)
        row.addVariable("rnum", characters[i]);
        // Create two columns
        for(int j = 1; j <= 2; j++) {
            Teng::Fragment_t &col = row.addFragment("col");
            // Add variable ‘cnum’ into ‘row’ (‘1’ or ‘2’)
            col.addVariable("cnum", (long int)j);
        }
    }

    // Output to standard output
    Teng::FileWriter_t writer(stdout);

    // Simple error log
    Teng::Error_t err;

    // Generate page
    return teng.generatePage(
        templ, // Template
        "", // Dictionary (none)
        "", // Language (none)
        "", // Configuration (none)
        "text/html", // Content type
        "utf-8", // Encoding
        root, // Root fragment
        writer, // Writer
        err // Error log
    );
}
<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>A
            1 2 3
        </p><p>B
            1 2 3
        </p>
    </body>
</html>

Python API

Requirements

To use Teng Python API, you need Python version at least 1.5. Python version at least 2.2 is strongly encouraged. Moreover you need to build and install the Teng Python module.

Building

To build Teng Python module, you need woking POSIX-compatible C++ compiler compliant to ISO 14882:1998 (ISO C++) with STL, Bourne-compatible shell, POSIX-compatible make, and at least one of supported versions of Python with Distutils modules (see Requirements).

Follow this procedure to build Teng Python module:

Procedure 3. Building Teng Python module

  1. Build and install C++ API.

    [Note]Note

    Teng Python module will compile and install even if you do not build and install C++ API, but importing module ‘teng’ will fail due to unsatisfied library dependencies.

  2. Enter the Teng Python module build directory:

    $ cd <build_directory>/python
  3. Build the module:

    $ ./setup.py build
  4. Install Teng Python module:

    $ su -c './setup.py install'
    [Note]Note

    If you’re already logged in as super user (usualy ‘root’), type:

    # ./setup.py install

Types

You can use either Python’s built-in objects or Teng native data object to specify data for Teng engine. However, you cannot mix them together.

When using Python’s built-in objects, the following rules is used:

  • Fragments are created from instances of object ‘dict’. Keys must be instances of object ‘str’ (other instances including instances of object ‘unicode’ are silently ignored and such data will not be supplied to the template). Values can be instances of objects ‘str’, ‘unicode’, ‘int’, and ‘float’; other objects instances are converted to instances of object ‘str’ before proceeding.

  • Nested fragments are mapped as instances of object ‘list’, or tuples (doesn’t matter which). This instance or tuple must contain instances of object ‘dict’. In the case you know there will be only one iteration of the fragment, you can supply instance of object ‘dict’ of the first iteration instead.

When using Teng native data object, the data are mapped as instances of object ‘Fragment’ in Teng Python module. The usage of object ‘Fragment’ is very similar to usage of C++ API’s ‘Teng::Fragment_t’ class.

[Warning]Warning

When using Teng native data object, there is a behaviour that violates Python conventions: deletion of root fragment deletes internal tree and invalidates all subnodes pointing to this tree and such subnodes cannot be used any more. However, deletion of non-root fragment doesn’t violate the convetions.

Creating engine

teng.Teng.__init__(teng.Teng  self,
 str  root = "",
 str  encoding = "utf-8",
 str  contentType = "",
 int  logToOutput = 0,
 int  errorFragment = 0,
 int  validate = 0)

Creates new Teng engine. Call it using:

engine = teng.Teng(…)

This method is encapsulation of C++ API’s ‘Teng::Teng_t’ class constructor.

root

Defines root for relative paths (ie. paths not starting with ‘/’).

encoding

Default encoding for processing the page if not specified in ‘generatePage’.

contentType

Default encoding for processing the page if not specified in ‘generatePage’.

logToOutput

If true, append error log to output.

[Important]Important

Specifying this flag in the Teng engine constructor is deprecated by dictionary command ‘%enable logtooutput’.

errorFragment

If ture, create ‘._error’ fragment for error log.

[Important]Important

Specifying this flag in the Teng engine constructor is deprecated by dictionary command ‘%enable errorfragment’.

For description of this fragment see command ‘%enable errorfragment’ of dictionary.

validate

If true, the template and supplied data will be validated against data definition if supplied in ‘generatePage’.

[Important]Important

Data definition has been deprecated and is ignored.

Creating data root

teng.Fragment teng.Teng.createDataRoot(teng.Teng  self,
 Object  data)

Creates ‘teng.Fragment’ instance for data root. Call it using:

engine.createDataRoot(…)
Object data

Either ‘dict’ or ‘teng.Fragment’ instance to populate the data root.

Adding fragment

teng.Fragment teng.Fragment.addFragment(teng.Fragment  self,
 str  name,
 Object  data)

Creates new ‘teng.Fragment’, populates it with data ‘data’, appends it to ‘self’, and finally returns it. Call it using:

fragment.addFragment(…)

This method is encapsulation of C++ API’s ‘Teng::FragmentList_t::addFragment’ method.

str name

Name of newly created fragment. If a fragment with name ‘name’ already exists, creates new iteration of it.

Object data

Either ‘dict’ or ‘teng.Fragment’ instance to populate the data root.

Generating page

dict teng.Teng.generatePage(teng.Teng  self,
 str  templateFilename = None,
 str  skin = None,
 str  templateString = None,
 str  dataDefinitionFilename = None,
 str  dictionaryFilename = None,
 str  language = None,
 str  configFilename = None,
 str  contentType = None,
 Object  data,
 str  outputFilename = None,
 FileObject  outputFile = None,
 str  encoding = None)

Generate a page. Call it using:

engine.generatePage(…)

This method is encapsulation of C++ API’s ‘Teng::Teng_t::generatePage’ method.

str templateFilename

Filename of template file. Conflicts with ‘templateString’.

str skin

Skin of template. Requires ‘templateFilename’.

[Important]Important

For HTML, XHTML, and XML, skinning is deprecated by CSS and XSLT.

For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

str templateString

String containing the template. Conflicts with ‘templateFilename’.

str dataDefinitionFilename

Filename of data definition file. Ignored if engine was created with validate equal to zero.

[Important]Important

Data definition has been deprecated and is ignored.

str dictionaryFilename

Filename of dictionary file without specified language. For more information see C++ API‘s ‘Teng::Teng_t’ class method ‘generatePage’.

str language

Language of dictionary file. Requires dictionaryFilename. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

str configFilename

Filename of file with configuration (language independent dictionary).

str contentType

Specifies generated page’s content-type. If not supplied, it is used the value supplied when creating engine.

Object data

Data tree. Either instance of ‘dict’ or ‘teng.Fragment’. For more information see Python API types section.

str outputFilename

Filename of file to which the output should be written. Conflicts with ‘outputFile’.

FileObject outputFile

File object instance to which the output should be written. This instance must have method ‘write’. Conflicts with ‘outputFilename’.

str encoding

Specifies generated page’s encoding. If not supplied, it is used the value supplied when creating engine.

Either ‘templateFilename’ or ‘templateString’ is required. If none is specified, an exception is raised.

Returned ‘dict’ object instance has the following values:

int status

The highest status code of generated errors; if no errors were generated, equals zero.

str output

Generated page.

Exists if neither ‘outputFilename’ nor ‘outputFile’ is specified.

tuple errorLog

Tuple of following ‘dict’ instances:

int level

Severity of the error.

str filename

Filename of template in which the error occured.

int line

Line on which the error occured.

int column

Column in which the error occured.

str message

Description of the error.

[Important]Important

Since version 1.0.13 of Teng library, duplicate error messages (ie. all their fields match) are supressed. Previous versions reported every occurence of every error.

Looking up dictionary

str teng.Teng.dictionaryLookup(str  dictionaryFilename,
 str  language,
 str  key)

Search dictionary dictionaryFilename of language language for an entry with key key. Call it using:

engine.dictionaryLookup(…)

This method is encapsulation of C++ API’s ‘Teng::Teng_t::dictionaryLookup’ method.

str dictionaryFilename

Filename of dictionary. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

str language

Language of dictionary. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

str key

Key of searched entry.

Returns ‘None’ if specified key does not exist in specified dictionary.

Examples

There are numerous ways to produce the reference example outputusing Teng Python module. Two significantly different options exist.

The first approach uses Python built-in objects to pass a data tree from a Python script to Teng.

Example 17. Python API example using Python built-in objects

#!/usr/bin/python
import teng

# Initialize Teng engine using default values
engine = teng.Teng()

# Create some data
data = { 'row' : []}
for i in range(ord('A'), ord('C')):
    row = {'rnum' : chr(i), 'col' : []}
    for j in range(0, 2):
        row['col'].append({'cnum' : j})
    data['row'].append(row)

# Define some template
template = '''<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <?teng frag row?><p>${rnum}
            <?teng frag col?>${cnum} <?teng endfrag?>
        </p><?teng endfrag?>
    </body>
</html>''';

# Generate page
print engine.generatePage(
    templateString = template,
    data = data,
    contentType = 'text/html',
    encoding = 'utf-8')['output']

# Delete Teng engine
del engine
<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>A
            0 1
        </p><p>B
            0 1
        </p>
    </body>
</html>

A different approach uses Teng native object to build the data tree:

Example 18. Python API example using Teng native object

#!/usr/bin/python
import teng

# Initialize Teng engine using default values
engine = teng.Teng()
data = engine.createDataRoot({})

for i in range(ord('A'), ord('C')):
    row = data.addFragment('row', {'rnum' : chr(i)})
    for j in range(0, 2):
        row.addFragment('col', {'cnum' : j})

# Define some template
template = '''<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <?teng frag row?><p>${rnum}
            <?teng frag col?>${cnum} <?teng endfrag?>
        </p><?teng endfrag?>
    </body>
</html>''';

# Generate page
print engine.generatePage(
    templateString = template,
    data = data,
    contentType = 'text/html',
    encoding = 'utf-8')['output']

# Delete Teng data and engine
del data
del engine
<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>A
            0 1
        </p><p>B
            0 1
        </p>
    </body>
</html>

PHP API

Requirements

To use Teng PHP extension, you need PHP4. Using at least version 4.1 is strongly encouraged. Moreover you need to build and install the Teng PHP extension.

Building

To build Teng PHP extension, you need woking POSIX-compatible C++ compiler compliant to ISO 14882:1998 (ISO C++) with STL, Bourne-compatible shell, POSIX-compatible make, and headers of PHP4 (see ‘Requirements’).

Follow this procedure to build Teng PHP extension:

Procedure 4. Building Teng PHP extension

  1. Build and install C++ API.

  2. Enter the Teng PHP extension build directory:

    $ cd <build_directory>/php4
  3. Prepare Teng PHP extension.

    $ ./bootstrap.sh
  4. Configure Teng PHP extension.

    $ ./configure
  5. Compile the extension:

    $ make
    [Tip]Tip

    You may suppress printing commands as they are executed by invoking:

    $ make -s

    Errors are still reported and do terminate compiling. There will be no output if no error occures.

  6. Install Teng PHP extension:

    $ su -c 'make install'
    [Note]Note

    If you’re already logged in as super user (usualy called ’root’), type:

    # make install
  7. To enable Teng PHP extension in your scripts, proceed one of the following steps:

    • Configure PHP to load Teng PHP extension.

      $ echo "extension teng.so" >><path_to_PHP_configuration>/php.ini
    • Load Teng PHP extension in your PHP script using the ‘dl’ function.

      [Warning]Warning

      This function may be disabled in your PHP configuration.

      dl("teng.so");
      [Note]Note

      Try to avoid using this step due to performance reasons as explained in ‘Types’ section.

  8. You can check whether the PHP loads Teng PHP extension by executing and examining:

    $ php -qi | lynx -stdin
    [Tip]Tip

    If you prefer using the ‘dl’ function, type:

    $ echo "<?php dl('teng.so'); phpinfo();?>" | php -q | lynx -stdin

    If you are unable to find a section called ‘teng’ then the Teng PHP extension is not loaded.

Configuration

Teng PHP extension can be configured using the following directives:

Table 3. PHP API configuration directives

DirectiveDefaultChangeableDescription
teng.template_rootNULLPHP_INI_ALLDefines the default root path used to access Teng templates and dictionaries.
teng.default_dictNULLPHP_INI_ALLSets the path to default language dictionary.
teng.default_langNULLPHP_INI_ALLSets the default language.
teng.default_configNULLPHP_INI_ALLSets the path to default template configuration.
teng.default_content_type’text/html‘PHP_INI_ALLSets the default content type. See the Teng section in ‘phpinfo’ output, or the output of ‘teng_list_content_types’ for suported content types.
teng.default_encoding‘utf-8’PHP_INI_ALLSets the default document encoding. Can be any encoding supported on your system.
teng.validation’Off‘PHP_INI_ALLThis boolean flag indicates whether Teng should perform template and application data validation.
[Important]Important

Data definition has been deprecated and is ignored.

teng.log_to_output‘Off’PHP_INI_ALLIf this boolean flag is set, teng logs parsing and runtime errors into content-type dependant comments on the output page.
teng.error_fragment‘Off’PHP_INI_ALLIf this boolean flag is set, a fragment called ‘._error’ is created containing all errors.
teng.default_skinNULLPHP_INI_ALLSets the default template skin.
[Important]Important

For HTML, XHTML, and XML, skinning is deprecated by CSS and XSLT.

Types

There are two types provided by the Teng extension.

The first type is the engine itself. This type instances are persistant and reuseable, ie. when ‘teng_init’ is invoked and there already was created a Teng engine with the same ‘template_root’ argument, it is reused. Instances of this type are freed when the Teng PHP module in unloaded, therefore using the ‘dl’ function for loading the Teng PHP extension causes significant performace decrease.

The second type is a fragment. Every fragment function is fully reentrant, ie. there can be multiple data trees in your scripts. Each fragment instance is discarded at the end of your script’s execution along with all data it carries.

teng_init

resource teng_init([string  $template_root])

Returns a new Teng engine resource pointing to new Teng engine instance.

$template_root’ sets the implicit path used to access templates and dictionaries. If not provided, the ‘teng.template_root’ configuration directive is used. If the directive is not set, the script‘s current working directory is used.

Teng engine instances are persistent and reuseable. If a Teng engine resource with given ‘$template_root’ was allocated before, this function returns a resource pointing to that instance. This allows the application to seamlessly cache templates and dictionaries across multiple HTTP requests and significantly increases performance.

teng_release

boolean teng_release(resource $teng)

Releases Teng engine resource ‘$teng’ that was previously created via ‘teng_init’.

This does not destroy the Teng engine instance this resource is pointing at.

Calling this function is not necessary but a good practice.

teng_create_data_root

resource teng_create_data_root([array  $data])

Allocates and initializes a new internal data tree and returns it as a new fragment resource. Internal data trees are a fast and convenient way to pass application data to Teng.

$data’ is an associative array with the content of data tree’s root fragment. This array may include nests of associative arrays that will be translated into fragment nests; however use rather ‘teng_add_fragment’ function. Every element with non-associative (ie. integer) key is silently ignored. If ‘$data’ is not provided, the root fragment is created empty.

teng_release_data

void teng_release_data(resource $root)

Removes the data tree pointed by ‘$root’ allocated by ‘teng_create_data_root’ from memory, clears all nested fragments, and invalides all corresponding fragment resources.

Calling this function is not necessary but a good practice.

teng_add_fragment

resource teng_add_fragment(resource  $parent,
 string  $name,
 [array  $data])

Appends a nested fragment into fragment pointed by ‘$parent’ and returns a new fragment resource pointing on the enwly created fragment.

$name’ is a name for the newly created nested fragment. If there is no fragment nest with name ‘$name’ in the fragment pointed by ‘$parent’, an empty fragment nest with name ‘$name’ is created before.

$data’ is an associative array with the content of data tree’s root fragment. This array may include nests of associative arrays that will be translated into fragment nests; however use rather ‘teng_add_fragment’ function. Every element with non-associative (ie. integer) key is silently ignored. If ‘$data’ is not provided, the root fragment is created empty.

teng_page_string

string teng_page_string(resource  $teng,
 string  $template_path,
 [(array|resource)  $data],
 [array  $options])

Invokes Teng engine pointed by ‘$teng’ to generate a page from template file ‘$template_path’ and returns the result as a string.

$data’ is either an associative array or a Teng root fragment resource created by ‘teng_create_data_root’. It holds the entire data tree. If this variable is an array, ‘teng_create_data_root’ is called before proceeding.

$options’ is an optional associative array holding options modifying Teng engine’s behavior in the process of page generation. Any number of options can be provided. Unknown and unexpected options are silently ignored.

The following options are recognized:

skin

Skin of template.

[Important]Important

For HTML, XHTML, and XML, skinning is deprecated by CSS and XSLT.

For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

dict

Filename of dictionary file without specified language. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

If not supplied, it is used the value supplied in configuration.

lang

Language of dictionary file. Requires ‘dict’. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

If not supplied, it is used the value supplied in configuration.

config

Filename of file with configuration (language independent dictionary).

definition

Filename of data definition file. Ignored if ‘teng.validate’ in configuration is not ‘On’.

[Important]Important

Data definition has been deprecated and is ignored.

content_type

Specifies generated page’s content-type. If not supplied, it is used the value supplied in configuration.

encoding

Specifies generated page’s encoding. If not supplied, it is used the value supplied in configuration.

Errors during page generation are logged into PHP error output.

teng_page_string_from_string

string teng_page_string_from_string(resource  $teng,
 string  $template,
 [(array|resource)  $data],
 [array  $options])

Invokes Teng engine pointed by ‘$teng’ to generate a page from template string ‘$template’ and returns the result as a string.

$data’ is either an associative array or a Teng root fragment resource created by ‘teng_create_data_root’. It holds the entire data tree. If this variable is an array, ’teng_create_data_root’ is called before proceeding.

$options’ is an optional associative array holding options modifying Teng engine’s behavior in the process of page generation. Any number of options can be provided. Unknown and unexpected options are silently ignored.

The following options are recognized:

dict

Filename of dictionary file without specified language. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

If not supplied, it is used the value supplied in configuration.

lang

Language of dictionary file. Requires ‘dict’. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.

If not supplied, it is used the value supplied in configuration.

config

Filename of file with configuration (language independent dictionary).

definition

Filename of data definition file. Ignored if ‘teng.validate’ in configuration is not ‘On’.

content_type

Specifies generated page’s content-type. If not supplied, it is used the value supplied in configuration.

encoding

Specifies generated page’s encoding. If not supplied, it is used the value supplied in configuration.

Errors during page generation are logged into PHP error output.

teng_dict_lookup

(string|boolean) teng_dict_lookup(resource  $teng,
 string  $key,
 [string  $dict],
 [string  $lang])

Looks up the dictionary ’$dict’ for language ‘$lang’ for a literal with key ‘$key’ using Teng engine pointed by ‘$teng’ and returns its value; returns FALSE if not found.

If ‘$dict’ and/or ‘$lang’ is not supplied, it is used the value supplied in configuration.

teng_list_content_types

array teng_list_content_types()

Returns an array where every key represents supported content type and every value its brief description.

Examples

There are numerous ways to produce the reference example outputusing Teng PHP extension. Two significantly different options exist.

The first approach uses PHP native types to pass a data tree from a PHP script to Teng.

Example 19. PHP API example using PHP native types

<?php
// Initialize Teng engine with default data root
$teng = teng_init();

// Sample template
$template = "<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <?teng frag row?><p>\${rnum}
            <?teng frag col?>\${cnum} <?teng endfrag?>
        </p><?teng endfrag?>
    </body>
</html>";

// Build data tree
$data = array("row" => array());
for($i = 'A'; $i < 'C'; $i++) {
    $row = array(
        "rnum" => $i,
        "col" => array()
    );
    for($j = 0; $j < 2; $j++)
        $row["col"][] = array("cnum" => $j); 
    $data["row"][] = $row;
}

// Generate page
echo teng_page_string_from_string(
    $teng,
    $template,
    $data,
    array(
        "content-type" => "text/html",
        "encoding" => "utf-8"
    )
);

// Release Teng engine
teng_release($teng);
?>
<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>A
            0 1
        </p><p>B
            0 1
        </p>
    </body>
</html>

A different approach uses Teng native types to build the data tree:

[Tip]Tip

This approach is preferred.

Example 20. PHP API example using Teng native types (preferred)

<?php
// Initialize Teng engine with default data root
$teng = teng_init();

// Sample template
$template = "<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <?teng frag row?><p>\${rnum}
            <?teng frag col?>\${cnum} <?teng endfrag?>
        </p><?teng endfrag?>
    </body>
</html>";

// Build data tree
$data = teng_create_data_root();
for($i = 'A'; $i < 'C'; $i++) {
    $row = teng_add_fragment($data, "row", array("rnum" => $i));
    for($j = 0; $j < 2; $j++)
        teng_add_fragment($row, "col", array("cnum" => $j));
}

// Generate page
echo teng_page_string_from_string(
    $teng,
    $template,
    $data,
    array(
        "content-type" => "text/html",
        "encoding" => "utf-8"
    )
);

// Release root fragment
teng_release_data($data);

// Release Teng engine
teng_release($teng);
?>
<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>A
            0 1
        </p><p>B
            0 1
        </p>
    </body>
</html>

Index

Symbols

$_count, Fragment
$_number, Fragment
$_this, Fragment

B

building
C++ API, Building
PHP API, Building
Python API, Building
bytecode (see debugging)

C

C++ API
building, Building
compilation, Compilation
example, Example
FileWriter_t, FileWriter
FragmentList_t, FragmentList
FragmentValue_t, FragmentValue
Fragment_t, Fragment
installation (see C++ API > building)
requirements, Requirements
StringWriter_t, StringWriter
Teng_t, Teng
Writer_t, Writer
case, Operators
class
FileWriter_t, FileWriter
FragmentList_t, FragmentList
FragmentValue_t, FragmentValue
Fragment_t, Fragment
StringWriter_t, StringWriter
Teng_t, Teng
Writer_t, Writer
comment, Comment
compilation
C++ API, Compilation
conditions, Conditions
configuration
PHP API, Configuration
context, Object

D

date, date
debug (see debugging)
debugging, Debugging
defined, Operators
definition, Definition
dictionary, Types
disable, %disable
enable, %enable
expand, %expand
introduction, Introduction
maxincludedepth, %maxincludedepth
structure, Structure
syntax, Dictionary

E

engine
Python API, Creating engine
escape, escape
examples
C++ API, Example
PHP API, Examples
Python API, Examples
exist, Operators
expression
syntax, Expression

F

FileWriter_t, FileWriter
format, Format
frag (see fragment)
fragment, Types, Fragment
context, Object
identifier, Object
FragmentList_t, FragmentList
FragmentValue_t, FragmentValue
Fragment_t, Fragment
function
date, date
escape, escape
int, int
isnumber, isnumber
len, len
nl2br, nl2br
now, now
numformat, numformat
random, random
reorder, reorder
replace, replace
round, round
sectotime, sectotime
sec_to_time (see sectotime)
substr, substr
substr_word (see wordsubstr)
unescape, unescape
urlescape, urlescape
wordsubstr, wordsubstr

I

identifier, Object
import (see include)
include, Include
installation
C++ API (see building > C++ API)
PHP API (see building > PHP API)
Python API (see building > Python API)
int, int
integer, Types
isnumber, isnumber

J

joinlines, Format

L

len, len

N

nesting, Include
nl2br, nl2br
noformat, Format
now, now
nowhite, Format
nowhitelines, Format
numeric, Types
numformat, numformat

O

object
context, Object
identifier, Object
syntax, Object
onespace, Format
operator, Operators
case, Operators
defined, Operators
exist, Operators
ternary, Operators

P

PHP API
building, Building
configuratio, Configuration
examples, Examples
installation (see PHP API > building)
requirements, Requirements
teng_add_fragment, teng_add_fragment
teng_create_data_root, teng_create_data_root
teng_dict_lookup, teng_dict_lookup
teng_init, teng_init
teng_list_content_types, teng_list_content_types
teng_page_string, teng_page_string
teng_page_string_from_string, teng_page_string_from_string
teng_release, teng_release
teng_release_data, teng_release_data
types, Types
Python API
addFragment, Adding fragment
building, Building
createDataRoot, Creating data root
dictionaryLookup, Looking up dictionary
engine, Creating engine
examples, Examples
generatePage, Generating page
installation (see Python API > building)
requirements, Requirements
types, Types

R

random, random
Release Notes
1.0.13, 1.0.13
reorder, reorder
replace, replace
requirements
C++ API, Requirements
PHP API, Requirements
Python API, Requirements
round, round

S

sectotime, sectotime
sec_to_time (see sectotime)
set, Definition
string, Types
StringWriter_t, StringWriter
striplines, Format
substr, substr
substr_word (see wordsubstr)
suntax
fragment, Fragment
syntax
basics, Basics
debugging, Debugging
dictionary, Types, Dictionary
expression, Expression
fragment, Types
integer, Types
numeric, Types
object, Object
operator, Operators
real, Types
string, Types
tag, Basics
types, Types
variable, Variable

T

teng_add_fragment, teng_add_fragment
teng_create_data_root, teng_create_data_root
teng_dict_lookup, teng_dict_lookup
teng_init, teng_init
teng_list_content_types, teng_list_content_types
teng_page_string, teng_page_string
teng_page_string_from_string, teng_page_string_from_string
teng_release, teng_release
teng_release_data, teng_release_data
Teng_t, Teng
types, Types
PHP API, Types
Python API, Types

U

unescape, unescape
urlescape, urlescape

V

variable
automatic, Fragment
context, Object
definition, Definition
identifier, Object
set, Definition
syntax, Variable

W

whitespace, Format
wordsubstr, wordsubstr
Writer_t, Writer