NAME
    Merge extensions - Writing your own tags to be used in Merge pages.

    HTML::Merge - Embedded HTML/SQL/Perl system by Raz Information Systems.

DESCRIPTION
    This file contains instructions as to how to create your own Merge tags.

TYPES OF TAGS
    Generally, there are four types of tags in Merge.

  Output tags
    Tags such as <$RVAR> or others, that are substituted by values that
    appear in the output. For example: <$RVAR.x> is substituted by the value
    of the vairable x.

  Non block tags
    Tags that perform an action, and have no corresponding closing tags. For
    example: <$RSET.x='8'> sets the value 8 into the variable x.

  Opening block tags
    Tags that usually handle the flow of the template. These tags, together
    with the closing tags, encapsulate a block of HTML and tags between
    them. The data inside the block will be treated as regular output
    statements. If you wish to capture it for a different use, a capturing
    mechanism (for example, using the Perl select() statement) needs to be
    used. For example, <$RITERATION.LIMIT=4> .. </$RITERATION> will print
    everything inside the block 4 times.

  Closing block tags
    The tags that close blocks beginning in the opening tags. The tags
    <$REND>, <$REND_IF> and <$REND_WHILE> are privilleged as closing tags.
    Other closing tags use the SGML like notation of specifying a slash
    before the name of the tag, for example: </$RCOUNT> is the closing tag
    for <$RCOUNT>

COMPILATION PROCESS
    Do not execute, create code!

    When Merge scans the template, it does not interprete the program, but
    creates Perl code to run it. The HTML code is converted to print()
    statements. Non block tags are inserted as generated Perl code. Block
    tags are added as generated code, that encapsulate a perl operation on
    the code within. Output tags depend on connotation: when specified in
    the middle of HTML code, the generated code will be used as a parameter
    for print(). When specified as part of a parameter for another tag,
    string concatenation is used to create one string. For example:

    <$RVAR.x> is translated to : print ($vars{"x"});

    <$RQ.'<$RVAR.x>'> is translated to: $engines{""}.Query("" . ($vars{"x"})
    . "")

    In both cases, the code generated by <$RVAR> is an expression, not a
    list of statements.

    Notice, that when using *any* parameter gotten for a tag, either assumed
    to be string or not, it must be encapsulated in double quotes. Consider
    we are writing a tag <$RSQR> and generating the code "sqr($x)". If the
    user tried <$RSQR.<$RVAR.x>>, we will get sqr(" . $vars{"x"} . ") which
    is not what we intended. Therefore we should create the code:
    "sqr(\"$x\")" Which can be sqr("3") for <$RSQR.3> or sqr("" . $vars{"x"}
    . "") for <$RSQR.<$RVAR.x>>.

    Hint: sometimes you need to perform a few sentences for generating an
    output tag. In this case it is better to create a function to run in
    runtime in the extension module, for example:

            sub Proper {
                    my $str = shift;
                    $str =~ s/(\w+)/ucfirst(lc($1))/ge;
                    $str;
            }

    and generate the code: "HTML::Merge::Ext::Proper(\"$x\")". Note that all
    the functions in the extension files reside under the namespace
    HTML::Merge::Ext.

    You can access the variable $HTML::Merge::Ext::ENGINE, or simply
    $ENGINE, to determine which engine was called for the tag. The engine
    API is not documented yet and might change without a warning.

EXTENSION FILES
    Extension files are created per site, as a file called merge.ext,
    residing in the instance directory, or per server, in the file
    /etc/merge.ext.

EXTENDED TAGS SYNTAX
    Every tag is defined as a function returning the Perl code for the tag.
    The function must have a prototype cotaining only scalars, to represent
    the number of input parameters.

    If we defined a tag called <$RUSER> with two parameters, it will be
    called as <$RUSER.<first parameter>.<second parameter>>. If parameters
    were encapsulated with quotes, it's the job of the user defined function
    to strip them.

    All special chars in the parameters will be quoted with a leading
    backslash using the function quotemeta. Special chars that were not
    quoted belong to the generated code the parameters might already
    contain. We basically encourage that you don't alter the parameters,
    except of stripping quotes if necessary.

    Here is an example for a tag called PLUS, that accepts two parameters,
    and is substituted by the result of their addition in the output. Notice
    that the function prototype is crucial.

            sub OUT_PLUS ($$) {
                    my ($a, $b) = @_;
                    "\"$a\" + \"$b\""; # Return perl code to perform the operation
            }

    Notes:

    1   The prototype defines two parameters.

    2   The parameters must be encapsulated with double quotes, even though
        we expect numbers.

        Here is how ***NOT*** to implement the tag:

                sub OUT_PLUS ($$) {
                        my ($a, $b) = @_;
                        return $a + $b; # or equally WRONG:
                        return '"' . ($a + $b) . '"''; 
                }

        You should not perform the operation in compilation time, but enable
        it to perform in run time. The second version will work for
        <$RPLUS.4.5> but NOT for <$RPLUS.5.<$RVAR.a>>, which will result in
        a hard coded zero.

