Introduction

In a wide collection of WEB developing tasks, the “fast & light” construction of web interfaces is needed, without bringing in qualified programmers. Furthermore, when we use C or C++, it is necessary to make possible some changes in project design, without recompiling the source. In both cases we need to separate the data from it’s representation in order to realize the idea. CT++ (Template engine) meets the described requirements and gives some extra opportunities such as:
  • API. & User functions.
  • Logical operations in embranchments.
  • Many possibilities for construction of LOOP.
The Template Engine is fast even with large arrays of output data.

The syntax of template engine is based on "HTML::Template" module that has taken from Perl language, this point simplifies the transporting of applications from Object Perl to C++. The Template engine completely separates project source and data representation.

We wish you a good coding with CT++.

Developers group (CT++).

Email: shetuhin@corp.mail.ru

www: htpp://www.reki.ru/products/ctpp
Copyright © 2003 - 2005 CTPP Dev. Team | http://reki.ru/products/ctpp


Notations & Terms

<TMPL_var name> - CT++ operators.

__CONTEXT_VARS__ - The modifiers

Attention! - Additional and important information.


Operators

At a moment in CT++, there are six operators:
  • <TMPL_var VAR_NAME> - Direct parameter output.
  • <TMPL_if VAR_NAME> <TMPL_else> </TMPL_if> - The condition.
  • <TMPL_unless VAR_NAME> <TMPL_else> </TMPL_unless> - The complementary condition.
  • <TMPL_loop MODIFICATOR1 MODIFICATOR1 VAR_NAME> </TMPL_loop> - The loop.
  • <TMPL_udf FUNCTION_NAME(PARAMETER1, "text 1", PARAMETER2, "text2")> - User function execution.
  • <TMPL_include file.tmpl> - Including/inserting other templates taken from the file name in the current one.
In order to simplify the make-up, we made all operators names case insensitive, that is why the notifications such as: <TMPL_var , <TmPl_VaR , <tmpl_VAR are equal.

In CT++ the names of variables are case sensitive, that’s why for example: <TMPL_var ABC>, <TMPL_var abc>, <TMPL_var Abc> are not in equal state.

Define the top length of any operator before compiling the CT++ library, default value is 128 bytes.

VAR_NAME may contains any chars except '>', '(', ')' and space.

Attention! Parameters, which names starting with a symbol of underlining (for example __FIRST__) are reserved names and should NOT be used by the developer.


VARIABLES

In CT++ template engine two types of variables are defined: local and global.
The sense of these two concepts is completely equal with a similar idea in the other algorithmic languages such as C++ & Perl.

For variable output use operator <TMPL_var VAR_NAME>

Example 1.1
Template: "Hello, <b><TMPL_var username></b>!"
Parameter: username => "Olga"
Output: "Hello, Olga!"

You can use user defined functions to make a variable output.

Example 1.2
Template: "<a href="/index.cgi?username=<TMPL_var URLESCAPE(username)>">"
Parameter: username => "Àíäðåé"
Output: "<a href="/index.cgi?username=%C0%ED%E4%F0%E5%E9">"

Attention! You can not use ‘>’, round brackets, space char in the name of function or variable neither start it with an underline char. Only one parameter available in user defined function.

    Related links:
  • User defined functions


Operators of Condition

These operators impose condition on your template output, it depends on the result of logical expression placed to the right of the operator’s body.

CT++ 1.7.5 defines two operators of condition: <TMPL_if LOGICAL_EXPR> and <TMPL_unless LOGICAL_EXPR>.

Both operators evaluates logical expression to the result and according to it executes or not the further instructions. You can also use variables (local and global) and user defined functions inside of the operator’s body.

<TMPL_if LOGICAL_EXPR>
Some instructions if result has true value.
<TMPL_else>
Some instructions if result has false value.
</TMPL_if>

<TMPL_unless LOGICAL_EXPR>
Some instructions if result has false value.
<TMPL_else>
Some instructions if result has true value.
</TMPL_unless>

The branch of <TMPL_else> is not firmly binds, it means that the following notification is allowed: <TMPL_if LOGICAL_EXPR> Some instructions </TMPL_if>. Thus the operator <TMPL_unless differs from the operator <TMPL_if in the executing some instructions if the evaluated value is false. Example 2.1:

Template: "Hello, <b><TMPL_var username></b>!<TMPL_else>Wrong user name!</TMPL_if>
Parameter: username => "Vasya"
Output: "Hello, Vasya!"

Example 2.2:

Template: "<TMPL_if username>Hello, <b><TMPL_var username>!<TMPL_else>Wrong user name!</TMPL_if>
Parameter: not defined.
Output: "Wrong user name!"

The sense is different for the second operator:

Example 2.3:

Template: "<TMPL_unless username>Hello, <b><TMPL_var username></b>!<TMPL_else>Wrong user name!</TMPL_unless>
Parameter: "Vasya"
Output: "Wrong user name!"

    Related links:
  • User Defined Functions
  • Variables


Loops

The loop - The multiple repeating of some pre-defined actions.

The only type of loops has been defined in CT++ - the forward running over through the data array. The operator corresponding with this action looks like the following:

<TMPL_loop MODIFIERS LOOP_NAME>
The LOOP instructions.
</TMPL_loop>

There are four modifiers for this operato:
  • __GLOBAL_VARS__ makes visible the global variables inside of the LOOP’s body.
  • __NO_GLOBAL_VARS__ cancels the __GLOBAL_VARS__ modifier.
  • __CONTEXT_VARS__ creates context variables inside the loop.
  • __NO_CONTEXT_VARS__ cancels the __CONTEXT_VARS__ modifier.

Important! Changing these options affects the current loop and the all enclosed loops.

It is done to take off the collisions between put-in-loops, which occur while concurrently changed the __GLOBAL_VARS__ and __CONTEXT_VARS__ modifiers.

Example 3.1:
Template:

<table width="100%">
<TMPL_loop __CONTEXT_VARS__ EMPLOYEE_INFO>
<tr>
<td>#: <TMPL_var __COUNTER__></td>
<td>Name: <TMPL_VAR NAME></td>
<td>Job: <TMPL_VAR JOB></td>
</tr></TMPL_LOOP>
</table>

Parameters:
EMPLOYEE_INFO
[
{ NAME => "Ivanov Ivan", JOB => "The architect" },
{ NAME => "Petrov Petr", JOB => "The builder" }
]

Output:
<table width="100%">
<tr>
<td>1</td>
<td>Name: Ivanov Ivan</td>
<td>Job: The architect</td>
</tr>
<tr>
<td>2</td>
<td>Name: Petrov Petr</td>
<td>Job: The builder</td>
</tr>
</table>

    Related links:
  • Variables
  • Conditions


Context Variables

If you evidently put the mark to use context variables in the loop body, CT++ inserts seven special variables, called context vars. The names of these variables start with the double underline, this fact points to their system meaning. Set of values for "context vars":
  • __FIRST__ - sets to "1" during the first loop iteration, in other cases not defined.
  • __LAST__ - sets to the last iteration number, otherwise is not defined.
  • __INNER__ - accommodates the number from the second to the pre-last iteration, otherwise undefined
  • __ODD__ - the number of an odd iteration. For the even one - undefined.
  • __COUNTER__ - the number of current iteration.
  • __EVEN__ - opposite to the __ODD__ variable.
  • __SIZE__ - the whole number of the loop iterations.

    Related links:
  • User Defined Functions
  • Variables


User Defined Functions

There are a variety of situations when you need to represent data according to some condition.
To simplify the solution of this problem we defined the logic of User Defined Functions in CT++.
You can call them from the bodies of <TMPL_if, <TMPL_unless è <TMPL_var operators either using the <TMPL_udf operator. The following example shows how to call User Defined Functions:
<TMPL_var HTMLESCAPE(name)>

or

<TMPL_if IN_SET(name, "1", "2", "3")>
Variable "name" is set of "1", "2" or "3".
</TMPL_if>

List of embedded functions of the template engine:
  • URLESCAPE
  • HTMLESCAPE
  • NUM_FORMAT
  • IN_SET
  • HREF_PARAM
  • FORM_PARAM
  • ISEMAIL
  • ISALPHA
  • ISNUM
  • ISALNUM
  • ISINT
  • ISFLOAT

    Related links:
  • Variables
  • Conditions


