=pod =head1 NAME HTML::Embperl - Perl extension for embedding Perl code in HTML documents =head1 SYNOPSIS Embperl is a Perl extension module which gives you the power to embed Perl code directly in your HTML documents (like server-side includes for shell commands). =head1 DESCRIPTION =head1 Operating-Modes Embperl can operate in one of four modes: =head2 Offline Converts an HTML file with embedded Perl statements into a standard HTML file. B B Use embpexec.pl on Unix systems and embpexec.bat on Win32 systems. =over 4 =item B The full pathname of the HTML file which should be processed by Embperl. =item B Optional. Has the same meaning as the environment variable QUERY_STRING when invoked as a CGI script. That is, QUERY_STRING contains everything following the first "?" in a URL. should be URL-encoded. The default is no query string. =item B<-o outputfile> Optional. Gives the filename to which the output is written. The default is stdout. =item B<-l logfile> Optional. Gives the filename of the logfile. The default is /tmp/embperl.log. =item B<-d debugflags> Optional. Specifies the level of debugging (what is written to the log file). The default is nothing. See L<"EMBPERL_DEBUG"> for exact values. =back =head2 As a CGI script Instead of a file being sent directly by the web server, the document is processed by the CGI script and the result is sent to the client. B B Use embpexec.pl on Unix systems and embpexec.bat on Win32 systems. If C is invoked without any parameters and the environment variable B is set, it runs itself as a CGI script. This means that form data is taken either from the environment variable B or from stdin, depending on whether or not B is set. (This will be set by the web server depending on whether the request method is GET or POST). Input is taken from the file pointed to by B and the output is send to stdout. The logfile is generated at its default location, which is configurable via the environment variable B. To use this mode you must copy B 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 (aliasing, etc.) takes place before the URI makes it to PATH_TRANSLATED. If you are running the Apache httpd, you can also define B as a handler for a specific file extention or directory. Example of Apache C: Action text/html /cgi-bin/embperl/embpexec.pl =head2 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 other one-time actions (such as opening files and databases) can take place. This will drastically reduce response times for the request. To use this you must compile C with C and add C as the C. Example of Apache C: SetEnv EMBPERL_DEBUG 2285 Alias /embperl /path/to/embperl/eg SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI Another possible setup (for Apache 1.3bX see below) is SetEnv EMBPERL_DEBUG 2285 SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI AddType text/html .epl Don't forget the B. In this setup, all files ending with .epl are processed by Embperl. C Since does not work the same in Apache 1.3bX as it does in Apache 1.2.x, you need to use instead. SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI See the section L<"EMBPERL_DEBUG"> (dbgLogLink and EMBPERL_VIRTLOG) to find out how you can configure Embperl so you can view the log file with your browser! =head2 By calling HTML::Embperl::Execute (\%param) Execute can be used to call Embperl from your own modules/scripts (for example from a Apache::Registry or CGI script) or from within another Embperl page (only 1.2b1 or higher) to nest multiple Embperl pages (for example to store a common header or footer in an different file). Execute takes a hash reference as its argument. This gives it the chance to vary the parameters according to the job that should be done. (See B for more detailed examples) Possible items are: =over 4 =item B The file which should be used as source. If B is also specified, this parameter should be given a unique name to identify the source. Every time Embperl sees the same text in B, it assumes that you compiled the same source - that means that Embperl uses the same package name as in your last call, and only recompiles the code if B has changed or is undefined. =item B Reference to a string which contains the source. B must also be specified to give a name for the source. The name can be any text. =item B Last modification time of member B. If undef the code passed by input is always recompiled, else the code is only recompiled if mtime changes. =item B File to which the output should be written. If neither outputfile nor output is specified, ouput is written to stdout. =item B Reference to a scalar where the output should be written to. =item B If used under mod_perl, you should set the req_rec parameter to the Apache request record object provided by mod_perl. =item B This value specifies if and when the cleanup of the package should be executed. (See L<"Variable scope and cleanup"> below for more information on cleanup) =over 4 =item B Never cleanup the variables =item B or not specified If running under mod_perl, cleanup is delayed until the connection to the client is closed, so it does not lengthen the response time to the client. If the Execute function is called more the once before the end of the request, all cleanups take place after the end of the request and not between calls to Execute. If running as a CGI or offline, cleanup takes place immediately. =item B Immediate cleanup =back =item B Can be used to pass parameters to the Embperl document and back. Must contain a reference to an array. Example: HTML::Embperl::Execute(..., param => [1, 2, 3]) ; HTML::Embperl::Execute(..., param => \@parameters) ; The array @Z<>param in the Embperl document is setup as an alias to the array. See eg/x/Excute.pl for a more detailed example. =item B Could be used to setup the two Embperl predefined variables. =item B Same as L<"EMBPERL_OPTIONS"> (see below), except for cleanup. =item B Same as L<"EMBPERL_DEBUG"> (see below). =item B Same as L<"EMBPERL_ESCMODE"> (see below). =item B Same as L<"EMBPERL_PACKAGE"> (see below). =item B Same as L<"EMBPERL_VIRTLOG"> (see below). If B is equal to B the logfile is sent. =item B The URI of the request. Only needed for the virtlog feature. =item B Same as L<"EMBPERL_COMPARTMENT"> (see below). B You should set the B if you have already read the form data from stdin while in a POST request. Otherwise Execute will hang and try to read the data a second time. =item B Same as L<"EMBPERL_INPUT_FUNC"> (see below). =item B Same as L<"EMBPERL_OUTPUT_FUNC"> (see below). =back =head2 Helper functions for Execute =over 4 =item B This function can be used to setup the logfile path and (optional) a default value for the debugflags, which will be used in further calls to Execute. There will always be only one logfile, but you can use B to change it at any time. B You do not need to call Init in version >= 0.27. The initialization of Embperl takes place automatically when it is loaded. =item B Scans the B<%ENV> and setups B<%params> for use by B. All Embperl runtime configuration options are recognized, except EMBPERL_LOG. =back =head2 EXAMPLES for Execute: # Get source from /path/to/your.html and # write output to /path/to/output' HTML::Embperl::Execute ({ inputfile => '/path/to/your.html', outputfile => '/path/to/output'}) ; # Get source from scalar and write output to stdout # Don't forget to modify mtime if $src changes $src = 'Page [+ $no +]' ; HTML::Embperl::Execute ({ inputfile => 'some name', input => \$src, mtime => 1 }) ; # Get source from scalar and write output to another scalar my $src = 'Page [+ $no +]' ; my $out ; HTML::Embperl::Execute ({ inputfile => 'another name', input => \$src, mtime => 1, output => \$out }) ; print $out ; =head1 Runtime configuration The runtime configuration is done by setting environment variables, either on the command line (when working offline) or in your web server's configuration file. Most HTTP servers understand SetEnv If you are using Apache and mod_perl you can use PerlSetEnv The advantage of PerlSetEnv over SetEnv is that it can be used on a per directory/virtual host basis. =head2 EMBPERL_FILESMATCH If specified, only files which match the given B will be processed by Embperl, all other files will be handled by the standard Apache handler. This can be useful if you have Embperl documents and non Embperl documents (e.g. gifs) cohabitating in the same directory. EMBPERL_FILESMATCH works only under mod_perl. Example: # Only files which end with .htm will processed by Embperl PerlSetEnv EMBPERL_FILESMATCH \.htm$ =head2 EMBPERL_COMPARTMENT Gives the name of the compartment from which to take the opcode mask. (See the chapter about L<"(Safe-)Namespaces and opcode restrictions"> for more details.) =head2 EMBPERL_ESCMODE Specifies the initial value for L<"$escmode"> (see below). =head2 EMBPERL_LOG Gives the location of the log file. This will contain information about what Embperl is doing. How much information depends on the debug settings (see L<"EMBPERL_DEBUG"> below). The log output is intended to show what your embedded Perl code is doing and to help debug it. The default is B. B When running under mod_perl you need to use B for setting the logfile path, and mod_perl >= 1.07_03 if you load Embperl at server startup (with PerlScript or PerlModule). =head2 EMBPERL_PACKAGE The name of the package where your code will be executed. By default, Embperl generates a unique package name for every file. This ensures that variables and functions from one file can not affect those from another file. (Any package's variables will still be accessible with explicit package names.) =head2 EMBPERL_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 L<"EMBPERL_DEBUG"> and dbgLogLink for an Example how to set it up in your srm.conf. =head2 EMBPERL_OPTIONS This bitmask specifies some options for the execution of Embperl: =over 4 =item optDisableVarCleanup = 1 Disables the automatic cleanup of variables at the end of each request. =item optDisableEmbperlErrorPage = 2 Tells Embperl to not send its own errorpage in case of failure, instead giving the error back to the web server and let the web server handle it the standard way. Without this option, Embperl sends its own error page, showing all the errors which have occurred. If you have dbgLogLink enabled, every error will be a link to the corresponding location in the log file. =item optSafeNamespace = 4 Tells Embperl to execute the embedded code in a safe namespace so the code cannot access data or code in any other package. (See the chapter about L<"(Safe-)Namespaces and opcode restrictions"> below for more details.) =item optOpcodeMask = 8 Tells Embperl to apply an operator mask. This gives you the chance to disallow special (unsafe) opcodes. (See the Chapter about L<"(Safe-)Namespaces and opcode restrictions"> below for more details.) =item optRawInput = 16 Causes Embperl not to pre-process the source for a Perl expression. (The only exception is that carriage returns will be removed, as Perl does not like them.) This option should be set when you are writing your code with an ASCII editor. If you are using a WYSIWYG editor which inserts unwanted HTML tags in your Perl expressions and escapes special charcaters automatically (e.g., `<' appears as `<' in the source), you should not set this option. Embperl will automatically convert the HTML input back to the Perl expressions as you wrote them. =item optEarlyHttpHeader = 64 Normally, HTTP headers are sent after a request is finished without error. This gives you the chance to set arbitrary HTTP headers within the page, and gives Embperl the chance to calculate the content length. Also Embperl watches out for errors and sends an errorpage instead of the document if something goes wrong. To do this, all the output is kept in memory until the whole request is processed, then the HTTP headers are sent, and then the document. This flag will cause the HTTP headers to be sent before the script is processed, and the script's output will be sent directly. =item optDisableChdir = 128 Without this option, Embperl changes the currect directory to the one where the script resides. This gives you the chance to use relative pathnames. Since directory-changing takes up some millisecs, you can disable it with this option if you don't need it. =item optDisableFormData = 256 This option disables the setup of %fdat and @Z<>ffld. Embperl will not do anything with the posted form data. =item optDisableHtmlScan = 512 When set, this option disables the scanning of B html-tags. Embperl will only look for [+/-/!/$ ... $/!/-/+]. This will disable dynamic tables, processing of the input data and so on. =item optDisableInputScan = 1024 Disables processing of all input-related tags. ( The TEXTAREA tag is treated exactly like other input fields. =back =item B will over-ride the corresponding http header. This keeps Netscape from asking the user to reload the document when the content-type differs between the http header and the meta http-equiv. This can also be used to set http headers. When running under mod_perl http-headers can also be set by the function B Example of how to set a http header: This is the same as using the Apache function [- $req_rec ->  header_out("Language" => "DE"); -] =head1 Variable scope and cleanup The scope of a variable declared with B or B ends at the end of the enclosing [+/- ... -/+] block; the [+/- ... -/+] blocks act much like Perl's { ... } in that regard. Global variables (everything not declared with B or B) will be undef'ed at the end of each request, so you don't need to worry about any old variables laying around and causing suspicious results. This is only done for variables in the package the code is eval'ed in -- every variable that does not have an explicit package name. All variables with an explicit package name (i.e., in modules you use) will stay valid until the httpd child process dies. Embperl will change the current package to a unique name for every document, so the influence between different documents is kept to a minimum. You can set the name of the package with B. (See also L<"(Safe-)Namespaces and opcode restrictions">.) Since a CGI script is always a process of its own, you don't need to worry about that when you use Embperl as a CGI script. If you need to declare variables which need to live longer than just one HTTP request (for example, a database handle), you must declare them in another package (i.e., $Persistent::handle instead of $handle). If you use the strict pragma, you can use the B metacommand to declare your variables. C Bacause Apache::DBI has its own namespace, this module will work together with Embperl to maintain your persistent database connection. You can disable the automatic cleanup of global variables with B or the B parameter of the B function. If you like to do your own cleanup you can define a subroutine B in your document. This will be called right before the variables are cleaned up, but after the connection to the client is closed. EXAMPLE: [! sub CLEANUP { close FH ; } !] =head1 Predefined variables Embperl has some special variables which have a predefined meaning. =head2 %ENV Contains the environment as seen from a CGI script. =head2 %fdat Contains all the form data sent to the script by the calling form. The NAME attribute builds the key and the VALUE attribute is used as the hash value. Embperl doesn't care if it is called with the GET or POST method, but there may be restrictions on the length of parameters using GET -- not from Embperl, but perhaps from the web server, especially if you're using Embperl's CGI mode -- it is safer to use POST. Embperl also supports ENCTYPE multipart/form-data, which is used for file uploads. The entry in %fdat corresponding to the file field will be a filehandle, as with CGI.pm. (Embperl uses CGI.pm internally to process forms encoded with multipart/form-data.) File upload example: HTML page:
Embperl ACTION: [- if (defined $fdat{ImageName}) { open FILE, "> /tmp/file.$$"; print FILE $buffer while read($fdat{ImageName}, $buffer, 32768); close FILE; } -] =head2 @ffld Contains all the field names in the order in which they were sent by the browser. This is normally -- but not necessarily -- the order in which they appear in your form. =head2 %idat Contains all the values from all input tags processed so far. =head2 %udat (only 1.2b1 or higher) You can use B<%udat> to store per user data. As long as you don't use %udat, nothing happens, but as soon as you write anything to %udat, Embperl creates a session id and sends it via a cookie to the browser. The data you have written to %udat is stored by Apache::Session. The next time the same user request an Embperl page, the browser sends the cookie with the session id back and Embperl fill the %udat hash from Apache::Session with just the same values as you have stored for that user. (See also L<"Session handling">) =head2 $row, $col Row and column counts for use in dynamic tables. (See L<"HTML tag table"|"HTML Tags">.) =head2 $maxrow, $maxcol Maxium number of rows or columns to display in a table. To prevent endless loops, $maxrow defaults to 100 and $maxcol to 10. (See L<"HTML tag table"|"HTML Tags">.) =head2 $cnt Contains the number of table cells displayed so far. (See L<"HTML tag table"|"HTML Tags">.) =head2 $tabmode Determines how the end of a dynamic table is detected: B =over 4 =item B<1> End when an expression with $row becomes undefined. The row containing the undefined expression is B displayed. =item B<2> End when an expression with $row becomes undefined. The row containing the undefined expression B displayed. =item B<4> End when $maxrow rows have been displayed. =back B =over 4 =item B<16> End when an expression with $col becomes undefined. The column containing the undefined expression is B displayed. =item B<32> End when an expression with $col becomes undefined. The column containing the undefined expression B displayed. =item B<64> End when $maxcol columns have been displayed. =back The default is B<17>, which is correct for all sort of arrays. You should rarely need to change it. The two values can be added together. =head2 $escmode Turn HTML and URL escaping on and off. The default is on ($escmode = 3). =over 4 =item B<$escmode = 3> The result of a Perl expression is HTML-escaped (e.g., `>' becomes `>') in normal text and URL-escaped (e.g., `&' becomes `%26') within an tag. =item B<$escmode = 2> The result of a Perl expression is always URL-escaped (e.g., `&' becomes `%26'). =item B<$escmode = 1> The result of a Perl expression is always HTML-escaped (e.g., `>' becomes `>'). =item B<$escmode = 0> No escaping takes place. =back =head2 $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 B for more information. =head2 LOG This is the filehandle of the Embperl logfile. By writing `print LOG "something"' you can add lines to the logfile. NOTE: The logfile line should always start with the pid of the current process and continue with a four-character signature delimited by a ':', which specifies the log reason. Example: print LOG "[$$]ABCD: your text\n" ; If you are writing a module for use under Embperl you can say tie *LOG, 'HTML::Embperl::Log'; to get a handle by which you can write to the Embperl logfile. =head2 OUT This filehandle is tied to Embperl's output stream. Printing to it has the same effect as using the [+ ... +] block. (See also L) =head2 @param Will be setup by the B<'param'> parameter of the B function. Could be used to pass parameters to an Embperl document and back. (see L for further docs) =head2 $optXXX $dbgXXX All options (see L<"EMBPERL_OPTIONS">) and all debugging flags (see L<"EMBPERL_DEBUG">) can be read and set by the corresponding variables. Example: [- $optRawInput = 1 -] # Turn the RawInput option on Now write something here [- $optRawInput = 0 -] # Turn the RawInput option off again [+ $dbgCmd +] # Output the state of the dbgCmd flag =head1 Session handling From 1.2b1 and higher Embperl is able to handle per user sessions for you. You can store any data in the L<%udat> hash and if the same user request again an Embperl document, you will see the same values in that hash again. To configure Embperl to do session management for you, you must have installed Apache::Session and loaded it before you load Embperl and you must tell Embperl which storage you would like to use for Apache::Session, by setting the environement variable EMBPERL_SESSION_CLASS. You may have a startup.pl for your httpd which looks like this: $ENV{EMBPERL_SESSION_CLASS}='File' ; use Apache::Session::File ; use HTML::Embperl ; 1 ; NOTE: You can use all the environement variables recognized by Apache::Session to configure it. Now you are able to use the %udat hash for your user sessions. As long as you don't touch %udat Embperl will not create any session, also Apache::Session is loaded. As soon as you store any value to %udat, Embperl will create a new session and send a cookie to the browser to maintain it's id, while the data is stored by Apache::Session. (Further version may also be able to use URL rewriting for storing the id). B =head1 (Safe-)Namespaces and opcode restrictions Since most web servers will contain more than one document, it is necessary to protect the documents against each other. Embperl does this by using Perl namespaces. By default, Embperl executes every document in its own namespace (package). This will prevent documents from accidentally overriding the other's data. You can change this behavior (or simply the package name) with the configuration directive B. NOTE: By explicitly specifying a package name, you can access data that is used by another document. If Embperl is used by more then one person, it may be neccessary to really protect documents from each other. To do this, Embperl gives you the option of using safe namespaces. Each document runs in its own package and can't access anything outside of this package. (See the documentation of Safe.pm for a more detailed discussion of safe namespaces.) To make a document run in a safe namespace, simply add B to B. The default package name used is the same as in normal operation and can be changed with B. NOTE: From the perspective of the document being executed, the code is running in the package B
! A second option to make Embperl more secure is the use of the opcode restriction mask. Before you can use the opcode mask, you must set up a safe compartment. B<$cp = HTML::Embperl::AddCompartment($name);> This will create a new compartment with a default opcode mask and the name $name. (The name is used later to tell Embperl which compartment to use.) Now you can change the operator mask. For example: B<$cp->deny(':base_loop');> In your configuration you must set the option B in B and specify from which compartment the opcode mask should be taken by setting B. Example (for use with mod_perl): B PerlScript startup.pl SetEnv EMBPERL_DEBUG 2285 Alias /embperl /path/to/embperl/eg SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI PerlSetEnv EMBPERL_OPTIONS 12 PerlSetEnv EMBPERL_COMPARTMENT test B $cp = HTML::Embperl::AddCompartment('test'); $cp->deny(':base_loop'); This will execute the file startup.pl on server startup. startup.pl sets up a compartment named `test', which will have a default opcode mask and additionaly, will have loops disabled. Code will be executed in a safe namespace. NOTE: The package name from the compartment is B used! Look at the documentation of Safe.pm and Opcode.pm for more detailed information on how to set opcode masks. =head1 Utility Functions =head2 AddCompartment($Name) Adds a compartment for use with Embperl. Embperl only uses the opcode mask from it, not the package name. AddCompartment returns the newly- created compartment so you can allow or deny certain opcodes. See the Safe.pm documentation for details of setting up a compartment. See the chapter about L<"(Safe-)Namespaces and opcode restrictions"> for details on how Embperl uses compartments. Example: $cp = HTML::Embperl::AddCompartment('TEST'); $cp->deny(':base_loop'); =head2 MailFormTo($MailTo, $Subject, $ReturnField) Sends the content of the hash %fdat in the order specified by @Z<>ffld to the given B<$MailTo> addressee, with a subject of B<$Subject>. If you specify $ReturnField the value of that formfield will be used as B. Usually, this will be the field where the user enters his e-mail address in the form. If you specifiy the following example code as the action in your form
The content of the form will be mailed to the given e-mail address. MailFormTo uses L<"EMBPERL_MAILHOST"> as SMTP server or B if non given. Example: Feedback [- MailFormTo('webmaster@domain.xy', 'Mail from WWW Form', 'email') -] Your data has been sccesfully sent! This will send a mail with all fields of the form to webmaster@domain.xy, with the Subject 'Mail form WWW Form' and will set the Return-Path of the mail to the address which was entered in the field with the name 'email'. B You must have Net::SMTP (from the libnet package) installed to use this function. =head2 exit B will override the normal Perl exit in every Embperl document. Calling exit will immediately stop any further processing of that page and send the already-done work to the output/browser. B This currently works only under mod_perl. B If you write a module which should work with Embperl under mod_perl, you must use Apache::exit instead of the normal Perl exit (just like always when running under mod_perl). =head1 Input/Output Functions =head2 ProxyInput ($r, $in, $mtime, $src, $dest) B SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI PerlSetEnv EMBPERL_INPUT_FUNC "ProxyInput, /embperl/ifunc, http://otherhost/otherpath" This input function will request the source from another URL instead of reading it from the disk. In the above USAGE Example, a request to /embperl/ifunc/foo.html, will first fetch the URL http://otherhost/otherpath/foo.html, and then it will process this document by Embperl and then it will send it to the browser. This could be used to process documents by mod_include B Embperl, so in one document there can be both Server-Side Includes and Embperl Commands. Example B for B and B: SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI PerlSetEnv EMBPERL_INPUT_FUNC "ProxyInput, /embperl, http://localhost/src" SetHandler server-parsed Options +Includes The source files must be in the location /src, but they will be requested via the URI /embperl. Every request to /embperl/foo.html will do a proxy-request to /src/foo.html. The file /src/foo.html will be processed by mod_include and then sent to Embperl, where it can be processed by Embperl before being sent to the browser. It would be also possible to use two httpd's on different ports. In this configuration, the source and the URI location could be the same. =head2 LogOutput ($r, $out, $basepath) B SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI PerlSetEnv EMBPERL_OUTPUT_FUNC "LogOutput, /usr/msrc/embperl/test/tmp/log.out" LogOutput is a custom output function. It sends the output to the browser B writes the output to a unique file. The filename has the the form "$basepath.$$.$LogOutputFileno". =head1 Inside Embperl - How the embedded Perl code is actually processed If Embperl encounters a piece of Perl code B<([+/-/!/$ .... $/!/-/+])> it takes the following steps. =over 4 =item 1. Remove anything which looks like an HTML tag =item 2. Translate HTML escapes to their corresponding ASCII characters =item 3. Remove all carriage returns =item 4. Eval the Perl code into a subroutine =item 5. Call the subroutine =item 6. Escape special characters in the return value =item 7. Send the return value as output to the destination (browser or file) =back Steps 1-4 take place only the first time the Perl code is encountered. Embperl stores the eval'ed subroutine, so all subsequent requests only need to execute steps 5-7. Steps 6 and 7 take place only for code surrounded by [+ ... +]. What does this mean? Let's take a piece of code like the following: [+
$a = "This '>' is a greater-than sign"
+] =head2 1. Remove the HTML tags. Now it looks like [+ $a = "This '>' is a greater-than sign" +] The
s were inserted by some WYSIWYG HTML editor (e.g., by hitting return to make the source more readable. Also, such editors often generate "random" tags like , etc.). Embperl removes them so they don't cause syntax errors. There are cases where you actually want the HTML tag to be there. For example, suppose you want to output something like [+ "" +] If you write it this way, Embperl will just remove everything, leaving only [+ "" +] There are several ways to handle this correctly. a. Move the HTML tag out of the Perl code. This is the best way, but it is not possible every time. b. [+ "\" +] You can escape the opening angle bracket of the tag with `\'. c. [+ "<FONT COLOR=$col>" +] You can use the HTML escapes instead of the ASCII characters. Most HTML editors will automatically do this. (In this case, you don't have to worry about it at all.) d. Set optRawInput (see below). This will completely disable the removal of HTML tags. NOTE: In cases b-d, you must also be aware of output escaping (see below). You should also be aware that Embperl will interpret the Perl spaceship operator (<>) as an HTML tag and will remove it. So instead of [- $line = ; -] you need to write either a. [- $line = \; -] b. [- $line = <STDIN>; -] Again, if you use a high-level HTML editor, it will probably write version (b) for you automatically. =head2 2. Translate HTML escapes to ASCII characters Since Perl doesn't understand things like $a < $b, Embperl will translate it to $a < $b. If we take the example from earlier, it will now look like [+ $a = "This '>' is a greater sign" +] This step is done to make it easy to write Perl code in a high-level HTML editor. You do not have to worry that your editor is writing > instead of > in the source. Again, sometimes you need to have such escapes in your code. You can write them a. \> Escape them with a `\' and Embperl will not translate them. b. &gt; Write the first `&' as its HTML escape (&). A normal HTML editor will do this on its own if you enter > as text. c. Set optRawInput (see below) This will completely disable the input translation. Since not all people like writing in a high level or WYSIWYG HTML editor, there is an option to disable steps 1 and 2. You can use the B in EMBPERL_OPTIONS to tell Embperl to leave the Perl code as it is. It is highly recommended to set this option if you are writing your HTML in an ASCII editor. You normally don't want to set it if you use some sort of high level HTML editor. You can also set the optRawInput in your document by using B<$optRawInput>, but you must be aware that it does not have any consequences for the current block, because the current block is translated before it is executed. So write it in separate blocks: [- $optRawInput = 1 -] [- $line = -] =head2 3. Remove all carriage returns All carriage returns (B<\r>) are removed from the Perl code, so you can write source on a DOS/Windows platform and execute it on a UNIX server. (Perl doesn't like getting carriage returns in the code it parses.) =head2 4. Eval perl code into a subroutine The next step generates a subroutine out of your Perl code. In the above example it looks like: sub foo { $a = "This '>' is a greater sign" } The subroutine is now stored in the Perl interpreter in its internal precompiled format and can be called later as often as necessary without doing steps 1-4 again. Embperl recognizes if you request the same document a second time and will just call the compiled subroutine. This will also speed up the execution of dynamic tables and loops, because the code inside must be compiled only on the first iteration. =head2 5. Call the subroutine Now the subroutine can be called to actually execute the code. If Embperl isn't executing a [+ ... +] block we are done. If it is a [+ ... +] block, Embperl needs to generate output, so it continues. =head2 6. Escape special characters in the return value Our example returns the string: "This '>' is a greater sign" The greater sign is literal text (and not a closing html tag), so according to the HTML specification it must be sent as > to the browser. In most cases, this won't be a problem, because the browser will display the correct text if we send a literal '>'. Also we could have directly written > in our Perl string. But when the string is, for example, the result of a database query and/or includes characters from national character sets, it's absolutely necessary to send them correctly-escaped to the browser to get the desired result. A special case is the
HTML tag. Since it includes a URL, the text must be URL-escaped instead of HTML-escaped. This means special characters like `&' must be sent by their hexadecimal ASCII code and blanks must be translated to a `+' sign. If you do not do this, your browser may not be able to interpret the URL correctly. Example: When $n is "My name" the requested URL, when you click on the hyperlink, will be http://host/script?name=My+name In some cases it is useful to disable escaping. This can be done by the variable B<$escmode>. Example: (For better readability, we assume that optRawInput is set. Without it, you need to cover the Embperl pre-processing described in steps 1-3.) [+ "" +] This will be sent to the browser as <FONT COLOR=5>, so you will see the tag on the browser screen instead of the browser switching the color. [+ local $escmode=0 ; "" +] This will (locally) turn off escaping and send the text as a plain HTML tag to the browser, so the color of the output will change. NOTE: You cannot set $escmode more than once inside a [+ ... +] block. Embperl uses the first setting of $escmode it encounters inside the block. If you need to change $escmode more than once, you must use muliple [+ ... +] blocks. =head2 7. Send the return value as output to the destination (browser/file) Now everything is done and the output can be sent to the browser. If you haven't set dbgEarlyHttpHeaders, the output is buffered until the successful completion of document execution of the document, and is sent to the browser along with the HTTP headers. If an error occurs, an error document is sent instead. The content length and every is added to the HTTP header before it is sent. If Embperl is executed as a subrequest or the output is going to a file, no http header is sent. =head1 Performance To get the best performace from Embperl, it is necessary to restrict logging to a minimum. You can drastically slow down Embperl if you enable all logging options. (This is why `make test' takes a while to run.) You should B enable B, B or B in a production environment. More debugging options are useful for development where it doesn't matter if the request takes a little bit longer, but on a heavily-loaded server they should be disabled. Also take a look at B for general ideas about performance. =head1 Bugs None known. Under perl5.004 there are memory leaks. This is not an Embperl bug, but can cause your httpd to grow endlessly when running under mod_perl. Please upgrade to perl5.004_04 to fix this. You should also upgrade to a mod_perl version higher than 1.07_01 as soon as possible, because until 1.07_01 there is a memory leak in Apache->push_handler. =head1 Compatibility I have tested Embperl succesfully =head2 on Linux 2.x with =over 4 =item perl5.004_04 =item perl5.005_01 =item apache_1.2.5 =item apache_1.2.6 =item apache_1.3b3 =item apache_1.3b5 =item apache_1.3b6 =item apache_ssl (Ben SSL) =item Stronghold 2.2 =back I know from other people that it works on many other UNIX systems =head2 on Windows NT 4.0 with =over 4 =item perl5.004_04 =item perl5.005 =item apache_1.3b5 =item apache_1.3.1 =back =head2 on Windows 95 with =over 4 =item perl5.004_02 (binary distribution) =item Offline mode =back =head1 Support =head2 Feedback and Bug Reports Please let me know if you use or test this module. Bugs, questions, suggestions for things you would find useful, etc., are discussed on the mod_perl mailing list. >From the mod_perl README: The Apache/Perl mailing list (modperl@apache.org) is available for mod_perl users and developers to share ideas, solve problems and discuss things related to mod_perl and the Apache::* (and Embperl) modules. To subscribe to this list, send mail to majordomo@apache.org 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/ There is an Epigone archive for the mod_perl mailing list at http://forum.swarthmore.edu/epigone/modperl =head2 Commerical Support You can get free support on the mod_perl mailing list (see above). If you need commercial support (with a guarantee for response time or a solution) for Embperl or want a web site where you can run your Embperl/mod_perl scripts without setting up your own web server, please send e-mail to info@ecos.de. =head1 References =head2 Information mod_perl http://perl.apache.org/ mod_perl FAQ http://perl.apache.org/faq Embperl http://perl.apache.org/embperl/ DBIx::Recordset ftp://ftp.dev.ecos.de/pub/perl/dbi apache web server http://www.apache.org/ ben-ssl (free httpsd) http://www.apache-ssl.org/ stronghold (commerical httpsd) http://www.c2.net/ europe http://www.eu.c2.net/ other Apache modules http://perl.apache.org/src/apache-modlist.html =head2 Download mod_perl http://www.perl.com/CPAN/modules/by-module/Apache Embperl ftp://ftp.dev.ecos.de/pub/perl/embperl DBIx::Recordset ftp://ftp.dev.ecos.de/pub/perl/dbi =head2 CVS The lastest developements are available from a CVS. Look at L<"perldoc CVS.pod"|CVS/"INTRO"> for a detailed description. =head1 Author G. Richter (richter@dev.ecos.de) =head1 See Also perl(1), mod_perl, Apache httpd