NAME
       HTML::EP - a system for embedding Perl into HTML

SYNOPSIS
       <html><head><title>CGI-Env</title></head>
       <ep-comment>
           This is an HTML document. You see. Perhaps you wonder about
           the unknown HTML tags like ep-comment above? They are part
           of the EP system. For example, this comment section will
           be removed and you won't see it in your browser.
       </ep-comment>
       <ep-perl>
           # This is an example of embedding Perl into the page.
           # We create a variable called time, containing the current
           # time. This variable will be used below.
           my $self = $_;
           $self->{'time'} = localtime(time());
           ''; # Return an empty string; result becomes embedded into the
               # HTML page
       </ep-perl>
       <body><h1>The current time</h1>
           Your HTML::EP system is up and running: The current time is $time$.
       </body>
       </html>

DESCRIPTION
   Have you ever written a CGI binary? Easy thing, isn't it? Was
   just fun!

   Have you written two CGI binaries? Even easier, but not so much
   fun.

   How about the third, fourth or fifth tool? Sometimes you notice
   that you are always doing the same:

       Reading and parsing variables

       Formatting output, in particular building tables

       Sending mail out from the page

       Building a database connection, passing CGI input to the
       database and vice versa

       Talking to HTML designers about realizing their wishes

   You see, it's soon to become a pain. Of course there are little
   helpers around, for example the CGI module, the mod_perl suite
   and lots of it more. Using them make live a lot easier, but not
   so much as you like. the CGI(3) manpage. the mod_perl(3)
   manpage.

   On the other hand, there are tools like PHP or WebHTML.
   Incredibly easy to use, but not as powerfull as Perl. Why not
   get the best from both worlds? This is what EP wants to give
   you, similar to ePerl or HTML::EmbPerl. I personally believe
   that EP is simpler and better extendible than the latter two.
   the ePerl(1) manpage. the HTML::EmbPerl(3) manpage.

   In short, it's a single, but extensible program, that scans an
   HTML document for certain special HTML tags. These tags are
   replaced by appropriate output generated by the EP. What remains
   is passed to the browser. Its just like writing HTML for an
   enhanced browser!

 Prerequisites

   As far as I know EP depends on no system dependent features.
   However, it relies on some other Perl modules:

   CGI         The CGI module should be a part of your Perl core's
               installation. If not, you should definitely upgrade
               to Perl 5.004. :-) My thanks to Lincoln D. Stein
               <[email protected]>. Note, you need a late
               version, including the CGI::Cookie module.

   HTML::Parser
               This module is used for parsing the HTML templates.
               My thanks to Gisle Aas <[email protected]>.

   libwww      The LWP library contains a lot of utility functions, for
               example HTML and URL encoding and decoding. Again,
               my thanks to Gisle Aas <[email protected]>. :-)

   Mail::Internet
               Graham Barr <[email protected]> wrote the MailTools
               package. Some parts of it, in particular the
               Mail::Internet module is used for sending mail from
               within the HTML page. Thank very much, Graham!

   Storable    Raphael Manfredi's <[email protected]>
               excellent Storable module is used for storing
               sessions. I owe him much, as Storable is usefull in
               a lot of other modules.

   Perl itself and the above modules are available from any CPAN
   mirror, for example

          ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/by-module

   Note that you don't need to install these manually, the CPAN
   module will help you. See the the section on "Automatic
   Installation" below.

 Automatic Installation

   Installing this module (and the prerequisites from above) is
   quite simple, if you have the CPAN module available and network
   access, you might try an automatic installation:

           perl -MCPAN -e shell

   If the CPAN prompt appears, asking you for commands, enter

           install Bundle::HTML::EP

 Manual Installation

   If automatic installation doesn't work, you just fetch the
   archive, extract it with

       gzip -cd HTML-EP-0.1125.tar.gz | tar xf -

   (this is for Unix users, Windows users would prefer WinZip or
   something similar) and then enter the following:

       cd HTML-EP-0.1125
       perl Makefile.PL
       make
       make test

   If any tests fail, let me know. Otherwise go on with

       make install

   This will put the required Perl modules into a destination where
   Perl finds it by default. Additionally it will install a single
   CGI binary, called `ep.cgi'.

   The docs are available online with

       perldoc HTML::EP

   If you prefer an HTML version of the docs, try

       pod2html lib/HTML/EP.pm

   in the source directory.

 Using the CGI binary

   You have different options for integrating EP into your WWW
   server, depending on which server you are using and the
   permissions you have. The simplest possibility is running an
   external CGI binary. Another option is to use mod_perl with
   Apache, see the section on "Using mod_perl" below.

   I suggest that you choose an extension and configure your WWW
   server for feeding files with this extension into `ep.cgi'. For
   example, with Apache, you can add the following lines to your
   `srm.conf':

       ScriptAlias /cgi-bin/ep.cgi /usr/bin/ep.cgi
       AddType x-ep-script .ep
       Action x-ep-script /cgi-bin/ep.cgi

   This tells Apache that files with extension ep.cgi are handled
   by the CGI binary `/usr/bin/ep.cgi'. Make sure, that the
   ScriptAlias line is entered *before* any other ScriptAlias
   instruction! In particular, the following would be wrong:

       ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/
       ...
       ScriptAlias /cgi-bin/ep.cgi /usr/bin/ep.cgi

   The first rule would be applied before our rule, so that it
   could never match.

   From now on your server will never return files with extension
   .ep directly! Verify your installation by creating the following
   file:

       <html><head><title>Local time</title></head>
       <body>
       The current time is:
       <ep-perl>scalar(localtime(time))</ep-perl>
       </body>

   (Note that this is a much shorter version of the example in the
   synopsis.) Store it as `/test.ep' on your web server and
   retrieve the file via your Web server. If you see the time
   displayed, you are up and running.

 Using mod_perl

   The EP package can be integrated into mod_perl, for example by
   using the following commands in `srm.conf':

       PerlModule Apache::EP
       <Files *.ep>
         SetHandler perl-script
         PerlHandler Apache::EP->handler
         Options ExecCGI
       </Files>

   Keep in mind, that mod_perl differs in many details from
   programming CGI binaries. In particular you might need to
   restart Apache for loading changes in modules.

 Using the Internet Information Server

   I am sure there is a better way of installation, in the sense of
   mod_perl, however, I am no IIS expert. I can only recommend
   using Perl as an external binary, in the sense of CGI.

   The idea is to advice the IIS, that files with extension .ep
   have to be executed by running

           C:\Perl\bin\perl.exe c:\Perl\bin\ep.cgi %s%s

   with %s%s being the path to the EP document. (Of course the
   paths have to be adjusted to your local Perl.) This can be done
   by creating a new extension in the window "Base
   directory/Configure". (Window name translated from the german
   IIS, it�s "Basisverzeichnis / Konfigurieren" here and might be
   different in english.)

 Available methods

   All EP tags are starting with the prefix *ep-*. Some available
   tags are:

   ep-comment
       This is a multi-line tag for embedding comments into your
       HTML page. But why use this tag, instead of the usual HTML
       comment, `<!--'? The difference is, that the user will never
       see the former.

       Example:

           <html>
               <!-- This is a comment. I like comments. --!>
               <ep-comment>
                   This is another comment, but you won't see it
                   in your browser. The HTML editor will show it
                   to you, however!
               </ep-comment>
           </html>

       Do not try to embed EP instructions into the comment
       section! They won't produce output, but they might be
       executed anyways.

   ep-perl
       This is for embedding Perl into your script. There are two
       versions of it: A multiline version is for embedding the
       Perl code immediately into your script. Example:

           <html>
               <head><title>The Date</title></head>
               <body>
                   <h1>The Date</h1>
                   <p>Hello, today its the</p>
                   <p align=center>
                   <ep-perl>
                       # This little piece of Perl code will be executed
                       # while scanning the page.
                       #
                       # Let's calculate the date!
                       #
                       my($sec,$min,$hour,$mday,$mon,$year)
                           = localtime(time);
                       # Leave a string with the date as result. Will be
                       # inserted into the HTML stream:
                       sprintf("%02d.%02d.%04d", $mday, $mon+1, $year+1900);
                   </ep-perl>
                   </p>
               </body>
           </html>

       If you don't like to embed Perl code, you may store it into
       a different file. That's what the single-line version of ep-
       perl is for:

           <html>
               <head><title>The Date</title></head>
               <body>
                   <h1>The Date</h1>
                   <p>Hello, today its the</p>
                   <p align=center>
                   <ep-perl src="date.pl">
                   </p>
               </body>
           </html>

       You have noticed, that the little script's result was
       inserted into the HTML page, did you? It did return a date,
       in other words a string consisting of letters, digits and
       dots. There's no problem with inserting such a string into
       an HTML stream.

       But that's not always the case! Say you have a string like

           Use </html> for terminating the HTML page.

       This cannot be inserted as a raw string, for obvious
       reasons. Thus the ep-perl command has an attribute *output*.
       Use it like this:

           <ep-perl output=html>
               'Use </html> for terminating the HTML page.';
           </ep-perl>

       Possible values of the *output* attribute are `raw'
       (default), `html' (HTML encoded) and `url' (URL encoded).

       It's a common mistake, to use the Perl command `return' in
       embedded Perl. Never do that! If you need return (there are
       of course situations where returning can help), do it like
       this:

           <ep-perl>
               sub eval_me {
                   if ($this) {
                       return 'foo';
                   } elsif ($that) {
                       return 'bar';
                   }
                   '';
               }
               eval_me();
           </ep-perl>

       See the section on "Variables" below for interactions
       between Perl variables and EP variables.

       For security reasons, you might set an attribute *safe*, as
       in

           <ep-perl safe=1>...</ep-perl>

       This will create a Safe compartment for you and run the
       embedded script in the compartment. Using this attribute is
       highly recommended!

   ep-mail
       This command will send an e-mail. The attributes will be
       used for creating the email header, in particular the
       `subject', `from' and `to' attribute should be used.
       Example:

           <ep-mail subject="Howdy!" from="[email protected]"
                    reply-to="[email protected]" to="[email protected]">
               Hello, Bill, old chap. How are you?

               Yours sincerely,
               Jochen
           </ep-mail>

       You can still use EP variables in the E-mail body, for
       example the following works:

           <ep-mail subject="Test" reply-to="$cgi->email$" to="[email protected]"
                    from="[email protected]">
               Hello, Joe,
               this e-mail was sent to you by $@cgi->name$.
           </ep-mail>

       But note that we suppress conversion into HTML format in the
       mail body! See the section on "Variables" below for details.

       Recent sendmail versions are quite picky about validity of
       email addresses. Thus it is highly recommended that you use
       valid addresses for the *to* and *from* fields. If you want
       to customize the sender, you'd better choose a fixed *from*
       field and modify the *reply-to* field only, as in the
       example above.

   ep-errhandler
       This command advices EP, what to do in case of errors. See
       the section on "Error handling" below. Example:

           <ep-comment>
               Set the template being used for system errors.
           </ep-comment>
           <ep-errhandler type=system src=/templates/syserr.html>
           <ep-comment>
               Likewise, set the template for user errors.
           </ep-comment>
           <ep-errhandler type=user src=/templates/usererr.html>

       If an error occurs, the given scripts are loaded and used as
       templates instead of the current one. You don't need
       external files! Instead you can use

           <ep-errhandler type=user>
               <HTML><HEAD><TITLE>User error</TITLE></HEAD>
               <BODY><H1>User error</H1>
               <P>Replace user and continue. :-)</P>
               <P>To be serious, the following problem happened:</P>
               <PRE>$errmsg$</PRE>
               <P>Please return to the calling page, fix the problem
               and retry.</P>
               </BODY></HTML>
           </ep-errhandler>

       However, you might prefer to use a single error template and
       of course it's faster to use external error templates than
       parsing builtin templates. (At least, if no error occurs. :-
       )

   ep-error
       This command forces an error message. See the section on
       "Error handling" below. You can trigger user or system
       errors by setting the *type* attribute to the values
       `system' (default) or `user'. The *msg* attribute is for
       setting the error message.

       Example:

           <ep-comment>
               If no email address was entered, force a user error.
           </ep-comment>
           <ep-if eval="$cgi->email$">
               Email address is ok.
           <ep-else>
               <ep-error msg="Missing email address" type=user>
           </ep-if>

   ep-database
       This command connects to a database. Its attributes are
       `dsn', `user' and `password' corresponding to the same
       attributes of the DBI connect method. See the DBI(3) manpage
       for details on DBI.

       Example:

           <ep-database dsn="DBI:mysql:test" user="joe"
                        password="Authorized?Me?">

       You can use different database connections by using the
       *dbh* attribute:

           <ep-database dbh="dbh2" dsn="DBI:mSQL:test">

       The *dbh* attribute advices EP to store the DBI handle in
       the given variable. (Default: `dbh') See the section on
       "Variables" below.

   ep-query
       This command executes an SQL statement. The `query'
       attribute will be used for passing the SQL statement. Of
       course a multiline version is available, thus

           <ep-query statement="INSERT INTO foo VALUES (1, 'bar')">

       is the same as

           <ep-query>
               INSERT INTO foo VALUES (1, 'bar')
           </ep-query>

       If your query retrieves a result, use the `result' attribute
       to store it in a variable, for example like this:

           <ep-query statement="SELECT * FROM employees" result="employees"
                     resulttype="hash" startat=0 limit=-1>

       This will create a variable `employees', an array ref of
       hash refs. You can use the ep-list command for displaying
       the output. See the section on "Variables" below.

       When using multiple database connections, use the *dbh*
       attribute for choosing the connection. (See the *ep-
       database* method above.)

       If you have big result tables, you might prefer DBI's
       *fetchrow_arrayref* method over creating hash refs, because
       arrays are created faster than hash refs. This is achieved
       by setting the attribute *resulttype* to array. The default
       is hash. Other resulttypes are *single_hash* and
       *single_array*: If your query will return at most a single
       element, then the result variable will contain the first row
       (or an undefined value) and not an array.

       Sometimes you don't want to retrieve the complete result
       table. In that case you can use the attributes *startat* and
       *limit*. For example, to retrieve rows 0-19, use startat=0
       and *limit=20*. Likewise you would use startat=20 and
       limit=20 for rows 20-39.

       When using the *MySQL* engine, the *startat* and *limit*
       attributes are directly mapped to MySQL's *LIMIT* clause.

   ep-list
       This command is used to display an array of refs. Lets
       assume, that the variable `employees' contains a an array
       ref of refs with the attributes *name* and *department*.
       Then you could create a table of employees as follows:

           <table><tr><th>Nr.</th><th>Name</th><th>Department</th>
           <ep-list items="employees" item="e">
                  <tr><td>$i$</td><td>$e->name$</td><td>$e->department$</td>
           </ep-list>
           </table>

       This will be processed as follows: For any item in the
       array, retrieved from the variable `employees', create a
       variable `e' and display the text between ep-list and /ep-
       list for it by replacing the patterns $e->name$ and $e-
       >department$ with the corresponding values.

       The variable *i* is initially set to 0 and incremented by
       one with any element.

       As an alternative to the *items* attribute, you may prefer
       the *range* attribute: For example

         <ep-list range="1..12" item=month><OPTION>$month$</ep-list>

       will create the options array of a select box for you, where
       the user can select a month. If your prefer month names, you
       may better choose

         <ep-list range="jan,feb,mar,apr,jun,jul,aug,sep,oct,nov,dec"
          item=month><OPTION>$month$</ep-list>

       It is even possible to mix both versions, as in

         <ep-list range="1..3,6..7,10" item=m><OPTION>$m$</ep-list>

       See the *ep-select* command below for another example of the
       *range* attribute.

       It is possible to nest multiple ep-list statements, as in

         <ep-list range="1..3" item="i"><ep-list range="4..6"
           item="j">$i$$j$ </ep-list></ep-list>

       This will create the output "14 15 16 24 25 26 34 35 36".

   ep-select
       This is similar to ep-list, but it is specifically designed
       for creating SELECT boxes and similar things. We explain it
       by example:

           <ep-select name="year" range="1991..1995" item="y"
                      selected="$cgi->year$">
               <OPTION $selected$>$y$</ep-select>

       If you supply a *selected* attribute, then a variable
       *selected* will be created for any item. The value will be
       either an empty string or the word `SELECTED' (configurable
       via the attribute *selected-text*), depending on whether the
       item matches the *selected* value or not.

   ep-input
       This is usefull for reading an objects data out of CGI
       variables. Say you have a form with input fields describing
       an address, the field names being address_t_name,
       address_t_street, address_n_zip and address_t_city. By using
       the command

           <ep-input prefix="address_" dest="address">

       the EP program will create a variable "address" for you
       which is an hash ref as follows:

           $cgi = $_->{cgi};
           $_->{address} = {
               name =>   { col => 'name',
                           val => $cgi->param("address_name"),
                           type => 't',
                         },
               street => { col => 'street',
                           val => $cgi->param("address_street"),
                           type => 't',
                         },
               zip =>    { col => 'zip',
                           val => $cgi->param("address_zip"),
                           type => 'n',
                         },
               city =>   { col => 'city',
                           val => $cgi->param("address_city"),
                           type => 't'
                           }
           };

       In general column names beginning with *address* will be
       splitted into `prefix_type_suffix', the type being one of

   t           Text columns (CHAR, VARCHAR, BINARY, or whatever), that
               will be quoted using the $self->{'dbh'}->quote()
               method.

   n           Numeric columns (INTEGER, REAL, ...) that will be left
               untouched

   dd
   dm
   dy          Day, month and year of a date. The combined fields will
               be quoted as 'yyyy-mm-dd'.

   s           Set columns as created using MultiSelect boxes; the
               selected values will be used for creating a comma
               separated string.

       The idea is generating SQL queries automatically out of the
       `address' variable. This task is supported by the *sqlquery*
       attribute:

           <ep-database dsn="DBI:mysql:test">
           <ep-input prefix="address_" dest="a" sqlquery=1>
           <ep-comment>Create a new record, if no ID is given</ep-comment>
           <ep-if eval="$cgi->id$">
           <ep-query
            statement="INSERT INTO addresses ($@a->names$) VALUES ($@a->values$)">
           <ep-else>
           <ep-query
            statement="UPDATE addresses SET $@a->update$ WHERE id = $@id$">

       The *sqlquery* creates attributes *names*, *values* and
       *update* for you, that may be used in INSERT or UPDATE
       queries. Note that the *ep-input* must be preceeded by an
       *ep-database* call, because it is using DBI's *quote*
       method. the DBI(3) manpage.

       There are situations where you want to fetch not only a
       single object, but a list of objects. Suggest an order form
       of articles. Then you might have input fields
       *art_0_t_name*, *art_0_n_count*, *art_0_n_price*,
       *art_1_t_name*, ...

       In that case you can give the *ep-input* command an
       attribute list, like this:

           <ep-input prefix="art_" dest="art" list=1>

       The module will read an array ref of objects to the variable
       `dest'. Any object will have an additional scalar variable
       `i' referring to the items number, beginning with 0. In
       other words, you can process the order form as follows:

           <ep-input prefix="art_" dest="art" list=1>
           <ep-perl>
             my $self = $_;
             my $sum = 0.0;
             for (my $i = 0;  defined($self->{cgi}->param("art_$i_n_count"));
                  $i++) {
                 $sum += $self->{cgi}->param("art_$i_n_count") *
                         $self->{cgi}->param("art_$i_n_price")
             }
             ''
           </ep-perl>
           <ep-mail from="$cgi->email$" to="order@mydomain"
                    subject="Order form">
             The following items have been ordered:

               Nr.    Price   Article

             <ep-list>
               $art->count->val$  $art->price->val$  $art->name->val$
             </ep-list>

             Total sum: $sum$
           </ep-mail>

   ep-input-sql-query
           <ep-input-sql-query dest=art>

       This method is internally called by ep-input and implements
       the creation of the *names*, *values* and *updates*
       attributes.

       It takes as input the hash ref given by the variable *dest*,
       usually created by ep-input. The hash ref consists of column
       names as keys and hash refs with the attributes *type* and
       *val*.

       The main reason for putting this into a separate method is
       subclassing: It is quite usual, that you want ep-input to
       read the data, then do some verification and/or modification
       on the data (for example, canonicalizing dates) and finally
       create the SQL query. This can be done quite easily by
       subclassing the *_ep_input_sql_query* method: Within the
       method you verify and/or modify data entered by the user and
       then call the super class.

       For example, a typical subclass implementation could look
       like this:

         sub _ep_input_sql_query {
           my $self = shift;  my $attr = shift;
           # If the user left the MYCOL column empty, set it to NULL.
           my $dest = $attr->{'dest'};
           $self->{$dest}->{'MYCOL'} = undef
               if $self->{$dest}->{'MYCOL'} eq '';
           $self->SUPER::_ep_input_sql_query($attr);
         }

   ep-include
       Sometimes you want to source external files. This can be
       done by using

           <ep-include file="myfile">

       If a file with the given name doesn't exist, the file name
       is treated as being relative to your WWW servers
       *DOCUMENT_ROOT* directory.

   ep-exit
       This directive terminates processing of the current HTML
       page.

 Conditional HTML

   It is possible to blank out parts of the HTML document. See the
   following example:

       <html><head><title>Conditional HTML</title></head>
       <body>
         <h1>Conditional HTML</h1>
         <ep-if eval="$_->{cgi}->param('i') < 0">
           You have entered a negative number for i!
         <ep-else eval="$_->{cgi}->param('i') == 0">
           You have entered zero for i!
         <ep-else>
           <ep-if eval="$_->{cgi}->param('j') < 0">
             You have entered a negative number for j!
           <ep-else eval="$_->{cgi}->param('h') == 0">
             You have entered zero for j!
           <ep-else>
             Ok, both numbers are positive.
           </ep-else>
         </ep-else>
       </body>
       </html>

   The example is of course somewhat unnatural, because you'd
   better use a single ep-perl in that case, but it shows that we
   can use arbitrary complex structures of conditional HTML.

   The *eval* attribute is simply treated as a truth value, as in
   Perl. Thus empty strings or numeric zeros are FALSE, everything
   else is TRUE. This is reversed, if you replace *eval* with
   *neval*:

       <ep-if neval="$a$">
         a is not set
       <ep-else>
         a is set
       </ep-if>

   If you'd like to compare numeric values, use the *cnd*
   attribute, as in

       <ep-if cnd="$a$<$b$">
         a is lower than b
       <ep-else>
         a is greater than or equal to b
       </ep-if>

   You may choose either of ==, !=, <, >, <= or >= for the
   condition. And finally you may compare string values like this:

       <ep-if cnd="'$a$' eq '$b$'">
         a is equal to b
       </ep-if>

   Note the use of the single quotes, which is really required
   here. Available conditions are eq and ne.

   As with ep-list, you may nest multiple ep-if's or combine them
   with ep-list. The following is invalid, though:

     <ep-list range="1..3" item="i">
       <ep-if cnd="$i$<3">ok</ep-list></ep-if>

   As the ep-if starts within the ep-list, it must also be
   terminated before the corresponding /ep-list.

 Localization

   Localization is available via the HTML::EP::Locale module.
   Currently it only offers methods for localizing strings.

   To access the module, let's assume you prefer your visitors
   reading the german (de) version of your page, but it is also
   available in english (en). Then start your HTML page with

       <ep-package name="HTML::EP::Locale" accept-language="de,en">

   When the package is loaded, it tries to guess your documents
   language. The default language is *de* (german) or whatever you
   choose when installing the package. Another language can be
   specified by

   *       By setting the CGI variable *language*, for example by
           making a link to mypage.ep?language=en.

   *       By setting the environment variable *HTTP_ACCEPT_LANGUAGE*;
           most browsers do this for you. For example with
           Netscape, this variable is configurable via
           Edit/Preferences/Navigator/Languages.

   Two possibilities are available for localizing strings. For
   short strings like titles, headers or Link refs you might prefer
   this version:

       <ep-language de="Titel" en="Title">

   Obviously this is not appropriate for longer strings and it must
   not contain HTML patterns. Thus another version is available:

       <ep-language language=de>
         <p>Dies ist ein Absatz.</p>
         <p>Dies ist der zweite Absatz.</p>
       <ep-language language=en>
         <p>This is one paragraph.</p>
         <p>This is another paragraph.</p>
       </ep-language>

   Note you need not use a /ep-language for terminating the german
   part, similar to the ep-if, ep-elseif, ..., ep-else, /ep-if
   structure.

   A special problem with localization is the choice of a character
   set. You can fix a certain character set with something like

     <META HTTP-EQUIV="Content-type"
           CONTENT="text/html; CHARSET: iso-8859-2">

 Error handling

   Error handling with EP is quite simple: All you do in case of
   errors is throwing a Perl exception. For example, DBI handles
   are created with the RaiseError attribute set to 1, so that SQL
   errors trigger a Perl exception. You never care for errors!

   However, what happens in case of errors? In that case, EP will
   use the template that you have set with ep-errhandler and treat
   it like an ordinary EP document, by setting the variables
   `errmsg' and `admin'.

   If you don't set an error handler, the following template will
   be used, which is well suited for creating an own error
   template:

       <html><head><title>Internal error</title></head>
       <body><h1>Internal error</h1>
       <p>An internal error occurred. The server has not been able to
       fullfill your request. The error message is:</p>
       <pre>
           $errmsg$
       </pre>
       <p>Please contact the Webmaster,
       <a href="mailto:$admin$">$admin$</a>,
       tell him the URL, the time and error message.
       </p>
       <p>We apologize for any inconvenience, please try again later!</p>
       <br><br><br><p>Yours sincerely,</p><p>The Webmaster</p>
       </body>
       </html>

 Variables

   It is important to understand, how EP variables work, in
   particular when working with ep-perl.

   You always have an object $_, which is an instance of the
   HTML::EP class (a subclass of HTML::Parser). This object has
   certain attributes, in particular `$_->{cgi}', a CGI object and
   `$_->{dbh}', the DBI handle. (Of course valid after `ep-
   database' only.) If you want to set or modify a variable, you
   have to set `$_->{varname}'. If you want to retrieve the value,
   use the same. Note that you cannot use `$_' for a long time, as
   it will be changed by Perl loops and the like, thus your Perl
   code typically starts with

       $_ = $self;

   But how do you access the variable from within EP documents? You
   just write

           $varname$

   This will be replaced automatically by the parser with the value
   of `$_->{varname}'. Even more, the value will be converted into
   HTML source!

   If `varname' is a structured variable, for example a hash or
   array ref, you may as well use

           $varname->attrname$
   or

           $varname->0$

   to access `$_->{varname}->{attrname}' or `$_->{varname}->[0]',
   respectively. A special value of *varname* is `cgi': This will
   access the CGI variable of the same name, thus the following are
   equivalent:

           $cgi->email$

   and

           $_->{cgi}->param('email');

   But what, if you don't want your variable to be HTML encoded?
   You may as well use

           $@varname$      (Raw)
           $#varname$      (URL encoded)
           $~varname$      (SQL encoded)

   The latter uses the $_->{dbh}->quote() method. In particular
   this implies that you have to be connected to a database, before
   using this tag!

   You can even use these symbols in attributes of EP commands. For
   example, the following will be usefull when sending a mail:

       <ep-mail subject="Howdy!" from="$@cgi->email$"
                to="[email protected]">

   Attributes may include EP variables, just like ordinary HTML
   code. Even more, they may contain Perl code which is evaluated
   just like code between `<ep-perl>' and `</ep-perl>'. However,
   you need to use the variable `$_' in the code, because the
   package otherwise doesn't detect what you want it to do.

   See the section on "Custom variable formatting" for setting up
   your own formats.

   Of course you can set EP variables from within an ep-perl
   section. But sometimes it is desirable to set them from within
   HTML. In such cases you can do something like

     <ep-set var="a" val="b">

   Now, if you do a

     Variable a has the value $a$.

   the value b will be emitted. It is also possible to set
   multiline variables:

     <ep-set var="a">
       This is a template, extending a single line.
     </ep-set>

 Custom variable formatting

   Sometimes the builtin formatting methods of HTML::EP are not
   sufficient. A good example are currencies. These can be handled
   with format methods. For example, see the following method for
   german currency values:

       <ep-package name="MyPackage">
       <ep-perl>
           package MyPackage;
           sub _format_DM {
               my($self, $val) = @_;
               sprintf("%.2f DM", $val);
               $val =~ s/\./,/;
               $val;
           };
           ''
       </ep-perl>

   This can be used as follows, suggest we have the following
   variables:

       a = 1
       b = 2.4
       c = 34.47

   then we can use

       a = $&DM->a$                =>  1,00 DM
       b = $&DM->b$                =>  2,40 DM
       c = $&DM->c$                => 34,47 DM

   In other words: Use the special marker &, followed by the custom
   formats method name, the dereferencing operator and finally the
   variable name.

   The above method is already predefined by the HTML::EP::Locale
   module.

   As you have seen, the pattern $&METHODNAME->var$ triggers the
   call of

       $self->_format_METHODNAME($self->{'var'});

   It is not always usefull to fix a method name. In such cases you
   may instead store a code ref in

 Modifying the CGI headers

   The attribute $self->{'_ep_heaaders'} is containing arguments
   that you want to pass to CGI->header(). Use it like this:

       <ep-perl>
         $_->{'_ep_headers'} = { '-status' => '402 Payment required',
                                 '-expires' => '+3d'
                                }
       </ep-perl>

 Doing a redirect

   A redirect is moving the browser to another page without
   actually displaying the current page. You can do it like this:

       <ep-redirect target="http://other.server/other/page">

 Producing Non-HTML

   Say you want a CGI binary that creates a gif and not an HTML
   document. (See the `ifgif.ep' file from the SNMP::Monitor
   distribution for an example.) Two problems are arising here:
   First of all you have to create your own headers. Next you
   *must* prevent that EP is emitting any output, because this
   might trash your images validity. Here's what to do:

       <ep-perl>
           my $self = $_;
           my $cgi = $self->{'cgi'};
           $self->_ep_database({'dsn' => 'DBI:mysql:test',
                                'user' => 'joe',
                                'password' => 'joe'});
           $self->_ep_query({'statement' => "SELECT image FROM images WHERE"
                                 . " id = " . $cgi->param('id'),
                             'result' => 'im',
                             'resultype' => 'single_hash'});
           $self->print($cgi->header('-type' => 'image/gif'),
                        $self->{im}->{'image'});
           $self->Stop();
       </ep-perl>

   Note the use of $self->Stop()!

 NPH Scripts

   The Apache server and other WWW servers have a nice feature that
   allows you to return HTML pages line by line: If your script is
   called something like nph-myscript then the server is passing
   the scripts output to the browser immediately. This is usefull,
   for example, if you display the output of a traceroute command:
   You'd like to see any line immediately, but it may take some
   time untill the next line arrives.

   Unfortunately NPH scripts are not well suited for HTML::EP: One
   of EP's major targets is that you need not care for errors: They
   may occur at any point but are still catched and handled by
   creating an error message. However, there's no other way to
   guarantee this without buffering output until the script ends.

   If you really need to use NPH, do it like this:

       <ep-perl>
         my $self = $_;
         local $| = 1; # make sure that Perl isn't buffering
         $self->print($self->{'cgi'}->header('-type' => 'text/html',
                                             '-nph' => 1));
         for (my $i = 0;  $i < 20;  $i++) {
           $self->print("This is line $i. Waiting one second ...\n")
           sleep 1;
         }
         $self->Stop();
       </ep-perl>

   Note, that *no* more output will be produced by EP after calling
   $self->Stop()!