URLESCAPE

This function replaces the set of chars with the order of %XX sets, where XX is the hex char code.

Example:
<TMPL_var URLESCAPE(name)>

<TMPL_udf URLESCAPE(name)>

    Related links:
  • User Defined Functions


HTMLESCAPE

Replaces sets like <, >, ", ' and & with the &lt;, &gt;, &quot;, &#039; and &amp; sets.

Example:
<TMPL_var HTMLESCAPE(name)>

<TMPL_udf HTMLESCAPE(name)>

    Related links:
  • User Defined Functions


NUM_FORMAT

Puts sign of a period to the integer number (1234567 -> 1,234,567).

Example:
<TMPL_var NUM_FORMAT(variable)>

<TMPL_udf NUM_FORMAT(variable)>

    Related links:
  • User Defined Functions


IN_SET

Function compares the first argument to other arguments.
Returns true if it is found though one concurrence. Example:
<TMPL_if IN_SET(variable, "1", "2", "3")>

You can compare also variables: <TMPL_if IN_SET(variable, variable1, "2", variable2)>

    Related links:
  • User Defined Functions


HREF_PARAM

Function serves for simplification of a conclusion of parameters in references.
Replaces with itself a construction like <a href=/abc?<TMPL_if a>param_a=<TMPL_var URLESCAPE(a)></TMPL_if>... to <a href=/abc?<TMPL_udf HREF_PARAM("param_a", a)> Function can accept one, two or three parameters.
First parameter is name. Second parameter - value. Third (optional) parameter specifies, whether it is necessary to deduce result at absence of the second parameter. Allowed vaues are "y", "yes", "n", "no" (default - "y").

Example:
<TMPL_udf HREF_PARAM("param_name", param, "yes")>

<TMPL_udf HREF_PARAM("param_name", param)> (It is equivalent previous)

<TMPL_udf HREF_PARAM("param_name", param, "n")>

    Related links:
  • User Defined Functions
  • FORM_PARAM


FORM_PARAM

The algorithm of this function is similar to function HREF_PARAM.

Replaces with itself a construction like <TMPL_if a><input type="hidden" name="param_a" value=<TMPL_var HTMLESCAPE(a)"></TMPL_if> to <TMPL_udf FORM_PARAM("param_a", a)>

Example:
<TMPL_udf FORM_PARAM("param_name", param, "yes")>

<TMPL_udf FORM_PARAM("param_name", param)> (It is equivalent previous)

<TMPL_udf FORM_PARAM("param_name", param, "n")>

    Related links:
  • User Defined Functions
  • HREF_PARAM


Functions of ISXXX family.

All ISXXX functions are using for check of types of the data. Functions accept unlimited quantity of parameters on an input and returns "1" in case of conformity of all transferred parameters to checked type.

ISEMAIL

Checks parameters on conformity to the simplified pattern of the post address.

Example:
<TMPL_if ISEMAIL("abc@example.com", email)>

ISALPHA

Checks parameters on presence only alphabetic symbols ([a-zA-Z]).

Example:
<TMPL_if ISALPHA("example")>

ISNUM

Checks parameters on presence only numeric symbols ([0-9]).

Example:
<TMPL_if ISNUM(some_value, "12345678")>

ISALNUM

Checks parameters on presence only alphanumeric symbols ([a-zA-Z0-9]).

Example:
<TMPL_if ISALNUM("mode123")>

ISINT

Checks parameters on conformity to an integer.

Example:
<TMPL_if ISINT("-890")>

ISFLOAT

Checks parameters on conformity to an float.

Example:
<TMPL_if ISFLOAT("1.234E+3")>

    Related links:
  • User Defined Functions


Including other templates

In some cases it happens to allocate conveniently identical parts in several templates (for example, heading or the menu on page) and to place them in one file.

This is done by operator <TMPL_include filename.tmpl>.

Example:
main.tmpl:
<TMPL_loop foo>
<TMPL_include filename.tmpl>
</TMPL_loop>

filename.tmpl:
<TMPL_var bar>

You should specify allowed include paths.

