/htmltmpl.js

javascript html template library (which is similar to HTML::Template perl module)

Primary LanguageHTMLGNU Lesser General Public License v3.0LGPL-3.0

htmltmpl
===========

htmltmpl is the javascript html template library. It must has capabilities
similar to HTML::Template perl module, but now it support only the next
constructs:

{%TMPL_VAR NAME=var_name DEFAULT="def value" ESCAPE=val%}
{%TMPL_LOOP NAME=loop_name%}...{%/TMPL_LOOP%}
{%TMPL_IF NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_IF%}
{%TMPL_UNLESS NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_UNLESS%}
{%TMPL_INCLUDE NAME=tmpl_name%}
{%TMPL_INCLUDE NAME=tmpl_name VAR=var_name%}

with ifdef extension:
{%TMPL_IFDEF NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_IFDEF%}
{%TMPL_IFNDEF NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_IFNDEF%}

with ifeq extension:
{%TMPL_IFEQ NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFEQ%}
{%TMPL_IFEQ NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFEQ%}
{%TMPL_IFNEQ NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFNEQ%}
{%TMPL_IFNEQ NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFNEQ%}
{%TMPL_IFGT NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFGT%}
{%TMPL_IFGT NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFGT%}
{%TMPL_IFGE NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFGE%}
{%TMPL_IFGE NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFGE%}
{%TMPL_IFLT NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFLT%}
{%TMPL_IFLT NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFLT%}
{%TMPL_IFLE NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFLE%}
{%TMPL_IFLE NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFLE%}

with ifin extension:
{%TMPL_IFIN NAME=var VALUES=[VAL1, ...]%}...{%TMPL_ELSE%}...{%/TMPL_IFIN%}

with func extension:
{%TMPL_FUNC NAME=func_name ARGS=[arg_1, ...] [ESCAPE=type]%}
{%TMPL_IFRET NAME=func_name ARGS=[arg_1, ...]%}...{%/TMPL_IFRET%}
{%TMPL_IFRET NAME=func_name ARGS=[arg_1, ...]%}...{%TMPL_ELSE%}...{%/TMPL_IFRET%}

with list extension:
{%TMPL_LIST NAME=list_name%}...{%/TMPL_LIST%}
{%TMPL_LIST NAME=list_name%}...{%TMPL_LISTITEM [ESCAPE=type]%}...{%/TMPL_LIST%}


See ex*.html files for examples of use.

You can open test.html in your browser to test that htmltmpl is works right.
If not so, please, report a bug.

Structure
=========

htmltmpl consists of core module and extension modules. The core module
supplies a main functionality and a base tags set. Extension modules
extend a base tags set. All modules reside in htmltmpl directory. For the
base tags set you must include only the core module:

	<script type="text/javascript" src="htmltmpl/core.min.js"></script>

If you need, for example, TMPL_IFDEF/TMPL_IFNDEF tags, you must include
ifdef.js extension module after the core:

	<script type="text/javascript" src="htmltmpl/core.min.js"></script>
	<script type="text/javascript" src="htmltmpl/ifdef.min.js"></script>

For those who want a single js file with all modules in it, there is
solid target of Makefile. Do:

	make && make solid

and you get htmltmpl.solid.js in the current directory. Or:

	make && make solid-min

to get htmltmpl.solid.min.js.

Using
=====

To create a htmltmpl object call the constructor with a template element as an
argument:

	var tmpl = new htmltmpl(document.getElementById("tmpl_div"));

Where tmpl_div is:

	<div style="display: none" id="tmpl_div">
		{%TMPL_LOOP NAME=loop1%}
			<div>{%TMPL_VAR NAME=var1%}</div>
		{%/TMPL_LOOP%}
	</div>

In this case the content of the outer div is got as a template. That is
(without quotes):

"
	{%TMPL_LOOP NAME=loop1%}
		<div>{%TMPL_VAR NAME=var1%}</div>
	{%/TMPL_LOOP%}
"

A template can be a string instead of an html element:

	var tmpl = new htmltmpl("<div>{%TMPL_VAR NAME=var1%}</div>");

Since container element node name and its id are used as a template
name for an error message, it's useful to assign an id to every template
container. Or use name parameter of htmltmpl constructor. I.e. for the
template:

	<div style="display: none" id="tmpl_items_list">
		{%TMPL_LOOP NAM=loop1%}
			<div>{%TMPL_VAR NAME=var1%}</div>
		{%/TMPL_LOOP%}
	</div>

