Andrew Alexandre Novikov

NAME

 Parse::Plain - template parsing engine (version 3.03)

SYNOPSIS

 # in user's code
 use Parse::Plain;
 
 my $t = new Parse::Plain('/path/to/filename.tmpl');
 my $t = new Parse::Plain('/path/to/filename.tmpl', 1, 2);
 
 $t->set_tag('mytag', 'value');          # %%mytag%% set to value
 $t->push_tag('mytag', '-pushed');       # %%mytag%% set to value-pushed
 $t->set_tag({'mytag' => 'value'});      # %%mytag%% set to value
 $t->unshift_tag('mytag', 'unshifted-'); # %%mytag%% set to unshifted-value
 
 # set a callback for tags like %%url:http://host.com/doc.html%%
 $t->callback('url', sub { return SomePackage::GetUrl($_[0]); });
 
 $t->push_block_src('myblock', 'some text to append to the block source');
 $t->unshift_block_res('myblock', 'some text to prepend to the block result');
 
 $t->parse('myblock', {'blocktag' => 'block value'});  # parse block
 $t->parse('myblock', {'blocktag' => 'another block value'});
 
 $t->parse;   # parse whole document
 $t->output;  # output parsed results to STDOUT
 
 $t->unparse; # reset parsed result to original template
 

DESCRIPTION

Parse::Plain is a Perl module for parsing text-based templates. It was designed to use with HTML, XHTML, XML and other markup languages but usually can be used with arbitrary text files as well.

Basic constructions in the templates are tags and blocks. Both must have names. Valid symbols for using in tag and block names are digits, latin letters, underscores, dashes, dots, semicolons, colons, commas, parentheses, asterisks, ampersands, slashes and caret symbols. An exclamation mark ('!') has special meaning and will be discussed later. All names are case sensitive.

Tag is a string in form %%tagname%%. There may be any number of tags with the same name and any number of different tags in the template.

Block is a construction that begins with line

  {{ blockname

and ends with symbols }}

Block-start element must be on separate line. There may be no other symbols from the beginning of line to the block-end element. However you may have other text (except block-start) after block-end on the same line (same as having those symbols on next line). Symbols between block-start and block-end form block body. Blocks are especially useful for iterative elements like table rows. Blocks can be nested and tags are allowed within block body.

There is also a special form of tag names. Let's say you have a block named myblock. Then in the template you can use tags named %%!myblock%% and they will be substituted to current value of myblock.

You can also hide block from place in template where it is defined by prepending ! to it's name. You'll still be able to use this block with appropriate tag names (with '!'). See "EXAMPLES" section.

There is a difference between source block and result block (as used in some method names). The source block is a chunk of text that is exactly as it appears in source template unless you have changed it using methods "block_src", "unshift_block_src", "push_block_src". The result block is a chunk of text that appears in the output and affected by calls to "parse" function on this block or may be modified with "block_res", "unshift_block_res", "push_block_res" methods as well. See description of these methods elsewhere in this document. To illustrate the difference:

  # source block named 'b' in template:
  # {{ b
  # -%%Y%%-
  # }}
  $val = $t->block_src('b');       # $val eq '-%%Y%%-'
  $val = $t->block_res('b');       # $val == undef
  
  # now let's modify source block
  $t->push_block_src('b', 'Z|');   # -%%Y%%-Z|
  $t->unshift_block_src('b', 'X'); # X-%%Y%%-Z|
  
  $val = $t->block_src('b');       # $val eq 'X-%%Y%%-Z|'
  $val = $t->block_res('b');       # $val == undef
  
  # now let's modify result block
  $t->parse('b', '1');             # result block: X-1-Z|
  $t->parse('b', '2');             # result block: X-1-Z|X-2-Z|
  $t->unshift_block_res('b', '|'); # result block: |X-1-Z|X-2-Z|
  
  $val = $t->block_src('b');       # $val eq 'X-%%Y%%-Z|'
  $val = $t->block_res('b');       # $val eq '|X-1-Z|X-2-Z|'
  

METHODS

new

The constructor. The first parameter (mandatory) is a path to template file. Template file must exist and be readable. If file cannot be read several attempts will be made (by default 5 attemts with 1 second interval between attemts). You can optionally change these values by passing additional paramteres to constructor ($lcnt_max and $ssec are respectively number of maximum retries and number of seconds to sleep between retries). If template cannot be read script dies.

set_tag

This method allows you to set tag values. There are two prototypes for this method. You may either pass a hash reference containing any number of tagname => value pairs or just pass two scalars (tagname and value).