DEBUGGING
   Debugging CGI applications is always a problem. The EP module
   does its best to support you.

   Whenever you supply a CGI variable *debug*, then the module will
   enter debugging mode. For example if your document is
   `/mypage.ep', then tell your browser to fetch
   `/mypage.ep?debug=1'. You won't see the usual HTML page, but a
   plain text page with lots of debugging messages and the created
   HTML source.

   You may extend the debugging code with sequences like

       <ep-perl>
           my $self = $_;
           $self->print("I'm here!\n") if $self->{debug};
       </ep-perl>

   Note that you should not call the *print* function directly, but
   the *print* method! The former works well in CGI environments,
   but EP should work even in other environments as well.

   But sometimes this is not sufficient: What's inserting debugging
   messages compared to using the Perl debugger? In that case you
   can emulate a CGI environment as follows:

       export DOCUMENT_ROOT=/usr/local/www/htdocs
       export PATH_TRANSLATED=$DOCUMENT_ROOT/mypage.ep
       export REQUEST_METHOD=GET
       export QUERY_STRING="var1=val1&var2=val2"
       perl -d /usr/bin/ep.cgi

   This allows you single-stepping through your program, displaying
   variable values and the like.

   However, the debug variable is obviously a security problem. For
   that reason the *debughosts* variable is present in
   HTML::EP::Config: You should set it to a regular expression
   matching the IP numbers of hosts that are allowed to enable
   debugging mode. The Makefile.PL should query for appropriate
   settings automatically while running.

