=head1 Name

Text::Wigwam::Tutorials::Basics - The basics of Wigwam templating.

=head1 Description

This tutorial explains the fundamentals of the Wigwam framework from a
template writer's perspective.

=head1 Introduction

Wigwam is a utility that provides the basic tools and features to build custom
template scripting environments. Because environments will vary, this tutorial
will focus on the the basic constructs and elements that make up Wigwam
templates.

=head1 Templates

Wigwam templates consist of simple plain-text documents which are interspersed
with special tags that act as place holders where data is to be inserted.
These tags contain tokens which can either represent data or manipulate it in
some way. When the template is parsed, each tag is systematically processed
from top to bottom and replaced by the resulting text that they produce.

=head2 Code tags

Code tags are denoted by a pair of delimiters, typically C<[!!> and C<!!]>,
and usually encompass one or more tokens which are separated by white-space.
These tags designate where data is to be inserted into the document.
Everything outside the boundary of a tag is simply left unaltered by the
parser.

=head2 Tokens

Tokens are the basic elements which make up the Wigwam scripting environment.
There are three basic types of tokens: literals; variables; and directives.

=head3 Literals

Literals are used to represent a value that does not change. There are two
types of literals: quoted; and unquoted numeric.

Quoted literals are identified by their surrounding quotation marks:

  [!! "This is a quoted literal" !!]
  [!! 'Single quotes can also be used' !!]

Unquoted numeric literals are any series of characters that equates to a valid
numeric value. 

  [!! -42 !!]   [!! 98.6 !!]   [!! +186E3 !!]

By default, Wigwam treats anything that appears to be a valid floating point
number as a literal numeric value. This behavior can be controlled via the
L<numbers|Text::Wigwam/configuration_tag> configuration option.

=head3 Variables

Variables are used to access values within Wigwam's variable space. Wigwam
variables are identified by their lack of identifier characters.

  [!! foo !!] [!! bar !!] [!! bazz !!]

=head3 Directives

