NAME
HTML::Embperl - Perl extension for embedding perl code in HTML documents
SYNOPSIS
Embperl is a perl extension module which gives you the ability to embed perl code in HTML documents (much like Server Side Includes for shell commands).
DESCRIPTION
Embperl can operate in one of four modes:
- Offline
-
converts a HTML file with embedded perl statements into a standard HTML file.
embpexec.pl [-o outputfile][-l logfile][-d debugflags] htmlfile [query_string]
- htmlfile
-
is the full pathname of the html file which should be processed by Embperl
- query_string
-
is optional and has same meaning as the environment variable QUERY_STRING when invoked as CGI-Script, i.e. everything following the first "?" in an URL. <query_string> should be url-encoded. Default is no query_string.
- -o outputfile
-
gives the filename to which the output is written. Default is stdout.
- -l logfile
-
is optional and give the filename of the logfile. Default is /tmp/embperl.log.
- -d debugflags
-
specifies the level of debugging (What is written to the logfile). Default is nothing. See below for exact values.
- As CGI-Script
-
instead of directly retrieving the document from the web-server, it is processed by the CGI-Script and the result is send to the client.
embpexec.pl
If
embpexec.pl
is invoked without any parameters and the environment variable PATH_TRANSLATED is set, it invoke it self as CGI-Script. That means form data is taken either from the environment variable QUERY_STRING or from stdin depending on CONTENT_LENGTH (this will be set by httpd depending on the method GET or POST). Input is taken from the file pointed to by PATH_TRANSLATED and output is send to stdout. The logfile is generated at it's default location (this is configurable via the environment variable EMBPERL_LOG).To use this mode you have to copy embpexec.pl to your cgi-bin directory. You can invoke it with the URL http://www.domain.xyz/cgi- bin/embpexec.pl/url/of/your/document.
The /url/of/your/document will be passed to Embperl by the web server. Normal processing i.e. aliasing etc. takes place before it is made to the filename contained in PATH_TRANSLATED.
If you are running apache httpd you can also define embpexec.pl as a handler for a specific file extention or directory.
Example of Apache
srm.conf
:<Directory /path/to/your/html/docs> Action text/html /cgi-bin/embperl/embpexec.pl </Directory>
- From mod_perl
-
(Apache httpd), this works like the CGI-Script, but with the advantage that the script is compiled only once at server startup, where also other one time action (such as opening files and databases ) can take place. This will drastically reduce response times for the request. To use this you have to compile
Apache httpd
withmod_perl
and addHTML::Embperl
asPerlHandler
.Example of Apache
srm.conf
:SetEnv EMBPERL_DEBUG 2285 Alias /embperl /path/to/embperl/eg <Location /embperl/x> SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI </Location>
See also under debugging (dbgLogLink and EMBPERL_VIRTLOG) how you can setup Embperl so you can view logfile with your browser!
- As standalone process
-
At the moment this is only for debugging because it can only handle one request at a time, no serialization takes place if more than one client is accessing an embperl-document. This mode has the same advantage as mod_perl, because the process is once started and running (hopefully) until the web server goes down. Data from the web-server is transferred via two named pipes. The first gives the data of the request and is feeded by a small c-program which is invoked as a CGI-Script and the second transfers the output back to the CGI-Program, which sends it to the client. This mode should work in conjunction with every web server, but to really use it a serialization (and maybe a management for multiple processes must be done)
embpexec.pl -D
or
embpexec.pl if PATH_TRANSLATED is not defined as a environment variable
This start Embperl as a Daemon. You have also to copy the file embcgi to your cgi-bin directory. This program is invoked as CGI-Script by the web server. The names of the named pipe which will be used must be changed in epmain.c and embpcgi.c before compiling it and the pipes must be created by hand (i.e. mkfifo) with read and write access for both processes, before starting the processes. Input- and Formdata is the same as for the CGI-Script. Logfile outut is going to stdout.
WARNING: Everybody who has write access to the named pipe can do things as user which runs Embperl daemon. So be carefully not to run Embperl as root unless you are sure nobody else can access it.
Runtime configuration
At the moment there are a few things which could be configured at runtime. This is done by setting environment variables, either on the command line (when working offline) or in your web servers configuration file. Most http daemons understand
SetEnv <var> <value>
- EMBPERL_LOG
-
gives the pathname of the log file. This will contain more or less infos about what Embperl is doing depending on the debug settings (see below). The log-output is specially intended to see what your embedded perl code is doing and to debug it. Default is /tmp/embperl.log
- EMBEPRL_VIRTLOG
-
gives a virtual location, where you can access the embperl logfile with a browser. This feature is disabled (default) if EMBPERL_VIRTLOG is not specified. See also dbgLogLink for an Example how to set it up in your srm.conf.
- EMBPERL_DEBUG
-
This is a bitmask which specifies what should be written to the log The following values are defined:
- dbgStd = 1,
-
Minimum Infos
- dbgMem = 2,
-
Memory and Scalar Value allocation
- dbgEval = 4,
-
Arguments and result of evals
- dbgCmd = 8,
-
Metacommands and HTML tags which are processed
- dbgEnv = 16,
-
List environement variables
- dbgForm = 32,
-
List form data
- dbgTab = 64,
-
Log processing of dynamic tables
- dbgInput = 128,
-
Log processing of html input tags
- dbgFlushOutput = 256,
-
Flush output after every write (Should normaly not set. Only for debugging when Embperl crashs, will drasticaly slow down operation)
- dbgFlushLog = 512,
-
Flush logfile after every line (Should normaly not set. Only for debugging when Embperl crashs, log is automatily flushed after each html file, when set will slow down operation)
- dbgAllCmds = 1024,
-
Logs all commands and HTML tags, regardless if they are really excuted or not. (Showing a + or - to tell you if they are executed).
- dbgSource = 2048,
-
Logs the next piece of the HTML-source which is processed. (Gives a lot of output!)
- dbgFunc = 4096,
-
Only anvailable when compiled with -DEPDEBUGALL. Normaly only used for debugging Embperl itself. Logs all functionentrys to the logfile (lot of data!)
- dbgLogLink = 8192,
-
Inserts a link on the top of each page, which can be used to view the log for current html file. See also EMBEPRL_VIRTLOG under configuration.
Example:
SetEnv EMBPERL_DEBUG 10477 SetEnv EMBPERL_VIRTLOG /embperl/log <Location /embperl/log> SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI </Location>
- dbgDefEval = 16386
-
Shows everytime a new perl-code is compiled
- dbgCacheDisable = 32768
-
Disables the usage of the p-code cache. All the perl code is recompiled everytime. (Should not be used in normal operation, slows down Embperl drasticaly)
- dbgEarlyHttpHeader = 65536
-
Normaly http-headers are send after the request was finished without any errors. This gives you the chance to set aribary http-header within the page, and Embperl the chance to calculate the content length. To do this all the output the kept in memory until the http-headers are send, and send afterwards. This flag will cause the http-headers to be send before script-processing and then the output directly without keeping it in memory (like versions before 0.18)
A good value to start is
2285
or10477
if you want to view the logfile with your browser (Don't forget to set EMBPERL_VIRTLOG). If Embperl crashs (you get a Segmentation fault) add512
so the logfile is flushed and you can see where Embperl crashs. - EMBPERL_NAMESPACE
-
gives the name of the namesspace within the code should be executed. If not defined executes in namespace HTML::Embperl:: with no operator restrictions. (with a normal eval statement).
NOTE at the moment if you use a namespace it is added automatiliy with all operators allowed. This will change in furthrer releases.
SYNTAX
Embperl understands four categories of commands. The first three are special Embperl command, the last category are some HTML-Tags which can trigger a special processing. Before the special Embperl-commands are processed and for the VALUE attribute of the input tag (see below), all HTML-Tags are removed and special HTML characters are translated to their ascii values (e.g. < is translated to "<" ). Embperl-commands can spawn multiple lines and not necessarily starts or ends at line boundary. You can escape from this behavior by preceding the special character or HTML tag with a backslash. This is done, so you can create your embperl-html- file with your favorite (WYSIWYG) HTML-Editor, no matter if it inserts tags like line breaks or formatting into your Embperl-commands where you don't want them. All Embperl-commands starts with a "[" and ends with a "]". To get a real "[" you must enter "[[".
I am not using sgml comments (i.e. <! ... !> or similar things) because some HTML-Editors can't create them or it's much more complicated. Sinces every HTML-Editor takes [ and ] as normal text, there should be no problem.
- [+ perl-code +]
-
Replace the command with the result of the perl code (The value returned by eval "perl-code"). As
perl-code
you can use everything which can be an argument to the perl eval statement (see Security below for restrictions). Examples:[+$a+] replaces the [+$a+] with the content of the variable $a [+$a+1+] every expression can be used [+ $x[$i] +] also array and hashes or more complex expressions works
NOTE:
White space are ignored The output will automaticly HTML escaped (e.g. "<" is translated to <). You do have to care about it. - [- perl-code -]
-
Executes the perl-code, but delete the whole command from the HTML output.
Examples:
[-$a=1-] set the variable $a to one, no output will be generated [-use somemodule-] you can use other modules [-$i=0; while ($i<5) {$i++} -] even more complex statements or multiple statements are possible.
NOTE: Statements like if, while, for, etc. must be included in one embperl command. You can not have the if in one command block and the terminating "}" or else in another.
- [$cmd arg$]
-
Execute a Embperl metacommand <cmd> can be one of the following (<arg> varies depending on <cmd>):
- if, elsif, else, endif
-
everything following the if metacommand until the else, elsif or endif is only outputted if the perl expression given in <arg> is true. else and elsif works analog.
Examples:
[$if $ENV{REQUEST_METHOD} eq 'GET' $] Method was GET<BR> [$else$] Method other than GET used<BR> [$endif$]
This will send one of the two sentence to the client, depending on the request method used to call the document.
- while, endwhile
-
Executes a loop until the <arg> given to while is false
Example: (see eg/x/while.htm)
[- $i = 0; @k = keys %ENV -] [$ while ($i < $#k) $] [+ $k[$i] +] = [+ $ENV{$k[$i]} +]<BR> [- $i++ -] [$ endwhile $]
This will send a list of all environment variables to the client.
NOTE: The '<' is translated to '<' before call the perl eval.
-
<arg> consists of zero, one or two names of hashs (without the leading %). The hidden metacommand will generated hidden fields for all data contained in first hash and not in second hash. Default for first hash is
%fdat
and for second hash%idat
. This is intended for situations where you want to pass data from one forms to the next, e.g. two forms which should be filled one after each other (e.g. an input form and a second form to review and accept the input). Here you can transport the data from previous forms within hidden fields. (See eg/x/neu.htm for an example).NOTE: This should only be used for small amount of data, since the hidden fields are sent to the browser, which sends it back at next request. If you have large data, store it within a file with a unique name and send only the filename within the hidden field. But be aware of the fact, that the data could be change by the browser if the user didn't behave exactly as you except. Your program should handle such situations properly.
- HTML Tags
-
Embperl recognizes the following HTML Tags (all other are simply passed through, as long as they not part of a Embperl command).
- table, /table, tr, /tr
-
Embperl can generate dynamic tables (one or two dimensional). You only have to specify one row/column. Embperl generates as much rows/columns as nessecary. This is done by using the magic variables $row, $col and $cnt. If you don't use $row/$cnt/$cnt within a table, Embperl does nothing and simply pass the table through. Embperl checks if the varibale $row/$col/$cnt is used. Embperl repeats all text between <table> and </table>, as long the expressions in which $row or $cnt occurs is/are defined. Embperl repeats all text between <tr> and </tr>, as long the expressions in which $col or $cnt occurs is/are defined.
See also $tabmode (below) for end of table criteria.
Examples: (see eg/x/table.htm for more examples)
[- @k = keys %ENV -] <table> <tr> <td>[+ $i=$row +] </td> <td>[+ $k[$row] +] </td> <td>[+ $ENV{$k[$i]} +] </td> </tr> </table>
This will show all entries in array @k (which contains the keys from %ENV), so the whole environment is displayed (like in the while example), with the first column containing the index (from 0) and the second containing the content of the array and the third the environment variable.
This could be used to display the result of database query if you have the result in an array. You make as much columns as you need. It is also possible to call a fetch subroutine in each table row.
- th, /th
-
th tags is interpreted as table heading. If the whole row is made of <th> </th> instead of <td> </td> it's treated as column heading. Everythingelse will be treated as row heading in the future, but is ignored in the current version.
-
Lists and Dropdown/Listboxes are treated excatly as one dimensional tables. Only $row, $maxrow, $cnt, $maxcnt and $tabmode are honoured. $col and $maxcol are ignored. see eg/x/lists.htm for an example.
- option
-
Embperl looks if theres a value from the form data for a specific option in a menu. If so this option will be preselected.
Example:
<form method="POST"> <P>Select Tag</P>
If you request this document with list.htm?SEL1=x you can specify that the element which has a value of x is initialy selected <p><select name="SEL1"> <option value="[+ $v[$row] +]">[+ $k[$row] +]</option> </select></p> </form>
- input
-
The input tag interacts with the hashs
%idat
und%fdat
. If the input tag has no value and a key exists with the same text as the NAME attribute of the input tag, Embperl generates a VALUE attribute which the corresponding value to the hashkey. All values of <input> tags are stored in the hash%idat
, which NAME as hashkey and VALUE as hashvalue. Special processing is made for TYPE=RADIO and TYPE=CHECKBOX. If the VALUE attribute contains the same text as the value of the hash the CHECKED attribute is inserted else it is removed. So if you specify as action url the file which contains the form itself, the form will be redisplayed with same values as entered in the first form. (See eg/x/neu.htm for an example) - textarea, /textarea
-
The textarea tags treated excatly like other input fields (see above)
Predefined variables
Embperl has some special variables which has a predefined meaning.
- %ENV
-
contains the environment as seen from a CGI-Script.
- %fdat
-
contains all the formdata send to the script by the calling form. The NAME attribute build the key and the VALUE attribute is used as hashvalue. Embperl doesn't matter if it's called with GET or POST method. (but there may be restrictions on the length of parameters using GET, not from Embperl but maybe from your Webserver, especialy if you using cgi-mode, so it's more save to use POST). Embperl also support multipart formdata, as it's been used for fileupload. For normal fields there is no difference to normal formdata, see docs of CGI.pm how fileupload fields are handled.
- @ffld
-
contains all the field names in the order they where send by the browser (normally as they appear in your form)
- %idat
-
contains all the values from all input tags processed so far.
- $row
-
row count for use in dynamic tables (see html tag table)
- $maxrow
-
maxium number of rows displayed in a table. This is set to 100 by default to prevent endless loops. (see html tag table)
- $col
-
column count for use in dynamic tables (see html tag table)
- $maxcol
-
maxium number of columns displayed in a table. This is set to 10 by default to prevent endless loops. (see html tag table)
- $cnt
-
contains the number of tables cells displayed so far (see html tag table)
- $tabmode
-
determintas how the end of a dynamic table is detected:
end of table
- 1
-
end when a expression with $row gets undefined (The row containing the undefined is not displayed)
- 2
-
end when a expression with $row gets undefined (The row containing the undefined is displayed)
- 3
-
end when $maxrow rows displayed
end of row
- 16
-
end when a expression with $col gets undefined (The column containing the undefined is not displayed)
- 32
-
end when a expression with $col gets undefined (The column containing the undefined is displayed)
- 63
-
end when $maxcol column displayed
default is 17 which is correct for all sort of arrays. You rarely should have to change it. The two values can be added together
- $req_rec
-
This variable is only available when running under control of mod_perl. It contains the request record needed to access the apache server api. See perldoc Apache for more information.
- LOG
-
is the filehandle of the embperl logfile, by writing print LOG "something" you can add lines to the logfile. NOTE: The logfileline should always start with the pid of the currect process and continue with a four character signature delimited by a ':', which specifies the log reason.
Example: print LOG "[$$]ABCD: your text\n" ;
NOTE 2: You must set the dbgFlushLog (= 512) to get the right order in the logfile. This will not be necessary any more in one of the next releases.
Namespaces and operator restrictions
Since most web servers will contain more than one document, it is necessary to protected them against each other. Embperl does this by using perl-namespaces. You can assign different names spaces to different directories (or even files within apache 1.2). If an Embperl document is scaned in a namespace all execution takes place within this namesspace and the code is not allowed to access another namespace as his own. This is done by the perl module Safe.pm. This gives also the ability to restrict the usage of perl operators, which can be defined with a operator mask. At the moment these features are at experimental state and can't be fully configured. Also there seems to be a memory leak.
UTILITY FUNCTIONS
- MailFormTo ($MailTo, $Subject)
-
Sends the content of the hash %fdat in the order specified by @ffld to the given $MailTo adresse, with the subject of $Subject.
If you specifiy the following example code as action in your form
<form action="x/feedback.htm" method="POST" enctype="application/x-www-form-urlencoded">
The content of the form will be mailed to the given email adress.
Example:
<html> <head> <title>Feedback</title> </head> <body> Your data has been sccesfully send! [- MailFormTo ('webmaster@domain.xy', 'Mail from WWW Form') -] </body> </html>
NOTE: You must have Net::SMTP (from libnet package) installed to use this function.
BUGS
At the moment Namespaces are at experimental state and can't be fully configured. Also there seems to be a memory leak.
Tainting doesn't work correct under perl5.004.
Under perl5.004 there are memory leaks, this is not an Embperl Bug, but can cause your httpd to endless grow when running under mod_perl. Please upgrade to perl5.004_04 to fix this.
FEEDBACK and BUGREPORTS
Please give me a feedback if you use/test this module. Bugs, questions, thinks you would find useful etc. are discussed on the mod_perl mailling list.
>From mod_perl README:
>For comments, questions, bug-reports, announcements, etc., join the >Apache/Perl mailing list by sending mail to >listserv@listproc.itribe.net with the string "subscribe modperl" in >the body.
>There is a hypermail archive for this list available from: >http://outside.organic.com/mail-archives/modperl/
SUPPORT
You can get free support on the mod_perl mailing list (see above). If you need commercial support (with a garantie for response time/a solution) for Embperl or want a web site where you can run your Embperl/mod_perl scripts without setting up your own internet www-server, please send an email to info@ecos.de.
WWW-LINKS
mod_perl http://perl.apache.org/ mod_perl FAQ http://www.ping.de/~fdc/mod_perl/ Embperl http://perl.apache.org/embperl.html apache web server http://www.apache.org/ see also http://www.perl.com/CPAN/modules/by-module/Apache/apache-modlist.html
AUTHOR
G.Richter <richter@dev.ecos.de>
SEE ALSO
perl(1), mod_perl, apache httpd.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 1068:
You forgot a '=back' before '=head1'