Attention! You CAN NOT place a part of a loop or condition in separate templates.
In other words, this construction will not work:
main.tmpl:
<TMPL_if foo>
<TMPL_include abc.tmpl>

abc.tmpl:
</TMPL_if>


Introduction

CT++ is written in C++ with widely using of STL. For sucessfully building needs the compiler gcc version 2.95.4 or higer or MS Visual C++ version 6 or higer.

CT++ provides simple C++ interface for creation of the user functions.

Also provides simplified C API.


Algorithm

Process of work CT++ template engine contains four parts:
  1. Initialization
  2. Parsing template file
  3. Imposing of parameters (the first pass)
  4. Imposing of parameters (the second pass) and a conclusion of results
In the first stage occurs loading of the text of a pattern, automatic loading standard functions set and initialization of necessary variables.

The second stage is a construction of a tree of syntactic analysis of a template file. All syntactic errors are generated at this stage.

During the first pass (the third stage) there is an imposing the parameters which are taking place outside of cycles. It gives a prize for simple patterns in which the simple conclusion of parameters (without conditions and cycles) prevails.

Last stage - imposing of parameters on structures of cycles and conditions and the further conclusion of results.


Code Example

File name: tests/test_3_1.cpp.
All other examples you can found in catalog tests.

Source code:

// C++ Includes
#include <iostream>
// Local Includes
#include <ctpp/ctpp.hpp>

int main(void)
{
using namespace template_parser_ns;
using namespace std;

// We create structure of the data
param_data * pData = new param_data(param_data::HASH);
// Insert global parameter
pData -> hash_insert_new_var("global_param", "Global Parameter");

// Insert cycle
param_data * pArray = pData -> hash_insert_new_array("EMPLOYEE_INFO");

// Inside a cycle - hash with parameters
param_data * pHash = pArray -> array_insert_new_hash();
// Parameter "NAME"
pHash -> hash_insert_new_var("NAME", "Ivanov Ivan");
// Parameter "JOB"
pHash -> hash_insert_new_var("JOB", "The architect");

pHash = pArray -> array_insert_new_hash();
pHash -> hash_insert_new_var("NAME", "Petrov Petr");
pHash -> hash_insert_new_var("JOB", "The builder");
// We substitute global parameter
pHash -> hash_insert_new_var("global_param", "Replaced Parameter");

try
{
// Templae engine
template_text oTemplate;

// Includes Loader
loader_base * pLoaderBase = new loader_base();

// Allowed list of catalogs to include
v_include_dir vIncludeDir;
vIncludeDir.push_back("./tmpl");
oTemplate.set_include_dir(vIncludeDir);
// Template File
pLoaderBase -> load_file("./tmpl/3_1.tmpl");
// Parse the template
oTemplate.parse(pLoaderBase -> get_data());
// We impose parameters on a pattern
oTemplate.param(pData);
string sOutput;
// Result
sOutput.assign(oTemplate.output());
cout << sOutput << endl;
}
catch(exception &e) { cout << e.what() << endl; exit(1); }
return 0;
}

Template:

<TMPL_include header.tmpl>
<TMPL_var global_param>
<TMPL_loop __CONTEXT_VARS__ __GLOBAL_VARS__ EMPLOYEE_INFO>
<TMPL_var NAME> - <TMPL_var JOB>
<TMPL_var global_param>
<TMPL_unless IN_SET(NAME, "Ivanov Ivan")>
TEST_ANY_PARAM
</TMPL_unless>
</TMPL_loop>
<TMPL_include footer.tmpl>

Parameters:

global_param => "Global Parameter"
EMPLOYEE_INFO
[
{ NAME => "Ivanov Ivan", JOB => "The architect" },
{ NAME => "Petrov Petr", JOB => "The builder", global_param => "Replaced Parameter" }
]

Opuput:
<!-- Copyright (c) 2004 Andrei V. Shetuhin -->
<html>
<head>
<title>Sample</title>
</head>
<body>
Global Parameter

Ivanov Ivan - The architect
Global Parameter

Petrov Petr - The builder
Replaced Parameter

TEST_ANY_PARAM

</body>
</html>
<!-- Footer End -->

 Compilation:

gcc -c test_3_1.cpp -I /usr/local/include/ctpp

For dynamic linking:
gcc test_3_1.o -L /usr/local/lib -o test_3_1 -lctpp

For static linking:
gcc -static test_3_1.o -L /usr/local/lib -o test_3_1 -lctpp -lstdc++


CT++ API

Class template_text

// Constructor
template_text(udf_fn_factory * pFactory = NULL,
const int iLine = 1,
const int iPos = 1,
const int iTabLength = 9,
const bool bDebug = false,
const bool bStrict = true,
const bool bLoopContextVars = false,
const bool bGlobalVars = false);

 where:
pFactory - factory of the objects of the user functions

iLine - the number of the line of template (default - 1)
iPos - position in the line of template (default - 1)
iTabLength - size of the symbol of tabulation in spaces (default 9)

These three parameters are used as initial values in the system of the syntax analysis of template.

bDebug - enable or disable debug (default off)
bStrict - strict syntax checking (after construction <TMPL_must follow the operator of template engine CT++, default on)

bLoopContextVars - use of contextual variables in the cycle (default off)
bGlobalVars - use of global variables in the cycle (default off)

// Getting Factory
udf_fn_factory * get_fn_factory();

 Getting the factory of objects. If the object of template engine ñîçäàåòñÿ áåç ôàáðèêè îáúåêòîâ,is created without the factory of objects, object independently creates its internal factory with the set of standard functions.
Method get_fn_factoryserves for obtaining the pointer to the factory

// Setting IncludeDir
void set_include_dir(const v_include_dir &vIncludeDir);

 ãäå:
vIncludeDir - list of catalogs for the i of the investments through <TMPL_include filename.tmpl>

If path to the file name does not begin from the slash, file consecutively searches for in all catalogs from vIncludeDir. But if path begins from the slash, path is checked against the entry in vIncludeDir. If path is not found in vIncludeDir or it is not possible to open file, is generated exception std::logic_error.

// Parse the template
void parse(const std::string & sData);

void parse(std::string::const_iterator & sDataBegin, std::string::const_iterator & sDataEnd);

 Overloaded method. To the entrance are obtained the beginning and the end of the sequence of the symbols, which are been template, or the string of symbols.

// Insert the parameters
void param(param_data * pParamData);

 Insert of the parameters into the template.

// Result output
std::string & output();

 Result output to user.

// Cleaning the template
void clear_template();

 Cleaning template.

// Destructor
~template_text() throw();

Class loader_base

Base class for creating its own includes loader.
// Load file
virtual void load_file(const std::string &sFileName);

Method obtains the complete name of file.

// Getting data
virtual std::string & get_data();

Returns contents of opened file.

// Destructor
virtual ~loader_base() throw();

Class udf_fn_factory

Class-installerof the user defined functions.

// Installation of user defined function
void install_udf_fn(const std::string &sFunctionName, udf_fn * pUDFFn);

 Puts the object of function in the factory of objects created previously. First parameter - name of function in the template. Second parameter - pointer to the object of function.

// Removind of user defined function
void remove_udf_fn(const std::string &sFunctionName);

 Removes user defined function from the factory of objects. First parameter - name of function in the template.

// Getting pointer to the function
udf_fn * get(const std::string &sFunctionName);

 First parameter - name of function in the template.

// Clear factory
void clear();

 Removes all function from the factoryu, including standard functions set.

// Destructor
virtual ~udf_fn_factory();

Class param_data

This class is used for the transfer of parameters to template engine.

Determinations of essences.
In template engine CTPP there are three types of the data: line, array and hash are given. Below the determination of these types:
// String
typedef std::string t_param_str;

// Array
typedef std::vector<param_data *> t_param_array;

// Hash
typedef std::map<std::string, param_data *> t_param_hash;

For the indication of the type of object serves the enumeration e_value_type:
enum e_value_type { VAR, ARRAY, HASH };

 // Constructor
param_data(e_value_type eIType = VAR);

 Is created object in by the assigned type.

// Pointer to the VAL
t_param_str * val();

 Returns pointer to the object of the type "line". If this method inquires in the object with the type, different from VAR, is generated exception std::logic_error.