EXAMPLES
   The program comes with a set of examples incorporated. These
   are:

     - A simple Unix user administration in examples/admin.

     - A generic frontend for editing DBI tables in examples/edit.ep

     - A POP3 client for the web in examples/pop3.

   Other examples are:

     - The SNMP monitor, a utility for watching, logging and displaying
       interface utilization and status of network interfaces via WWW.
       See the directory authors/id/JWIED on any CPAN mirror, for example
       ftp://ftp.funet.fi/pub/languages/perl/CPAN.

     - The EP Explorer, an application I wrote for managing printer queues
       on a Unix hosts. The user can select a file for printing it, much
       like he did within the Windows explorer. Likewise, he can watch
       the printer status.

     - The HTML::EP::Glimpse package, a simple search engine based on
       Glimpse. (In other words, some flavour of WebGlimpse, which is
       much simpler to install and maintain and allows a free design.)

EXTENSIONS
   It is quite easy to write own methods.

 Single line extensions

   For example, suggest you want a method for setting EP variables:

       <ep-set var="e" value=1>

   Once the variable is created, you can access it via

      $e$

   This can be done like this:

       <ep-perl package="HTML::EP">
         # Write a handler for ep-env:
         sub _ep_set ($$) {
             my($self, $attr) = @_;
             my $var = $attr->{'var'};
             my $val = $attr->{'value'};
             $self->{$var} = $val;
             '';
         }

         # Return an empty string:
         '';
       </ep-perl>

   Note that we used the name _ep_set: By default the EP module
   takes the method name (ep-env in out case) translates all
   hyphens to underscores and adds a leading underscore. We'll see
   in the next section how you can override this behaviour.

 Multi line extensions

   But how to write methods, that use a `<tag>' .. `</tag>' syntax?
   As an example, we write a method for creating external files.
   The method receives two attributes, a *file* attribute for the
   files name and a *contents* attribute for the files contents.
   The method can be used in two ways:

       <ep-file file="test.dat" contents="Hi!">

   or like this, in multiline mode:

       <ep-file file="test.dat">
           Hi!
       </ep-file>

   Here it is:

       <ep-perl package="HTML::EP">
       # Write a handler for ep-file:
       sub _ep_file {
           my $self = shift; my $attr = shift;
           my $contents = $self->AttrVal($attr->{'contents'}, @_);
           my $file = $attr->{'file'};
           require Symbol;
           my $fh = Symbol::gensym();
           (open($fh, ">$file)  &&  (print $fh $contents)  &&
               close($fh)) or die "Error while creating $file: $!";
           '';
       }
       # Return an empty string:
       '';
       </ep-perl>

   The main difference to the previous example is that our method
   is that a special attribute (*contents*) is defined, that may be
   passed as part of the ep-file statement. However, if you don't
   define it as part of the statement, the *AttrVal* method reads
   more text from the document untill it finds a matching /ep-file.

   Note the use of the *Symbol* package when accessing files:
   *Never* use global handles like

       open(FILE, ...)

   as this might break future multithreading code!

   The above example works well, if you don't need to nest your
   statement. If this should be the case, you need to deal with
   EP's token streams. See the ep-if and ep-list methods for
   examples.

 External extensions

   So far we have discussed only minor extensions that we did
   install as part of HTML::EP. However, this is somewhat dangerous
   with mod_perl: Suggest you have multiple virtual hosts. It might
   happen, that virtual host www.foo.com defines a method ep-file,
   but www.bar.net defines another. We'd have an immediate name
   space clash.

   To prevent such a namespace pollution, EP supports external
   extensions with an inheritage model that is borrowed from Perl.
   Suggest we write a Shop extension. Of course this extension
   borrows from HTML::EP::Session. Thus we have the following class
   design:

       Shop  ---isa--->  HTML::EP::Session  ---isa--->  HTML::EP

   We start writing our Shop extension like any other Perl package:

       package Shop;
       @Shop::ISA = qw(HTML::EP::Session); # HTML::EP::Session inherits
                                           # from HTML::EP

       sub _ep_shop_session {
           my($self, $attr) = @_;
           # Initialize the session
           ...
           '';
       }

       sub init {
           my $self = shift;
           if (!$self->{'_ep_shop_initialized'}) {
               $self->{'_ep_shop_initialized'} = 1;
               $self->SUPER::init();
               # Do something here
               ...
           }
       }

   In the HTML page we load this package as follows:

       <ep-package name="Shop">
       <ep-shop-session>

   This will do a require Shop, bless the object $self into the
   class *Shop* and call $self-init()>. Note that we allow the init
   method to be called more than once, this is important for
   stacking packages.

   By default packages are loaded from Perl's system directories.
   You can use the attribute *lib* to add private directories to
   the library search path. This can be relative to the servers
   document root, as in

       <ep-package name="Shop" lib="/perl-lib">

 Inheriting from multiple extensions

   You may use multiple ep-package statements, as in

       <ep-package name="HTML::EP::Locale">
       <ep-package name="HTML::EP::Session">

   Your object will be blessed into a new class, that inherits from
   both. However, note that the order is reversed: In the above
   example, your object will be an instance of class
   HTML::EP::PACK2 and HTML::EP::PACK2::ISA will be set to

       qw(HTML::EP::Session HTML::EP::Locale)

CHANGES
   This section describes user visible changes against previous
   versions. For details and other modifications see the
   `ChangeLog' file, that is part of the distribution.

   epparse
   epperl  In previous versions it was not possible to include EP
           variables or Perl code in attributes of EP commands,
           unless using a prefix `epparse-' or `epperl-', as in

               <ep-mail to=joe epparse-from="$cgi->mail$" subject=Hello>

           This is no longer the case, because the package now
           autodetects whether you are using such constructs. (At
           least it should. :-) The obvious disadvantage is an
           incompatibility, but the new version is much better
           readable and surprisingly even (much!) faster, because
           only hash values are modified and not hash structures.

TODO
           Create an EP server that is accessible via a small C wrapper

           Add a preprocessor, that creates Perl code as output.

AUTHOR AND COPYRIGHT
   This module is

       Copyright (C) 1998-1999     Jochen Wiedmann
                                   Am Eisteich 9
                                   72555 Metzingen
                                   Germany

                                   Phone: +49 7123 14887
                                   Email: [email protected]

   All rights reserved.

   You may distribute this module under the terms of either the GNU
   General Public License or the Artistic License, as specified in
   the Perl README file.

SEE ALSO
   the DBI(3) manpage, the CGI(3) manpage, the HTML::Parser(3)
   manpage