List of Tables
List of Examples
Table of Contents
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.
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 :-)
Table of Contents
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:
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’.
To report bugs and submit support and feature requests, use SourceForge.net Tracker.
![]() | 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.
Table of Contents
Teng is case sensitive in all ways except for exactly specified exceptions.
Tags are enclosed by ‘<?teng’ and ‘?>’ marks.
![]() | Tip |
|---|---|
If you need to generate ‘ |
<!-- 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).
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 (‘\’)
line feed character (UNIX and POSIX line break)
carriage return character (Apple through MacOS 9 and Commodore line break)
carriage return and line feed character pair (DOS and Windows line break)
a horizontal tab
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.
fragmentdictionaryFragment 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.
Table 1. Operators overview
| numeric | string | description |
|---|---|---|
| == | =~ | 1 if equal, 0 otherwise |
| eq | ||
| != | !~ | 1 if not equal, 0 otherwise |
| ne | ||
| >= | none | 1 if greater or equal, 0 otherwise |
| ge | ||
| <= | none | 1 if lesser or equal, 0 otherwise |
| le | ||
| > | none | 1 if greater, 0 otherwise |
| gt | ||
| < | none | 1 if lesser, 0 otherwise |
| lt | ||
| + | ++ | addition; string concatenation |
| - | none | subtraction |
| * | ** | multiplication; string repetition |
| / | none | division |
| % | none | modulo |
| ! | ! | 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 |
| ~ | none | bit negation (complement; each bit is set if argument has not the same bit set) |
| & | none | bit AND (each bit is set if both arguments have the same bit set) |
| | | none | bit OR (each bit is set if at least one argument has the same bit set) |
| ^ | none | bit 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.
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 |
|---|---|
This operator is available since version 1.0.13 of Teng library. |
Checks whether object with identifier ‘identifier’ exists.
Returns one of following values:
such object does not exist or is an empty fragment
such object exists and is non-empty if a fragment
![]() | 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 |
<?teng expr expression ?>${expression}Evalutes ‘expression’ and prints evaluted value.
![]() | Tip |
|---|---|
If you need to generate ‘ |
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:
unqualified object identifier
Selects object in local context.
partialy qualified object identifier
Selects object in context of object ‘context’, which is in local context.
fully qualified object identifier
Selects object in context of object ‘context’, which is in global (ie. top-most) context.
![]() | Note |
|---|---|
If fragment is used for specifying context, it’s first dictionary (‘iteration’) is used. |
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’.
<?teng expr $variable?>${variable}$variablePrints 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}#variablePrints 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 |
|---|---|
If you need to generate ‘ |
<?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.
<?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.
<?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:
removes all whitespaces
collapse all whitespace characters into one space
removes all whitespaces at the beginning and end of each line except for line breaks
removes all whitespaces at the beginning and end of each line including line breaks
removes all empty lines
does no formating at all (useful when a part of formatting block should not be formated)
<?teng endformat ?>Terminates whitespace formating block.
<?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:
Total number of iterations (dictionaries in fragment array). This is an integer.
Actual count of iterations begining with 0. This is an integer.
0 ≤ $_number < $_count.
This object exists only in fragment block.
Actual fragment context, ie. ‘$_number’th 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’.
<?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’).
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 |
|---|---|
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. |
Table of Contents
This preface is about external dictionaries (dictionaries specified in files). For more information on dictionaries see ‘syntax’ preface.
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.
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
houseThe United States House of Representativesmonths|January|February|March|April|May|June|July|August|September|October|November|December| %enable debug
%disable flagDisables configuration flag ‘flag’. This command overrides configuration specified by calling application.
For list of available flags, see ‘%enable’.
%enable flagEnables configuration flag ‘flag’. This command overrides configuration specified by calling application.
Following flags are defined:
Enables printing disassembled bytecode on place specified by ‘bytecode’ command.
This flags is disabled by default.
Enables printing debugging information on place specified by ‘debug’ command.
This flags is disabled by default.
Creates error fragment ‘._error’ that enables access to all errors generated during template processing.
Each iteration has the following variables:
statusSeverity of the error.
filenameFilename of template in which the error has occured.
lineLine on which the error occured.
columnColumn in which the error occured.
messageDescription of the error.
This flags is disabled by default.
![]() | 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. |
Prints error log to output at the end of the document as comment.
This flags is disabled by default.
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 stateEnables 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.
Table of Contents
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
| character | description | example for Sunday January 2nd, 2005 16:05:06 CET |
|---|---|---|
| %% | literal ‘%’ | % |
| %a | abbreviated weekday name | Sun |
| %A | full weekday name | Sunday |
| %b | abbreviated month name | Jan |
| %B | full month name | January |
| %d | day of month with leading zero | 02 |
| %e | day of month without leading zero | 2 |
| %h | alias for ‘%b’ | Jan |
| %H | hour with leading zero using a 24-hour clock | 16 |
| %I | hour with leading zero using a 12-hour clock | 04 |
| %j | day of year with leading zeros | 002 |
| %k | hour without leading zero using a 24-hour clock | 16 |
| %l | hour without leading zero using a 12-hour clock | 4 |
| %m | month with leading zero | 01 |
| %M | minute with leading zero | 05 |
| %n | month without leading zero | 1 |
| %p | ‘AM’ or ‘PM’ or corresponding string as defined in locales | PM |
| %P | same as ‘%p’, but lower case | pm |
| %r | 12-hour time; same as ‘%I:%M:%S %p’ | 04:05:06 PM |
| %R | 24-hour time without seconds; same as ‘%H:%M’ | 16:05 |
| %S | seconds with leading zero | 06 |
| %T | 24-hour time; same as ‘%H:%M:%S’ | 16:05:06 |
| %u | weekday as number; starting with 1 from Monday | 7 |
| %w | number of weekday staring with 0 for Sunday | 0 |
| %y | two-digit year | 05 |
| %Y | four-digit year | 2005 |
Any other character escaped by ‘%’ among the ones above is print as unescaped.
![]() | 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
string escape(string string)
Escapes ‘string’ according to current content type.
This function‘s inverse function is ‘unescape’ function.
integer int(string number)
Returns ‘number’ with chopped decimal values.
integer isnumber(integer value)
integer isnumber(real value)
integer isnumber(string value)
Returns 1 if ‘value’ is numeric; otherwise returns 0.
integer len(string string)
Returns length of ‘string’ in characters.
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 |
|---|---|
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. |
real now()
Returns current time stamp with precission of microsecond.
For example see example of function ‘date’.
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
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 |
|---|---|
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. |
string replace( | string | text, |
| string | out, | |
| string | in) |
Returns ‘text’ with all occurences of ‘out’ replaced with ‘in’.
![]() | Important |
|---|---|
This function is available since version 1.0.13 of Teng library. |
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’.
string sectotime(integer number)
Takes ‘number’ as seconds and returns ‘H:MM:SS’ formated string.
![]() | 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. |
string substr( | string | text, |
| integer | from, | |
| integer | to, | |
| string | prefix = "", | |
| string | suffix = "") |
Returns substring of string ‘text’ beginning after ‘from’th and ending with ‘to’th character.
If ‘from’ or ‘to’ are negative, they choose -‘from’th, resp. -‘to’th 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 |
|---|---|
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. |
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.
string urlescape(string string)
Escapes ‘string’ according to RFC 1738, so it can be used in URL.
string wordsubstr( | string | text, |
| integer | from, | |
| integer | to, | |
| string | prefix = "", | |
| string | suffix = "") |
Returns substring of string ‘text’ beginning after ‘from’th and ending with ‘to’th character. Leading and tailing whitespaces are removed. Incomplete words are completed.
![]() | 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 -‘from’th, resp. -‘to’th 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’.
Table of Contents
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 |
|---|---|
This library might work in Microsoft Windows under Cygwin or Mingw32, althrough this was never tested. |
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
Unpack Teng library source into a build directory, eg. ‘/usr/local/src/teng’.
Enter the C++ API build directory:
$ cd <build_directory>/tengConfigure Teng library Makefile:
$ ./configure![]() | Tip |
|---|---|
You can change installation root (defaults to ‘/usr/local’) by invoking: |
![]() | Warning |
|---|---|
If you use exotic path, your compiler may not find Teng library. If so, you’ll need typing its path manually. |
![]() | Tip |
|---|---|
For list of all configurable settings type: |
Compile the library:
$ make![]() | Tip |
|---|---|
You may suppress printing commands as they are executed by invoking: 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>’.
Install Teng library and its header files:
$ su -c 'make install'![]() | Note |
|---|---|
If you’re already logged in as super user (usualy called ‘root’), type: |
To compile programs using Teng C++ API, follow the following procedure:
Procedure 2. Compiling a program using Teng C++ API
Build and install Teng library.
Include Teng C++ API header file.
#include <teng.h>
Write your program.
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.
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 |
|---|---|
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.oExecute 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 |
|---|---|
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. |
class Teng::FileWriter_t: public Teng::Writer_t {publicFileWriter_t(const std::string & filename);publicFileWriter_t(FILE * file);public virtual~FileWriter_t();public virtual intwrite(const std::string & str);public virtual intwrite(const char * str);public virtual intwrite(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 |
|---|---|
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.
class Teng::Fragment_t: public std::map<std::string, Teng::FragmentValue_t *> {publicFragment_t();public~Fragment_t();public voidaddVariable(const std::string & name, const std::string & value);public voidaddVariable(const std::string & name, const long int value);public voidaddVariable(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_t’ name 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’.
class Teng::FragmentList_t: public std::vector<Teng::Fragment_t *> {publicFragmentList_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.
class Teng::FragmentValue_t {publicFragmentValue_t();publicFragmentValue_t(const std::string & value);publicFragmentValue_t(long int value);publicFragmentValue_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’.
class Teng::StringWriter_t: public Teng::Writer_t {publicStringWriter_t(std::string & str);public virtual intwrite(const std::string & str);public virtual intwrite(const char * str);public virtual intwrite(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.
class Teng::Teng_t {publicTeng_t(const std::string & root, int logMode= 0, bool validate= false);public~Teng_t();public intgeneratePage(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 intgeneratePage(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 intdictionaryLookup(const std::string & dictionary, const std::string & language, const std::string & key, std::string & value);static void}listSupportedContentTypes(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.
rootDefines root for relative paths (ie. paths not starting with ‘/’).
logModeSets the mode of errors logging. It can be zero or OR-ed one or more of the following values:
Teng_t::LM_LOG_TO_OUTPUTIf this bit is set, the error log will be appended at the end of the generated page.
Teng_t::LM_ERROR_FRAGMENTIf 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 |
|---|---|
Specifying this flags in the Teng engine constructor is deprecated by dictionary command ‘%enable’. |
validateIf true, the template and supplied data will be validated against data definition if supplied in ‘generatePage’.
![]() | 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.
templateFilenameFilename of an external template.
skinSkin 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 |
|---|---|
For HTML, XHTML, and XML, skinning is deprecated by CSS and XSLT. |
templateStringTemplate supplied as string. This version is not recommended because the template is compiled every time it is called.
dataDefinitionFilename 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 |
|---|---|
Data definition has been deprecated and is ignored. |
dictionaryFilename 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.
languageLanguage of dictionary. See ‘dictionary’ for more information.
configFilenameFilename of configuration file. It is language-independent dictionary.
contentTypeContent type of the generated document. It is used for data escaping and comments.
encodingEncoding 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).
dataRoot fragment of objects data.
writerOutput character device. See class ‘Teng::Writer_t’.
errError 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)’.
class Teng::Writer_t {public inlineWriter_t();public inline virtual~Writer_t();public virtual intwrite(const std::string & str);public virtual intwrite(const char * str);public virtual intwrite(const std::string & str, std::pair<std::string::const_iterator, std::string::const_iterator> interval);public virtual intflush();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 |
|---|---|
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.
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>Table of Contents
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.
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
![]() | 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. |
Enter the Teng Python module build directory:
$ cd <build_directory>/pythonBuild the module:
$ ./setup.py buildInstall Teng Python module:
$ su -c './setup.py install'![]() | Note |
|---|---|
If you’re already logged in as super user (usualy ‘root’), type: |
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 |
|---|---|
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. |
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.
rootDefines root for relative paths (ie. paths not starting with ‘/’).
encodingDefault encoding for processing the page if not specified in ‘generatePage’.
contentTypeDefault encoding for processing the page if not specified in ‘generatePage’.
logToOutputIf true, append error log to output.
![]() | Important |
|---|---|
Specifying this flag in the Teng engine constructor is deprecated by dictionary command ‘%enable logtooutput’. |
errorFragmentIf ture, create ‘._error’ fragment for error log.
![]() | 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.
validateIf true, the template and supplied data will be validated against data definition if supplied in ‘generatePage’.
![]() | Important |
|---|---|
Data definition has been deprecated and is ignored. |
teng.Fragment teng.Teng.createDataRoot( | teng.Teng | self, |
| Object | data) |
Creates ‘teng.Fragment’ instance for data root. Call it using:
engine.createDataRoot(…)
dataEither ‘dict’ or ‘teng.Fragment’ instance to populate the data root.
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.
nameName of newly created fragment. If a fragment with name ‘name’ already exists, creates new iteration of it.
dataEither ‘dict’ or ‘teng.Fragment’ instance to populate the data root.
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.
templateFilenameFilename of template file. Conflicts with ‘templateString’.
skinSkin of template. Requires ‘templateFilename’.
![]() | 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’.
templateStringString containing the template. Conflicts with ‘templateFilename’.
dataDefinitionFilenameFilename of data definition file. Ignored if engine was created with validate equal to zero.
![]() | Important |
|---|---|
Data definition has been deprecated and is ignored. |
dictionaryFilenameFilename of dictionary file without specified language. For more information see C++ API‘s ‘Teng::Teng_t’ class method ‘generatePage’.
languageLanguage of dictionary file. Requires dictionaryFilename. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.
configFilenameFilename of file with configuration (language independent dictionary).
contentTypeSpecifies generated page’s content-type. If not supplied, it is used the value supplied when creating engine.
dataData tree. Either instance of ‘dict’ or ‘teng.Fragment’. For more information see Python API types section.
outputFilenameFilename of file to which the output should be written. Conflicts with ‘outputFile’.
outputFileFile object instance to which the output should be written. This instance must have method ‘write’. Conflicts with ‘outputFilename’.
encodingSpecifies 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:
statusThe highest status code of generated errors; if no errors were generated, equals zero.
outputGenerated page.
Exists if neither ‘outputFilename’ nor ‘outputFile’ is specified.
errorLogTuple of following ‘dict’ instances:
levelSeverity of the error.
filenameFilename of template in which the error occured.
lineLine on which the error occured.
columnColumn in which the error occured.
messageDescription of the error.
![]() | 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. |
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.
dictionaryFilenameFilename of dictionary. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.
languageLanguage of dictionary. For more information see C++ API’s ‘Teng::Teng_t’ class method ‘generatePage’.
keyKey of searched entry.
Returns ‘None’ if specified key does not exist in specified dictionary.
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>Table of Contents
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.
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
Enter the Teng PHP extension build directory:
$ cd <build_directory>/php4Prepare Teng PHP extension.
$ ./bootstrap.shConfigure Teng PHP extension.
$ ./configureCompile the extension:
$ make![]() | Tip |
|---|---|
You may suppress printing commands as they are executed by invoking: Errors are still reported and do terminate compiling. There will be no output if no error occures. |
Install Teng PHP extension:
$ su -c 'make install'![]() | Note |
|---|---|
If you’re already logged in as super user (usualy called ’root’), type: |
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.iniLoad Teng PHP extension in your PHP script using the ‘dl’ function.
![]() | Warning |
|---|---|
This function may be disabled in your PHP configuration. |
dl("teng.so");![]() | Note |
|---|---|
Try to avoid using this step due to performance reasons as explained in ‘Types’ section. |
You can check whether the PHP loads Teng PHP extension by executing and examining:
$ php -qi | lynx -stdin![]() | Tip |
|---|---|
If you prefer using the ‘dl’ function, type: |
If you are unable to find a section called ‘teng’ then the Teng PHP extension is not loaded.
Teng PHP extension can be configured using the following directives:
Table 3. PHP API configuration directives
| Directive | Default | Changeable | Description | |||
|---|---|---|---|---|---|---|
teng.template_root | NULL | PHP_INI_ALL | Defines the default root path used to access Teng templates and dictionaries. | |||
teng.default_dict | NULL | PHP_INI_ALL | Sets the path to default language dictionary. | |||
teng.default_lang | NULL | PHP_INI_ALL | Sets the default language. | |||
teng.default_config | NULL | PHP_INI_ALL | Sets the path to default template configuration. | |||
teng.default_content_type | ’text/html‘ | PHP_INI_ALL | Sets 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_ALL | Sets the default document encoding. Can be any encoding supported on your system. | |||
teng.validation | ’Off‘ | PHP_INI_ALL | This boolean flag indicates whether Teng should perform template and application data validation.
| |||
teng.log_to_output | ‘Off’ | PHP_INI_ALL | If 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_ALL | If this boolean flag is set, a fragment called ‘._error’ is created containing all errors. | |||
teng.default_skin | NULL | PHP_INI_ALL | Sets the default template skin.
|
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.
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.
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.
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.
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.
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.
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 of template.
![]() | 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’.
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.
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.
Filename of file with configuration (language independent dictionary).
Filename of data definition file. Ignored if ‘teng.validate’ in configuration is not ‘On’.
![]() | Important |
|---|---|
Data definition has been deprecated and is ignored. |
Specifies generated page’s content-type. If not supplied, it is used the value supplied in configuration.
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.
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:
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.
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.
Filename of file with configuration (language independent dictionary).
Filename of data definition file. Ignored if ‘teng.validate’ in configuration is not ‘On’.
Specifies generated page’s content-type. If not supplied, it is used the value supplied in configuration.
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.
(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.
array teng_list_content_types()
Returns an array where every key represents supported content type and every value its brief description.
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 |
|---|---|
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>