the template name is DIV#tmpl_items_list and an error message will be:

DIV#tmpl_items_list: line 2: TMPL_LOOP must have NAME attribute

htmltmpl constructor accept an object as a second argument with parameters to
change it behaviour. Properties names:

  case_sensitive (0/1)
	process template constructs in case-sensitive mode.
	1 by default.
  global_vars (0/1)
	make variables defined outside a loop visible.
	0 by default.
  loop_context_vars (0/1)
	Enable loop/list variables (__first__, __last__, __inner__,
	__outer__, __odd__, __even__, __counter__, __index__).
	0 by default.
  tmpl_is_commented (0/1)
	Enable this if a template is enclosed in <!--/-->. Thus,
	the comment constuct is striped from a result.
	This is need if we place a template inside a table.
	1 by default.
  err_on_no_data (0/1)
	If we found a template tag and have no such property in a supplied
	data, throw an error.
	0 by default.
  ret_dom
	Return a dom instead of an html code. Dom is generated by creating an
	HTML element(the element to create is autodetected by a first element
	in a result string - out_str), assigning to it innerHTML property a
	result string and returning childNodes of this HTML element.
	0 by default.
  strip_wrap_spaces
	Remove white space at the start and at the end of a template output
	string.
	1 by default.
  escape_defval
	Default value for ESCAPE attribute(ETEXT, AVAL or NO).
	ETEXT by default.
  name
	a template name for using in an error message. If null, then
	use container element name and its id or the first 10 characters
	of the template string(if a template is a string instead of
	some element node).
	null by default.

E.g.:

	var tmpl = new htmltmpl(document.getElementById("tmpl_div"),
		{ global_vars: 1,
		  ret_dom: 1 });

There is also parameters default values in htmltmpl.p object. If you, for
example, override ret_dom parameter default value for your every template,
more easier is to change htmltmpl default values with:

	htmltmpl.p.ret_dom = 1;

before a first call of htmltmpl constructor.

You can use as NAME attribute value a name of an inner object property:

	{%TMPL_VAR NAME=var.long.name%}

A possible apply call can be:

	tmpl.apply({var: {long: {name: "test"}}});

In case of an error, htmltmpl throw an exception.


Template tags
=============

core:
  TMPL_VAR
	{%TMPL_VAR NAME=var_name [DEFAULT=123] [ESCAPE=val]%}

	This is simply replaced with value of var_name property. If you use
	TMPL_VAR tag with DEFAULT attribute, then if var_name property isn't found
	a tag is replaced with a value of DEFAULT attribute. Attribute value
	should be enclosed in double or single quotes if it contains spaces or
	quotes. Quote inside a quoted value should be escaped with a backslash.
	ESCAPE attribute contains an escape type for a var value. Possible types:
	 - NO - no escaping
	 - ETEXT - element text - escape &, < and > with &amp;, &lt; and &gt;
	           respectively
	 - AVAL - attribute value - escape " and ' with &quot; and &#39;
	          respectively
	By default ETEXT is used.

  TMPL_LOOP
	{%TMPL_LOOP NAME=loop_name%}...{%/TMPL_LOOP%}

	For this construct htmltmpl finds in a data set a property with name
	loop_name which contain an array.

  TMPL_IF
	{%TMPL_IF NAME=bool_var%}...{%/TMPL_IF%}
	{%TMPL_IF NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_IF%}

	This tag allows a conditional including of a html part in a result.
	If bool_var data set property evaluates to true, then a content
	between {%TMPL_IF%} and {%/TMPL_IF%} or between {%TMPL_IF%} and
	{%TMPL_ELSE%} is included in a result.

  TMPL_UNLESS
	{%TMPL_UNLESS NAME=bool_var%}...{%/TMPL_UNLESS%}
	{%TMPL_UNLESS NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_UNLESS%}

	The same as TMPL_IF, but bool_var property must evaluates to false.

  TMPL_INCLUDE
	{%TMPL_INCLUDE NAME=tmpl_name%}
	{%TMPL_INCLUDE NAME=tmpl_name VAR=var_name%}

	On template applying here will be located an output of applying a template
	with a name tmpl_name. The second form used for applying a
    specified template only if var_name var is defined; in this case
	a content of var_name var is used as data source for a template tmp_name
	applying. All needed templates must be placed in tmpls property of a
	htmltmpl object and must be htmltmpl objects by itself.