Examples:

 $t->set_tag('mytag', 'value'); # set %%mytag%% to 'value'
 $t->set_tag({'mytag' => 'value', 'othertag' => 'otherval');

Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing tag_name => new_value pairs.

get_tag

Get current values of tags at. Parameter may be either array reference containing tag names or a list with tag names but not both intermixed. Returned value is a hash reference containing tag_name => value pairs. Using array reference as parameter is recommended.

push_tag

Append supplied values to current values of tags. There are two prototypes for this method. You may either pass a hash reference containing any number of tagname => value pairs or just pass two scalars (tagname and value). Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing tag_name => new_value pairs.

unshift_tag

Prepend supplied values to current values of tags. There are two prototypes for this method. You may either pass a hash reference containing any number of tagname => value pairs or just pass two scalars (tagname and value). Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing tag_name => new_value pairs.

block

Block accessor, allows to set or get values of specific blocks. This method exists for backwards-compatibility and accepts as input parameter only list (blockname, value) to set blockname to value or just scalar blockname to get it's value. You should call "block_src" or "block_res" methods instead. This method acts exactly like "block_src" if the block being accessed hasn't been parsed yet (this means that you haven't called yet "parse" method for this block from the object creation moment or after "unparse" call for this block). Elsewise this method acts like "block_res".

block_src

Block source accessor, allows to set or get values of sources of specific blocks. Arguments can be either scalar block name (to get it's value) or a pair of scalars ($block, $val) to set $block to $val or an array reference with block names to get their values or hash reference with { $block => $val, ... } pairs to set new values. Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing block_name => value pairs.

block_res

Block result accessor, allows to set or get values of results of specific blocks. Arguments can be either scalar block name (to get it's value) or a pair of scalars ($block, $val) to set $block to $val or an array reference with block names to get their values or hash reference with { $block => $val, ... } pairs to set new values. Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing block_name => value pairs.

push_block

Append supplied values to blocks. This method exists for backwards-compatibility and accepts only list with blockname, value as input parameter. You should call "push_block_src" or "push_block_res" methods instead. This method acts exactly like "push_block_src" if the block being accessed isn't parsed yet (this means that you haven't called yet "parse" method for this block from the object creation moment or after "unparse" call for this block). Elsewise this method acts like "push_block_res".

push_block_src

Append supplied values to block sources. There are two prototypes for this method. You may either pass a hash reference containing any number of block => value pairs or just pass two scalars (blockname and value). Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing block_name => new_value pairs.

push_block_res

Append supplied values to block results. There are two prototypes for this method. You may either pass a hash reference containing any number of block => value pairs or just pass two scalars (blockname and value). Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing block_name => new_value pairs.

unshift_block

Prepend supplied values to blocks. TThis method exists for backwards-compatibility and accepts only list with blockname, value as input parameter. You should call "unshift_block_src" or "unshift_block_res" methods instead. This method acts exactly like "unshift_block_src" if the block being accessed isn't parsed yet (this means that you haven't called yet "parse" method for this block from the object creation moment or after "unparse" call for this block). Elsewise this method acts like "unshift_block_res".

unshift_block_src

Prepend supplied values to block sources. There are two prototypes for this method. You may either pass a hash reference containing any number of block => value pairs or just pass two scalars (blockname and value). Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing block_name => new_value pairs.

unshift_block_res

Prepend supplied values to block results. There are two prototypes for this method. You may either pass a hash reference containing any number of block => value pairs or just pass two scalars (blockname and value). Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing block_name => new_value pairs.

reset_block_src

Resets block source values. The block source value may be changed invoking "block", "block_src", "push_block", "push_block_src", "unshift_block", "unshift_block_src", methods. This method allows you to restore block sources to it's original values from the source template. Parameter is either array reference or list containing block names to be restored. Returned value is a hash reference containing block_name => original_value pairs. Unlike "unparse" method this one changes block sources, not results.

reset_block_src_all

Calls "reset_block_src" for each block within template excpet outermost one (text).

get_oblock

Get original block source values. The block source value may be changed invoking "block", "block_src", "push_block", "push_block_src", "unshift_block", "unshift_block_src", methods. This method returns original values of block sources from the template. Unlike "reset_block" this method doesn't change current value of blocks. Parameter is either array reference or list containing block names to be restored. Returned value is a hash reference containing block_name => original_value pairs.

enum_blocks

Enumerate all blocks found in template. Takes no input. Return value is an array reference containing block names. Block names order is undefined.

set_text

Set text to argument. text is a special member containing outermost block source. Argument can be another instance of Parse::Plain. In this case "parse" method will be called on value object. Returns new value of text.

WARNING: Use with care and only when you are absolutely sure about what you are doing!

get_text

Returns current value of text. text is a special member containing outermost block source.

set_parsed

Set parsed to argument. parsed is a special member containing undef if outermost block has not been parsed yet or parsing result elsewise. Argument can be another instance of Parse::Plain. In this case "parse" method will be called on value object. Returns new value of parsed.

WARNING: Use with care and only when you are absolutely sure about what you are doing!

gtag

Global tag hash accessor. You may optionally set global tags that will be used in all blocks including outermost. These global tags have lesser priority then those set by "set_tag" method or "parse" arguments. Arguments can be either scalar tagname (to get it's value) or a pair of scalars (gtagname, val) to set gtagname to val or an array reference with tag names to get their values or hash reference with { $tag => $val, ... } pairs to set new values. Values may be another instances of Parse::Plain. In this case "parse" method will be called on value object. Returned value is a hash reference containing gtag_name => value pairs. Pass undef as value to remove global tag.

callback

Set callbacks. A callback allows you to have special tags in the form:

  %%tagname:param%%

For each such tag specified callback function will be called with param. Arguments to this method may be either pair of tagname, code reference or a hash reference containing pairs: { tagname => coderef, ... }. There is no return values. Pass undef as a coderef to remove given callback. You may not use colon in tagname. There is one predefined callback that allows you to include another templates within current. to do that just use tag %%INCLUDE:/path/to/file%%. In the file included all %%INCLUDE:%% tags will be processed recursively.

parse

Parse chunk of text using defined tags and blocks. If called without parameters the outermost block is parsed using tags and blocks defined so far. There are three optional parameters: $blockname, $hashref, $useglobalhash. First specifies block name to be parsed. You must call "parse" function on each block in your template at least once or the block will be ignored. You must also call "parse" function for each iteration of the block. See "EXAMPLES" section elsewhere in this document. You can also provide a referense to hash of tags used for parsing current block. For example:

  $t->parse('blockname', {'tag1' => 'val1', 'tag2' => 'val2'});

If you don't specify this hash reference hash filled by "set_tag" functions wiil be used instead. You can also use both hashes for parsing your block by setting third parameter to true. Returns parsing results (either text or block).

unparse

Reset block result values. This method allows you to reset some block results or the whole text (outermost block) so that you could "parse" it again from the scratch. Unlike "reset_block_src" this method only resets block result not source. If no input argument passed resets text (outermost block). To reset specific blocks pass an array reference or list with blocknames. Returns hash reference with pairs: { 'blockname' => 'old_block_result_value', ... }.

unparse_all

Calls "unparse" method for each block including outermost (text). Takes no input. Returns hash reference with pairs: { 'blockname' => 'old_block_result_value', ... } for each block except outermost one.

output

Print parsing results to STDOUT. If text hasn't been parsed yet calls "parse" method before. Returns parsed results.

TIPS AND CAVEATS

  • Names are case sensitive.

  • Non-defined tags and blocks are moved off from the result.

  • Block start and end elements may be padded with whitespaces or tabs for better readability.

  • Always parse innermost block before outer blocks or you may get mess.

  • Block start and end elements don't insert newline. Consider template fragment:

           He
      {{ myblock
    ll
      }}
    o

    One will be parsed to

           Hello

    line. However since version 3.00 you could also use such template:

           He
      {{ myblock
    ll
      }}o

    to get the same results as in the previous example.

  • You may not use colons in callback tagnames.

  • Obviously, it's not a very good idea to use this module for binary templates. ;-)

EXAMPLES

Using blocks

Template (template.tmpl):

 <table>
 <th>%%name%%</th>

 {{ block1
         <tr><td>%%tag1%%</td><td>%%tag2%%</td></tr>

 }}
 </table>

Code:

 use Parse::Plain;
 $t = new Parse::Plain 'template.tmpl';
 $t->set_tag('name', "My table");
 $t->parse('block1', {'tag1' => '01', 'tag2' => '02'});
 $t->parse('block1', {'tag1' => '03', 'tag2' => '04'}); 
 $t->output;

Output:

 <table>
 <th>My table</th>
         <tr><td>01</td><td>02</td></tr>
         <tr><td>03</td><td>04</td></tr>
 </table>

Using hidden blocks

Template (template.tmpl):

 <table %%border%%>
 
 {{ myblock
         <tr><td %%!hidden%%>%%value%%</td></tr>
 }} </table>
 
 {{ !hidden
 class="%%class%%" align="%%align%%"
 }}

Code:

 use Parse::Plain;
 $t = new Parse::Plain 'template.tmpl';
 $t->parse('hidden', {'class' => 'red', 'align' => 'right'});
 $t->parse('myblock', {'value' => '01'});
 $t->parse('myblock', {'value' => '02'});
 # we didn't define %%border%% tag
 $t->output;

Output:

 <table >
         <tr><td  class="red" align="right">01</td></tr>
         <tr><td  class="red" align="right">02</td></tr>
 </table>

Including files

Template 1 (template1.tmpl):

 Some text %%INCLUDE:template2.tmpl%%!

Template 2 (template2.tmpl):

 >>>%%INCLUDE:template3.tmpl%%<<<

Template 3 (template3.tmpl):

 0%%tag%%0

Code:

 use Parse::Plain;
 $t = new Parse::Plain 'template1.tmpl';
 $t->set_tag('tag', '!!!');
 $t->output;

Output:

 Some text >>>0!!!0<<<

BUGS

If you define a hidden block (with '!') and a nested block inside it and use then tag to show the hidden (outer) block behavior is undefined.

You have no way to change tag / block delimiters. See FAQ document provided with distribution for more details.

If you have found any other bugs or have any comments / wishes don't hesitate to contact me.

AUTHOR

  Andrew Alexandre Novikov.
  mailto: perl@an.kiev.ua
  www: http://www.an.kiev.ua/
  icq: 7593332

COPYRIGHTS

(C) Copyright 2003-2004 by Andrew A Novikov http://www.an.kiev.ua/

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html