IMPLEMENTING VARIOUS TAGS
    Functions should be in all uppercase, and consist of a prefix describing
    the type of the tag, an underscore, and the tag name. Merge is case
    insensitive, so don't try to define tags with lowercase names.

            For a non block tag, use the prefix B<API>.
            For a block opening tag, use the prefix B<OAPI>.
            For a block ending tag, use the prefix B<CAPI>.
            For an output tag, use the prefix B<OUT>.

    You can use the perl functions setvar, getvar and incvar to manipulate
    Merge variables.

    Here are some examples:

            sub OAPI_CSV ($) {
                    my $filename = shift;
                    $filename =~ s/^\\(["'])(.*)\\\1$/$2/; # Drop the quotes
                                                    # in compilation time!
                    <<EOM;
                    open(I, "$filename"); # Must use double quotes!
                    local (\$__headers) = scalar(<I>); # Do not use my() ! 
                    chop \$__headers;
                    local (\@__fields) = split(/,\\s*/, \$__headers);
                    # Notice that we must escape variable names with backslashes
                    while (<I>) {
                            chop;
                            my \@__data = split(/,\\s*/);
                            foreach my \$i (0 .. \$#__fields) {
                                    setvar(\$__fields[\$i], \$__data[\$i]);
                            }
            EOM
            }

            sub CAPI_CSV () {
                    "}";
            }

            Here is how we would use it:

            <$RCSV.'/data/<$RVAR.name>'>
                    <$RVAR.worker> has salary <$RVAR.salary><BR>
            </$RCSV>

            name could be 'workers.dat', and the file /data/workers.dat could be:

            worker, salary, office
            Bill, 9999999999999, Redmond
            George, 0, White House

MACRO TAGS
    Macro tags define a tag by simply grouping merge code to be susbtituted
    under it. Suppose we have two tags, <$RFIRST> that takes two parameters,
    and <$RSECOND> that takes two as well, we could define the tag
    <$RCOMBINED> this way:

            sub MACRO_COMBINED ($$$) {
                    <<'EOM';
            First $1 and $2: <$RFIRST.$1.$2><BR>
            Second $2 and $3: <$RSECOND.$2.$3><BR>
            EOM
            }

    This tag can now be called with three parameters. Note: You do not need
    to parse the parameters yourself in a Macro tag. You need to return a
    string containing Merge code and references to the parameters like in a
    shell script. Writing a prototype is still mandatory.

DESCRIBED TAGS
    Until now, extension tags could be called only with a list of parameters
    separated by commas. But merge enables defining tags that take a syntax
    similar to Merge native tags.

    Suppose we define a tag:

            sub OUT_MINUS ($$) {
                    my ($a, $b) = @_;
                    qq!("$a") - ("$b")!;
            }

    Now suppose we define a description function:

            sub DESC_MINUS {
                    'U-U';
            }

    We can now call the new tag: <$RMINUS.7-6> or <$RMINUS.<$RVAR.x>-1> and
    so on.

    All the non alpha characters in the description string stand for
    themselves. The following letters are assigned:

            U - Unquoted parameters (e.g. 9, ball, <$RVAR.a> etc).
            Q - Quote parameter, (e.g. 'building', "quoted string", 'a "parameter" with <$RVAR.a> inside')
            E - Call can end here, rest of the parameters optional. For example, a tag with the description QE:Q-QE*Q can be called as either 'first', 'first':'second'-'third' or 'first':'second'-'third'*'fourth'.
            D - Either a dot or equal sign.

MOD PERL COMPLIANCE NOTICE
    Merge implements the extensions by compiling them as Perl code into
    Merge itself. Therefore, on a mod_perl driven web server with several
    instances, extensions will be shared among all instances.

COPYRIGHT
    Copyright (c) 1999, 2000, 2001, 2002 Raz Information Systems Ltd.
    http://www.raz.co.il

    This package is distributed under the same terms as Perl itself, see the
    Artistic License on Perl's home page.