ifdef:
  TMPL_IFDEF
	{%TMPL_IFDEF NAME=bool_var%}...{%/TMPL_IFDEF%}
	{%TMPL_IFDEF NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_IFDEF%}

	This tag allows a conditional including of a html part in a result.
	If bool_var is defined, then a content between {%TMPL_IFDEF%} and
	{%/TMPL_IFDEF%} or between {%TMPL_IFDEF%} and {%TMPL_ELSE%} is
	included in a result.

  TMPL_IFNDEF
	{%TMPL_IFNDEF NAME=bool_var%}...{%/TMPL_IFNDEF%}
	{%TMPL_IFNDEF NAME=bool_var%}...{%TMPL_ELSE%}...{%/TMPL_IFNDEF%}

	The same as TMPL_IFDEF, but bool_var property must evaluates to undefined.

ifeq:
  TMPL_IFEQ
	{%TMPL_IFEQ NAME=var VALUE=VAL%}...{%/TMPL_IFEQ%}
	{%TMPL_IFEQ NAME=var WITH=another_var%}...{%/TMPL_IFEQ%}
	{%TMPL_IFEQ NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFEQ%}
	{%TMPL_IFEQ NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFEQ%}

	This tag allows a conditional including of a html part in a result.
	If var is equal to specified value VAL (or in form with WITH keyword,
	equal to a value of a specified variable), then a content between
	{%TMPL_IFEQ%} and {%/TMPL_IFEQ%} or between {%TMPL_IFEQ%} and
	{%TMPL_ELSE%} is included in a result.

  TMPL_IFNEQ
	{%TMPL_IFNEQ NAME=var VALUE=VAL%}...{%/TMPL_IFNEQ%}
	{%TMPL_IFNEQ NAME=var WITH=another_var%}...{%/TMPL_IFNEQ%}
	{%TMPL_IFNEQ NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFNEQ%}
	{%TMPL_IFNEQ NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFNEQ%}

	The same as TMPL_IFEQ, but var property must not be equal to specified
	VAL or another_var property value.

  TMPL_IFGT
	{%TMPL_IFGT NAME=var VALUE=VAL%}...{%/TMPL_IFGT%}
	{%TMPL_IFGT NAME=var WITH=another_var%}...{%/TMPL_IFGT%}
	{%TMPL_IFGT NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFGT%}
	{%TMPL_IFGT NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFGT%}

	The same as TMPL_IFEQ, but var property must be greater than specified
	VAL or another_var property value.

  TMPL_IFGE
	{%TMPL_IFGE NAME=var VALUE=VAL%}...{%/TMPL_IFGE%}
	{%TMPL_IFGE NAME=var WITH=another_var%}...{%/TMPL_IFGE%}
	{%TMPL_IFGE NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFGE%}
	{%TMPL_IFGE NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFGE%}

	The same as TMPL_IFEQ, but var property must be greater or equal to
	specified VAL or another_var property value.

  TMPL_IFLT
	{%TMPL_IFLT NAME=var VALUE=VAL%}...{%/TMPL_IFLT%}
	{%TMPL_IFLT NAME=var WITH=another_var%}...{%/TMPL_IFLT%}
	{%TMPL_IFLT NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFLT%}
	{%TMPL_IFLT NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFLT%}

	The same as TMPL_IFEQ, but var property must be less than specified
	VAL or another_var property value.

  TMPL_IFLE
	{%TMPL_IFLE NAME=var VALUE=VAL%}...{%/TMPL_IFLE%}
	{%TMPL_IFLE NAME=var WITH=another_var%}...{%/TMPL_IFLE%}
	{%TMPL_IFLE NAME=var VALUE=VAL%}...{%TMPL_ELSE%}...{%/TMPL_IFLE%}
	{%TMPL_IFLE NAME=var WITH=another_var%}...{%TMPL_ELSE%}...{%/TMPL_IFLE%}

	The same as TMPL_IFEQ, but var property must be less or equal to specified
	VAL or another_var property value.

