Parse::Plain - template parsing engine

- NAME
- SYNOPSIS
- DESCRIPTION
- METHODS
  - new
  - set_tag
  - get_tag
  - push_tag
  - unshift_tag
  - block
  - block_src
  - block_res
  - push_block
  - push_block_src
  - push_block_res
  - unshift_block
  - unshift_block_src
  - unshift_block_res
  - reset_block_src
  - reset_block_src_all
  - get_oblock
  - enum_blocks
  - set_text
  - get_text
  - set_parsed
  - gtag
  - callback
  - parse
  - unparse
  - unparse_all
  - output
- TIPS AND CAVEATS
- EXAMPLES
  - Using blocks
  - Using hidden blocks
  - Including files
- BUGS
- AUTHOR
- COPYRIGHTS

# NAME

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

# 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('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.

This version (2.1) contains most fuctionality of version 3.0 but is 100% compatible with 2.0x. This is probably the last 2.x version released.

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. Returns new value of tag (Warning: a random tag is returned if hash reference was passed!)

## get_tag

Get current value of tag. Parameter is a tag name. Returns tag value.

## push_tag

Append supplied value to current value of tag. Requires parameters: tag name and value. Value may be an instance of Parse::Plain. In this case parse method will be called automatically on value object. Returns new value of tag.

## unshift_tag

Prepend supplied value to current value of tag. Requires parameters: tag name and value. Value may be an instance of Parse::Plain. In this case parse method will be called automatically on value object. Returns new value of tag.

## block

Block source accessor, allows to set or get values of specific blocks. This method requires a input parameter list (blockname, value) to set blockname to value or just scalar blockname to get it's value. You should call block_src method instead. This method acts exactly like block_src but returns scalar value of block.

## 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 value to block, requires as input a list (blockname, value) You should call push_block_src method instead. This method acts exactly like push_block_src but returns scalar value of block.

## 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 value to block, requires as input a list (blockname, value) You should call unshift_block_src method instead. This method acts exactly like unshift_block_src but returns scalar value of block.

## 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 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