// Pointer to the ARRAY
t_param_array * array();

 Returns pointer to the object of the type "array". If this method inquires in the object with the type, different from ARRAY, is generated exception std::logic_error.

// Pointer to the HASH
t_param_hash * hash();

 Returns pointer to the object of the type "hash". If this method inquires in the object with the type, different from HASH, is generated exception std::logic_error.

// Type of the variable
e_value_type get_value_type();

 Getting the type of object.

// Insert variable into hash
param_data * hash_insert_new_var(const std::string &sKey, const std::string &sValue);

 Insert pair "key => value" â hash. Returns pointer to the created variable.

// Insert array into
param_data * hash_insert_new_array(const std::string &sKey);

 Insert pair "key => array" â hash. Returns pointer to the created array.

// Insert variable into array
param_data * array_insert_new_var(const std::string &sKey);

 // Insert hash into array
param_data * array_insert_new_hash();

 // Removes variable from hash
void param_data::hash_erase_var(const std::string &sKey);

 // Destructor
~param_data();


CT++ user defined functions API

At the given moment all user functions realize by means of the inheritance from the abstract class udf_fn (User Defined FuNction) from the namespace template_parser_ns.

For the transmission of data in class is provided the overloaded method param. Method assume upon the entrance one, two or three parameters of the type std::string, or one parameter of the type std::vector<std::string>.

Class must inform the causing process about a quantity of the necessary variables adopted. For this serves method accept_params(). Method must return one of four values: ONE_PARAM (one parameter), TWO_PARAMS (two parameters), THREE_PARAMS (three parameters) or ANY_PARAMS (vector with the unlimited quantity of parameters).

The interface of class is given below:
namespace template_parser_ns
{
//
// Parameters, transferred to the function
//
typedef std::vector<std::string> udf_fn_param;

//
// User defined function
//
class udf_fn
{
public:
// A quantity of the parameters
enum e_accept_params {ONE_PARAM, TWO_PARAMS, THREE_PARAMS, ANY_PARAMS};

// Give parameters
// Unlimited quantity of parameters
virtual void param(udf_fn_param * pParam);

// One parameter
virtual void param(const std::string &sParam);

// Two parameters
virtual void param(const std::string &sParam1, const std::string &sParam2);

// Three parameters
virtual void param(const std::string &sParam1, const std::string &sParam2, const std::string &sParam3);

// Number of the accepted parameters
virtual e_accept_params accept_params() = 0;

// Function handler
virtual void handler() = 0;

// Result
virtual std::string & result() = 0;

// Destructor
virtual ~udf_fn() { ;; }

};

} // namespace template_parser_ns

For the connection of new user function it is necessary to introduce the created class into the factory of objects. There are two methods of using the factory of the objects: creation by new and the use of current from the object of template engine. For creating the new factory of objects is used class udf_fn_factory from namespace template_parser_ns:

// Create the factory of the objects
template_parser_ns::udf_fn_factory * pFactory = new udf_fn_factory();

// Create the object of user function
template_parser_ns::udf_fn * pFunction = new user_function();
// Create function in the factory of the objects
pFactory -> install_udf_fn("FOOBAR", pFunction);

// Create the object of template engine
template_text * pTemplate = new template_text(pFactory);

In the case of using the current factory of objects the code will be approximately following:

// Create the factory of the objects
template_parser_ns::udf_fn_factory * pFactory = pTemplate -> get_fn_factory();

// Create the object of user function
template_parser_ns::udf_fn * pFunction = new user_function();
// Create function in the factory of the objects
pFactory -> install_udf_fn("FOOBAR", pFunction);


Errors Handling

CT ++ template engine can work in two modes: with the strict control of syntax (by default) and without. In case of the strict control of syntax exception std::logic_error is generated in the following cases:
  • Maximum length of operator exceed.
  • Found a syntax error in operator name. After construction <TMPL_ or </TMPL_ does not follow any of allowable names of tokens (var, include, loop, if, else, unless, udf).
The diagnostic message is: "Syntax error in <TMPL_operator_name PARAMETER_NAME at line LINE_NUMBER column COLUMN_NUMBER."