Directives add functionality to the environment by allowing operations to be
performed within templates. They are identified by the hash mark preceding
them.

  [!! #directive !!]

Directives are stored in modules and plug-ins which can be loaded on demand
from within templates, thereby the directives available in any given template
environment depends upon which modules and plug-ins have been loaded. The
documentation for any given directive should be distributed with the plug-in
or module that provides it. Always consult this documentation to obtain the
specifics of its function and usage.

=head2 Arguments

Directives often require arguments to be used as parameters for performing an
operation. Arguments may consist of any of the three basic token types and are
always placed immediately after the directive (this is the basis of prefix
syntax).

The L<#define directive|Text::Wigwam::Library::Assignment/_define_var_val> demonstrated below
expects two arguments: a variable name; and a value. It assigns a value to a
variable and does not produce any output.

  1: [!! #define foo "bar" !!]
  2: [!! foo !!]
  output:
  1: 
  2: bar

I<Note: The numbers followed by colons in many examples herein serve no
purpose other than to demonstrate what is happening line by line as the
template is parsed.>

The most important thing to remember about directives is that each requires a
fixed number of arguments.

  1: [!! #define foo "bar" "bazz" !!]
  2: foo=[!! foo !!]
  output:
  1: bazz
  2: foo=bar

What's happening on line 1 is that C<#define foo "bar"> represents a single
expression which assigns the variable C<foo> the value C<bar> and produces no
output, thus we are left with the trailing literal C<"bazz">. This literal is
then interpolated in place of the tag on line 1. Line 2 demonstrates that the
C<foo> variable was assigned the value of the first literal, C<bar>.

=head2 Blocks

Blocks are used to group a number of tokens together so that their combined
values may be joined and used as a single argument. There are two types of
blocks: code blocks; and text blocks. Both block types may also contain an
unlimited number of nested blocks and will always produce a string value
(text).

=head3 Code blocks

Code blocks are represented by the brace characters C<{> and C<}>.

  1: [!! #define foo { "bar" "bazz" } !!]
  2: foo=[!! foo !!]
  output:
  1: 
  2: foo=barbazz

=head3 Text blocks

Text blocks are denoted by the special tag delimiters C<!!E<gt>> and
C<E<lt>!!> and are functionally equivalent to code blocks. As the name
implies, text blocks are expressed in text form and may contain embedded tags.

  1: [!! #define foo !!>bar bazz<!! !!]
  2: foo=[!! foo !!]
  output:
  1: 
  2: foo=bar bazz

Text blocks are typically used when it makes more sense to express a value as
a large block of text as opposed to a long string of tokens. As an example,
let's say you have a simple template code snippet that you've now decided you
want stored in a variable:

  The [!!thing!!] is guaranteed to [!!function!!] or your [!!cost!!] will be refunded!

An unappealing approach would be to convert it into a string of tokens, like
so:

  [!!
    #define variable {
      "The "
      thing
      " is guaranteed to "
      function
      " or your "
      cost
      " will be refunded!"
    }
  !!]

A much better alternative is to place the unaltered code snippet between text
block delimiters, as it doesn't require us to make any alterations to the code
snippet.

  [!! #define variable !!>
   The [!!thing!!] is guaranteed to [!!function!!] or your [!!cost!!] will be refunded!
  <!! !!]

=head2 Comments

Comments exist within tag delimiters and are used to document code. Anything
existing between the comment delimiters C</*> and C<*/> are ignored by the
parser.

  1: [!! #define foo 'bar' /* This assigns a value to a variable */ !!]
  2: [!! foo /* output the value of the variable */ !!]
  output:
  1: 
  2: bar

=head2 White-space trimming

White-space outside of any individual tag delimiter can be eliminated at
compile time by using the white-space trimming tag delimiters. These alternate
tag delimiters will remove all tabs and spaces directly outside the delimiter
up to and including the first new-line (if encountered before a non-tab or
non-space). Anything beyond that will be left untouched.

By default, Wigwam defines the following white-space trimming tag delimiters
which, outside of their white-space trimming function, are equivalent to their
non-trimming counterparts.

 [!~ /* White space trimming code tag delimiters */ ~!]
 [!!  ~!> White space trimming text block delimiters <!~  !!]

  The [!! 'quick ' ~!>
  brown <!! 'fox ' ~!]
  jump [!~ 'ed ' !!]
  [!~ 'over' !!> the
  <!~ ' lazy' !!] dogs.

produces

 The quick brown fox jumped over the lazy dogs.

=head2 Configuration tag

Each template may contain its own configuration options tag which is processed
prior to template execution. It can be used to specify parsing options,
debugging features, template characteristics (such as redefining tag
delimiters), or to load plug-ins & modules. 

These options are defined via a uniquely identified and specially formatted
configuration tag. They take the following form:

 << Wigwam
     Options: 
     /* Tag delimiters */
      code_open = [!!;
      code_term = !!];
      text_open = !!>;
      text_term = <!!;
     /* White space trimming tag delimiters */
      code_open_trim = [!~;
      code_term_trim = ~!];
      text_open_trim = ~!>;
      text_term_trim = <!~;
     /* Other common options */
      numbers = float;
      plugins = DirectiveSet;
      modules = Core/Cgi, Core/Html;
    /* These comments are ignored */
 >>

Only the first encountered configuration tag is processed for any given
template. Any other configuration tags within the template will be treated
as plain text. This feature is useful when dealing with templates that
generate other templates.

I<The configuration tag may also be used to define default settings for, or
impose restrictions upon, subsequently invoked templates, though that aspect
will not be covered in this tutorial.>

=head2 Data management

This section focuses on the basic conventions involved in managing Perl's
various data types from within templates.

=head3 Strings

String values are nothing more than text, so handling them is straightforward.

  1: [!! #define foo "bar" /* Store a string value into the variable foo */ !!]
  2: [!! foo /* echo the value */ !!] 
  output:
  1: 
  2: bar

=head3 Arrays

An array (sometimes referred to as a list) is simply an ordered list of values
which may consist of strings, arrays, hashes or nested data structures made up
of some combination of any or all of these data types.

Arrays can be defined within templates using the parenthesis characters C<(>
and C<)>. In the following example, we assign a list of values to the C<stuff>
variable, then proceed to access the individual values by suffixing the
variable which contains the array with a colon metacharacter followed by a
numeric representation of the element to be accessed.

  1: [!! #define stuff ( "one" "two" "three" ) !!]
  2: [!! stuff:0 !!]
  3: [!! stuff:1 !!]
  4: [!! stuff:2 !!]
  output:
  1:
  2: one
  3: two
  4: three

Another means for defining arrays is to use the angle brackets C<E<lt>> and
C<E<gt>>. They function like the parenthesis except that raw variable names
are interpreted as literals which enables you to define a long string of
literals without the need to painstakingly quote each one.

  1: [!! #define stuff < one two three > !!]
  2: [!! stuff:0 !!]
  3: [!! stuff:1 !!]
  4: [!! stuff:2 !!]
 output:
  1:
  2: one
  3: two
  4: three

Laziness is not the only motivation for the angle brackets - they also make
template code more readable in many situations.

=head3 Hashes

A hash is a list of values which are accessible by way of an associated key,
as opposed to an element number as with arrays. Like arrays, hash values may
consist of strings or nested data structures.

Hashes can be defined within templates by using the percent C<%> character to
cast an array into a hash, during which the array values are converted to
key/value pairs. The hash values can then be retrieved explicitly by suffixing
the variable containing the hash with a dot metacharacter followed by the key
which references the desired value.

  1: [!! #define hashlist %< one uno  two dos  three tres > !!]
  2: [!! hashlist.one !!]
  3: [!! hashlist.two !!]
  4: [!! hashlist.three !!]
  output:
  1: 
  2: uno
  3: dos
  4: tres

=head3 Backtick metacharacter

The backtick metacharacter can be used in place of either the dot or colon
metacharacters to detect the type of data being accessed and use the
appropriate lookup syntax to access the data stored there. It can also be used
to perform operations on the data itself.

The following example defines an array of data, displays the data, then
performs the same operation on a hash of data.

 0: [!! #macro showdata { #parameters <data> #foreach item data`values`sort  item } !!]
 1: [!! #define data < a b c d > /* Array */ !!]
 2: [!! &showdata(data) !!]
 3: [!! #define data %< Aye a Bee b Cee c Dee d > /* Hash */ !!]
 4: [!! &showdata(data) !!]
 output:
 1: 
 2: abcd
 3: 
 4: abcd

=head3 Variable Interpolation

Variable interpolation is an indispensable tool for accessing data indirectly.
Wigwam allows variable interpolation through the use of square brackets within
the variable names.

 [!! #define foobazz "FOOBAR" !!]
 [!! #define quux "bazz" !!]
 [!! foo[quux] !!]

produces:

 FOOBAR

Interpolation is typically used to access hash or array elements when the key
or element number is stored in a variable.

  [!!
   #define rules %<
     paper %<
       rock "You win - paper wraps rock"
       scissors "You lose - scissors cuts paper"
     >
     rock %<
       paper "You lose - paper wraps rock"
       scissors "You win - rock crushes scissors"
     >
     scissors %<
       rock "You lose - rock crushes scissors"
       paper "You win - scissors cuts paper"
     >
   >
  #define choice rules`keys`rand /* Random choice */
  #define challenge rules`keys`rand /* ditto */
  !!]
  I've chosen [!! choice !!], you challenge with [!! challenge !!].
  Outcome: [!! #or rules.[challenge].[choice] "We tie" !!].

There is no limit on the number of nested square brackets that can be used on
any given variable. 

=head2 Try it

You can try out Wigwam on-line using the html form at the following address:
L<http://www.wigwamhq.org/tryit/>

=head1 Author

DJOHNSTON, E<lt>djohnston@cpan.orgE<gt>
WINGNUT, E<lt>wingnut@cpan.orgE<gt>

The latest Wigwam version and documentation are available at
http://www.wigwamhq.org

=head1 Copyright and License

Copyright 2004-2007 by Scot Woodward and Daniel Johnston

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

=cut