ifin:
  TMPL_IFIN
	{%TMPL_IFIN NAME=var VALUES=[VAL1, ...]%}...{%/TMPL_IFIN%}
	{%TMPL_IFIN NAME=var VALUES=[VAL1, ...]%}...{%TMPL_ELSE%}...{%/TMPL_IFIN%}

	This tag allows a conditional including of a html part in a result.
	If var value is equal to any of specified values in VALUES attribute,
	then a content between {%TMPL_IFIN%} and {%/TMPL_IFIN%} or between
	{%TMPL_IFIN%} and {%TMPL_ELSE%} is included in a result.

func:
  TMPL_FUNC
	{%TMPL_FUNC NAME=func1%}
	{%TMPL_FUNC NAME=func2 ARGS=[arg_1,...] [ESCAPE=type]%}

	Call a js function with a name pointed in NAME attribute value and use
	it return value as a replacement text. Optional arguments can be given to
	function using ARGS attributes. Before apply() method is called, all needed
	functions must be placed in funcs property of an htmltmpl object:

	var tmpl = new htmltmpl(document.getElementById("tmpl_data"));
	tmpl.funcs.echo = function (str) { return "echoing " + str; };
	var result = tmpl.apply({ var: "data" });

	where html code is:

	<div id="tmpl_data" style="display: none">
		{%TMPL_VAR NAME=var%}
		{%TMPL_FUNC NAME=echo ARGS=["first argument"]%}
	</div>

	and result is:

	"
		data
		echoing first argument
	"

  TMPL_IFRET
	{%TMPL_IFRET NAME=func1%}...{%/TMPL_IFRET%}
	{%TMPL_IFRET NAME=func1%}...{%TMPL_ELSE%}...{%/TMPL_IFRET%}
	{%TMPL_IFRET NAME=func2 ARGS=[arg_1,...]%}
	{%TMPL_IFRET NAME=func2 ARGS=[arg_1,...]%}...{%TMPL_ELSE%}...{%/TMPL_IFRET%}

    On apply stage a function with name specified in NAME attribute value
    is called(with specified arguments in ARGS attribute value - like for
    TMPL_FUNC) and if it return value is an object, then it is inserted
    in the data stack and a content between {%TMPL_IFRET%} and {%/TMPL_IFRET%}
    or between {%TMPL_IFRET%} and {%TMPL_ELSE%} is included in a result.
    If a return value is null, then a content between {%TMPL_ELSE%} and
    {%/TMPL_IFRET%} is included instead(or nothing if there is no TMPL_ELSE).

list:
  TMPL_LIST
	{%TMPL_LIST NAME=list_name%}...{%/TMPL_LIST%}
	{%TMPL_LIST NAME=list_name%}...{%TMPL_LISTITEM [ESCAPE=type]%}...{%/TMPL_LIST%}

	For this construct htmltmpl finds in a data set a property with name
	list_name which contain an array. Each {%TMPL_LISTITEM%} construct is
	replaced with a current item from this array.
	ESCAPE attribute contains an escape type for a var value. See TMPL_VAR
	description for info about it.


Examples:
=========

A template:

	<div style="display: none" id="tmpl_div">
		<div>
		{%TMPL_LOOP NAME=loop1%}
			<div>{%TmPl_VaR NaMe=var1%}</div>
		{%/TMPL_LooP%}
		</div>
	</div>

A constructor call:
	var tmpl = new htmltmpl(document.getElementById("tmpl_div"),
		{case_sensitive: 0,
		 ret_dom: 1});

Next you must apply a data set to the template:

	var res = tmpl.apply({loop1: [{var1: 123},
								 {var1: "string"},
								 {var1: "str 456"}]});

After this you have an array with html elements in res represents the next
html code:

"
	<div>

		<div>123</div>

		<div>string</div>

		<div>str 456</div>

	</div>
"

You can attach it with jquery append() to any element in a DOM:

	$("#res").append(res);

Or simply:

	document.getElementById("res").appendChild(res[0]);

The more strict variant is to use a err_on_no_data option:

	var tmpl, el;

	tmpl = new htmltmpl(document.getElementById("tmpl_div"),
		{case_sensitive: 0,
		 err_on_no_data: 1});
	try {
		el = tmpl.apply({loop1: [{var1: 123},
								 {var1: "string"},
								 {var1: "str 456"}]});
	} catch (ex) {
		return alert("Error has been occured: " + ex);
	}