Example:
Syntax error in <TMPL_var too_long_dataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa at line 132 column 116.
Exception std::logic_error generated always irrespective of a mode of check of syntax of a pattern in the following cases:
  • Found crossing of operators. Example:
    <TMPL_loop loop_var>
    <TMPL_if condition>
    |---> crossing of TMPL_if and TMPL_loop
    </TMPL_loop>
    </TMPL_if>

    The diagnostic message is: "Fatal: Logic error near at line LINE_NUMBER. Expected </TMPL_operator_name> but found </TMPL_operator_name>."

    Example:
    Fatal: Logic error near at line 123. Expected /TMPL_IF, but found /TMPL_LOOP.

  • Found the syntactic error in a name of function, or required function does not exist.
    Example:
    Line 140 column 66: User defined function `FOOBAR' not found.

  • Found incorrectly entered parameters.
    In this case exceptions generated by a class param_data.
Names of functions and variables should not contain symbols '>', '(', ')', space and cannot begin with a symbol of underlining . By a call from operator TMPL_var it is possible to specify only one parameter of function.


Build Instructions

The CT++ source is available in the source distribution.
Download and install the CT++ source distribution ctpp-1.7.5.tar.gz by extracting the files from the compressed archive.
Change current directory to ctpp-1.7.5 and run "./configure" script.
wget http://reki.ru/products/ctpp/download/ctpp-1.7.5.tar.gz
tar -xvzf ctpp-1.7.5.tar.gz
cd ctpp-1.7.5
./configure
make
make install
(for BSD-like operating systems - gmake)

Under FreeBSD you can also install CTPP from ports:

cd /usr/ports/textproc/ctpp
make install clean

For RPM-based Linux'es (SuSe, RedHat...) you can download RPM and Source RPM.
Building from Source RPM (example for Linux RedHat 8.0):

cd /usr/src/redhat/SRPMS
wget http://reki.ru/products/ctpp/download/ctpp-1.7.5.src.rpm
rpm -i ctpp-1.7.5.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -bb ctpp.spec
cd /usr/src/redhat/RPMS/i386

rpm -U ctpp-1.7.5-1.i386.rpm

For Gentoo Linux:

wget http://reki.ru/products/ctpp/download/Linux/gentoo/ctpp-1.7.5.ebuild
ebuild ctpp-1.7.5.ebuild digest
emerge ctpp-1.7.5.ebuild


License

BSD License.

Copyright (c) 2004, 2005, CTPP Dev. Team

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Gratitudes

Sam Tregar -- for the beginning of a way (HTML::Template 0.04 - 2.7)

Alexander Makarov -- for valuable remarks and advices on API

Andrew Fedorowsky -- for constant scepticism

Vadim Sukhanov -- for Perl XS

Vladimir Kovalevsky -- for English version of documentation

Dedicated to Alena (Kolychka)


CT++

Dedicated to Elen,
my gentle angel.

CT++

Fast C++ template engine

Copyright © 2003 - 2005 CTPP Dev. Team | http://reki.ru/products/ctpp


RE

Âûïîëíÿåò ïîèñê è/èëè çàìåíó çíà÷åíèÿ ñîîòâåòñòâåííî çàäàííîìó ðåãóëÿðíîìó âûðàæåíèþ.
Ñèíòàêñèñ ðåãóëÿðíûõ âûðàæåíèé ñîâïàäàåò ñ ñèíòàêñèñîì ðåøóëÿðíûõ âûðàæåíèé ÿçûêà Perl.

Example:
<TMPL_udf RE(time, "/([0-9]{2}):([0-9]{2})/", "$1 - $2")>

<TMPL_if RE(name, "/([a-zA-z]+)/")>

    Related links:
  • User Defined Functions


SPRINTF

Ôîðìàòèðóåò ñïèñîê ïàðàìåòðîâ â ñîîòâåòñòâèè ñ çàäàííûì øàáëîíîì.
Ñïåöèôèêàöèè ôîðìàòà âûâîäà ïîëíîñòüþ ñîîòâåòñòâåò ñòàíäàðòó sprintf(3) ISO/IEC 9899:1990 (ISO C89).

Example:
<TMPL_udf SPRINTF("%s %d", email, count)>

    Related links:
  • User Defined Functions