.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Embperl 3pm" .TH Embperl 3pm "2023-01-22" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Embperl \- Building dynamic Websites with Perl .SH "SYNOPSIS" .IX Header "SYNOPSIS" For a list of available Embperl documentation please view Embperl::TOC with \fBperldoc\fR\|(1) or \fBman\fR\|(1). If Embperl is not yet installed, have a look at perldoc \s-1TOC\s0.pod in the distribution archive. .SH "DESCRIPTION" .IX Header "DESCRIPTION" Embperl is a framework for building websites with Perl. .PP For the beginner it's any easy to setup and use way of embedding Perl code in \s-1HTML\s0 pages. .PP It delivers several features that ease the task of creating a websites, including dynamic tables, formfield-processing, escaping/unescaping, session handling, caching and more. .PP If your demands grows it gives you the power to make your Web site object-oriented and build it out of small reusable components. If you don't like the idea of mixing up all your layout and code Embperl supports separating it in different objects (e.g. createing an \&\s-1MVC\s0 application). Of course Embperl doesn't ties you to \s-1HTML,\s0 it allows components to be from different source formats (e.g. \s-1HTML, WML, XML, POD, ...\s0) and if necessary transforms it (for example via \s-1XSLT\s0) to other output formats. This is achieved by diving the output generation in small steps, where each is processed by a plugable provider. .PP Advanced user can create their own syntax definitions (for example tag libraries) and extent Embperl by writing their own providers and much more .PP \&\fB\s-1IMPORTANT:\s0\fR This document describes the syntax and several features of Embperl. Please read also perldoc Config.pod, which describes how to configure Embperl and how to access the different Embperl objects and their data. Also take a look at perldoc Embperl::Object to learn how to use Embperl page as objects. .PP Additionally there are a few introductions documents should consider to read: Intro.pod, IntroEmbperl2.pod and IntroEmbperlObject.pod. .SH "SYNTAX" .IX Header "SYNTAX" Embperl understands two categories of commands. The first one are special Embperl commands, and the second category consists of some \s-1HTML\s0 tags which can trigger special processing. Embperl commands can span multiple lines and need not start or end at a line boundary. .PP Before the special Embperl commands are processed, and for the \s-1VALUE\s0 attribute of the \s-1INPUT\s0 tag (see below), all \s-1HTML\s0 tags are removed and special \s-1HTML\s0 characters are translated to their \s-1ASCII\s0 values (e.g., `<' is translated to `<'). You can avoid this behavior by preceding the special character or \s-1HTML\s0 tag with a backslash. This is done in case your favorite (\s-1WYSIWYG\s0) \s-1HTML\s0 editor inserts tags like line breaks or formatting into your Embperl commands where you don't want them. .PP All Embperl commands start with a `[' and end with a `]'. To get a real `[' you must enter `[['. .PP Embperl does not use \s-1SGML\s0 comments (i.e., or similar things) because some \s-1HTML\s0 editors can't create them, or it's much more complicated. Since every \s-1HTML\s0 editor takes (or \fBshould\fR take) `[' and `]' as normal text, there should be no problem. .SS "[+ Perl code +]" .IX Subsection "[+ Perl code +]" Replace the command with the result you get from evaluating the Perl code. The Perl code can be anything which can be used as an argument to a Perl eval statement. (See \*(L"(Safe\-)Namespaces and opcode restrictions\*(R" below for restrictions.) Examples: .PP .Vb 2 \& [+ $a +] Replaces the [+ $a +] with the content of \& the variable $a \& \& [+ $a+1 +] (Any expression can be used) \& \& [+ $x[$i] +] (Arrays, hashes, and more complex \& expressions work) .Ve .PP \&\f(CW\*(C`NOTE:\*(C'\fR Whitespace is ignored. The output will be automatically HTML-escaped (e.g., `<' is translated to `<') depending on the value of the variables \f(CW$escmode\fR. You do not have to worry about it. .SS "[\- Perl code \-]" .IX Subsection "[- Perl code -]" Executes the Perl code, but deletes the whole command from the \s-1HTML\s0 output. .PP Examples: .PP .Vb 2 \& [\- $a=1 \-] Set the variable $a to one. \& No output will be generated. \& \& [\- use SomeModule ; \-] You can use other modules. NOTE the semicolon! \& \& [\- $i=0; while ($i<5) {$i++} \-] Even more complex \& statements or multiple \& statements are possible. .Ve .PP \&\f(CW\*(C`NOTE:\*(C'\fR Statements like if, while, for, etc., must be contained in a single Embperl command. You cannot have the if in one command block and the terminating `}' or else in another. .PP \&\f(CW\*(C`NOTE:\*(C'\fR To define subroutines, use \*(L"[! Perl Code !]\*(R" (see below) instead of [\- ... \-] to avoid recompilation of the subroutine on every request. .SS "[! Perl Code !]" .IX Subsection "[! Perl Code !]" Same as [\- Perl Code \-] with the exception that the code is only executed at the first request. This could be used to define subroutines, or do one-time initialization. .SS "[* Perl code *]" .IX Subsection "[* Perl code *]" (only version 1.2b2 or higher) \fB\s-1EXPERIMENTAL\s0!\fR .PP This is similar to [\- Perl Code \-]. The main difference is, while [\- Perl Code \-] always has its own scope, all [* Perl code *] blocks runs in the same scope. This allows you to define \*(L"local\*(R" variables with a scope of the whole page. Normally, you don't need to use local, because Embperl takes care of separate namespaces of different documents and cleanup after the request is finished, but in special cases it's necessary. For example, if you want to recursively call an Embperl document via Execute. .PP There is a second reason to use the [* Perl code *] instead of the [\- Perl Code \-]. If you like to use perl's control structures. Perl's if, while, for etc. can \fBnot\fR span multiple [\- Perl Code \-] blocks, but it can span multiple [* Perl Code *]. .PP .Vb 1 \& Example: \& \& [* foreach $i (1..10) { *] \& \& [\- $a = $i + 5 \-] \& loop count + 5 = [+ $a +]
\& \& [* } *] \& \& The following B work: \& \& [\- foreach $i (1..10) { \-] \& some text here
\& [\- } \-] .Ve .PP The same can be done with Embperl meta commands (see below) .PP .Vb 1 \& [$ foreach $i (1..10) $] \& \& [\- $a = $i + 5 \-] \& loop count + 5 = [+ $a +]
\& \& [$ endforeach $] .Ve .PP \&\fB\s-1NOTE 1:\s0\fR [* ... *] blocks _must_ always end with a \fB;\fR,\fB{\fR or \fB}\fR .PP \&\fB\s-1NOTE 2:\s0\fR [* ... *] cannot apear inside a html tag that is interpreted by Embperl (unless you disable the interpretation of such tags like table, input etc.) .PP \&\fB\s-1NOTE 3:\s0\fR There are still benefits of using [\- ... \-] and metacommands: \- much better debugging in the log file. \- no restriction on where they can be used. You can use them anywhere; even inside html tags that are interpreted by Embperl. .SS "[# Some Text #] (Comments)" .IX Subsection "[# Some Text #] (Comments)" (only version 1.2b2 or higher) .PP This is a comment block. Everything between the [# and the #] will be removed from the output. .PP \&\fB\s-1NOTE 1:\s0\fR The [* ... *] blocks are interpreted before the comment block, so they are executed also inside a comment. .PP \&\fB\s-1NOTE 2:\s0\fR Everything (except [* ... *]) is really removed from the source, so you can also use the [# ... #] block to take a part out of your document. .SS "[= =] (Internationalisation)" .IX Subsection "[= =] (Internationalisation)" Defines a string which should be translated into a local language. See Internationalisation (I18N) for details. .SS "[$ Cmd Arg $] (Meta-Commands)" .IX Subsection "[$ Cmd Arg $] (Meta-Commands)" Execute an Embperl metacommand. \fBCmd\fR can be one of the following. (\fBArg\fR varies depending on ). .IP "\fBif\fR, \fBelsif\fR, \fBelse\fR, \fBendif\fR" 4 .IX Item "if, elsif, else, endif" Everything following the \fBif\fR metacommand until the \fBelse\fR, \&\fBelsif\fR, or \fBendif\fR is only output if the Perl expression given in \&\fBArg\fR is true. \fBelse\fR and \fBelsif\fR work similarly. .Sp Example: .Sp .Vb 5 \& [$ if $ENV{REQUEST_METHOD} eq \*(AqGET\*(Aq $] \& Method was GET
\& [$ else $] \& Method other than GET used
\& [$ endif $] .Ve .Sp This will send one of the two sentences to the client, depending on the request method used to retrieve the document. .IP "\fBwhile\fR, \fBendwhile\fR" 4 .IX Item "while, endwhile" Executes a loop until the \fBArg\fR given to \fBwhile\fR is false. .Sp Example: (see eg/x/loop.htm) .Sp .Vb 5 \& [\- $i = 0; @k = keys %ENV \-] \& [$ while ($i < $#k) $] \& [+ $k[$i] +] = [+ $ENV{$k[$i]} +]
\& [\- $i++ \-] \& [$ endwhile $] .Ve .Sp This will send a list of all environment variables to the client. .IP "\fBdo\fR, \fBuntil\fR" 4 .IX Item "do, until" Executes a loop until the \fBArg\fR given to \fBuntil\fR is true. .Sp .Vb 1 \& Example: \& \& [\- $i = 0 \-] \& [$ do $] \& [+ $i++ +]
\& [$ until $i > 10 $] .Ve .IP "\fBforeach\fR, \fBendforeach\fR" 4 .IX Item "foreach, endforeach" Executes a loop for each element of the second \fBArg\fR, setting the first \fBArg\fR accordingly. .Sp .Vb 1 \& Example: \& \& [\- @arr = (1, 3, 5) \-] \& [$ foreach $v (@arr) $] \& [+ $v +]
\& [$ endforeach $] .Ve .IP "\fBnext\fR" 4 .IX Item "next" Inside of looks same as Perl next statement. You could also use the following syntax, which allows you to add an additional condition (or any other Perl code): .Sp .Vb 1 \& [* next if ($foo) *] .Ve .IP "\fBlast\fR" 4 .IX Item "last" Inside of looks same as Perl last statement. You could also use the following syntax, which allows you to add an additional condition (or any other Perl code): .Sp .Vb 1 \& [* last if ($foo) *] .Ve .IP "\fBredo\fR" 4 .IX Item "redo" Inside of looks same as Perl redo statement. You could also use the following syntax, which allows you to add an additional condition (or any other Perl code): .Sp .Vb 1 \& [* redo if ($foo) *] .Ve .IP "\fBhidden\fR" 4 .IX Item "hidden" \&\fBArg\fR consists of zero, one or two names of hashes (with or without the leading %) and an optional array as third parameter. The \&\fBhidden\fR metacommand will generate hidden fields for all data contained in the first hash but not in the second hash. The default used for the first hash is \f(CW%fdat\fR, \f(CW%idat\fR is used for the second. .Sp If the third parameter is specified, the fields are written in the order they appear in this array. That is, all keys of the first hash must be properly sorted in this array. This is intended for situations where you want to pass data from one form to the next, for example, two forms which should be filled in one after the other. (Examples might be an input form and a second form to review and accept the input, or a Windows-style \*(L"wizard\*(R"). Here you can pass along data from previous forms in hidden fields. (See eg/x/neu.htm for an example.) If you use just the 'hidden' command without parameters, it simply generates hidden fields for all form fields submitted to this document which aren't already contained in another input field. .Sp Example: .Sp .Vb 4 \&
\& \& [$ hidden $] \&
.Ve .Sp If you request this with .Sp .Vb 1 \& http://host/doc.htm?field1=A&field2=B&field3=C .Ve .Sp the output will be .Sp .Vb 2 \&
\& \& \& \& \&
.Ve .Sp \&\f(CW\*(C`NOTE:\*(C'\fR This should only be used for a small amount of data, since the hidden fields are sent to the browser, which sends it back with the next request. If you have a large amount of data, store it in a file with a unique name and send only the filename in a hidden field. Be aware of the fact that the data can be changed by the browser if the user doesn't behave exactly as you expect. Users have a nasty habit of doing this all of the time. Your program should be able to handle such situations properly. .IP "\fBvar\fR" 4 .IX Item "var" The var command declares one or more variables for use within this Embperl document and sets the \fBstrict\fR pragma. The variable names must be supplied as a space-separated list. .Sp Example: .Sp .Vb 1 \& [$var $a %b @c $] .Ve .Sp This is the same as writing the following in normal Perl code: .Sp .Vb 2 \& use strict ; \& use vars qw($a %b @c) ; .Ve .Sp \&\s-1NOTE 1:\s0 `use strict' within an Embperl document will only apply to the block in which it occurs. .IP "\fBsub\fR" 4 .IX Item "sub" (Only Embperl 1.2b5 and above) .Sp Defines a Embperl subroutine. Example: .Sp .Vb 3 \& [$ sub foo $] \&

Here we do something

\& [$ endsub $] .Ve .Sp You can call this subroutine either as a normal Perl subroutine .Sp .Vb 1 \& [\- foo \-] .Ve .Sp or via the Embperl::Execute function. .Sp .Vb 2 \& [\- Execute (\*(Aq#foo\*(Aq) # short form \-] \& [\- Execute ({ sub => \*(Aqfoo\*(Aq}) # long form \-] .Ve .Sp The difference is that the Execute function will reset the internal states of Embperl like they were before the subrountine call, when the subroutine returns. .Sp You may also pass Parameters to the subroutine: .Sp .Vb 4 \& [$ sub foo $] \& [\- $p = shift \-] \&

Here we show the first parameter [+ $p +]

\& [$ endsub $] \& \& \& [\- foo (\*(Aqvalue\*(Aq) \-] .Ve .Sp In Embperl 2.0.2 and up you can use a shortcut syntax for passing parameters: .Sp .Vb 3 \& [$ sub foo ($p) $] \&

Here we show the first parameter [+ $p +]

\& [$ endsub $] .Ve .Sp This behaves the same as the example above, but in addition the parameters defined in this way are lexcialy scoped and therefore only available inside the subroutine. .Sp In addtion you can define some initial Perl code for the subroutine: .Sp .Vb 5 \& [$ sub foo ($a, $b) \& my $c = $a + $b ; \& $] \&

The result is [+ $c +]

\& [$ endsub $] .Ve .Sp If you have a couple of commonly used subroutines you can define then in one file and import them into the modules where they are necessary: .Sp .Vb 1 \& [\- Execute ({ inputfile => \*(Aqmylib.htm\*(Aq, import => 1 }) \-] .Ve .Sp This will import all subroutines from the file \fImylib.htm\fR into the current page where they could call just as a normal Perl subroutine. .IP "\fBdump\fR" 4 .IX Item "dump" Embperl 2.1.1 and above. .Sp \&\f(CW\*(C`dump\*(C'\fR can be used to output the values of variables either to the output or to logfiles. The first parameter specifies the output channel: .RS 4 .IP "out" 4 .IX Item "out" Output to the page output .IP "pre" 4 .IX Item "pre" Same as \f(CW\*(C`out\*(C'\fR, but surrounded with a
 tag. This is the default, if
the output parameter is omitted.
.IP "log" 4
.IX Item "log"
Output to embperl log file
.IP "err" 4
.IX Item "err"
Output to stderr, which normally goes to the httpd error log.
.RE
.RS 4
.Sp
If the output parameter is omitted, \f(CW\*(C`pre\*(C'\fR is assumed.
.Sp
The following parameter can be a literal text (in quotes) or a list
of variables.
.Sp
Example:
.Sp
.Vb 1
\&  [$ dump err \*(Aqdump test\*(Aq, %fdat $]
\&
\&  [$ dump %fdat, $i, @array $]
.Ve
.RE
.SS "\s-1HTML\s0 Tags"
.IX Subsection "HTML Tags"
Embperl recognizes the following \s-1HTML\s0 tags in a special way.  All others are
simply passed through, as long as they are not part of a Embperl
command.
.IP "\fB\s-1TABLE\s0\fR, \fB/TABLE\fR, \fB\s-1TR\s0\fR, \fB/TR\fR" 4
.IX Item "TABLE, /TABLE, TR, /TR"
Embperl can generate dynamic tables (one\- or two-dimensional).  You
only need to specify one row or column.
.Sp
Embperl generates as many rows or columns as necessary. This is done
by using the magic variables \f(CW$row\fR, \f(CW$col\fR, and \f(CW$cnt\fR.  If you don't use
\&\f(CW$row\fR/$col/$cnt within a table, Embperl does nothing and simply passes
the table through.
.Sp
Embperl checks if any of \f(CW$row\fR, \f(CW$col\fR, or \f(CW$cnt\fR is used.  Embperl repeats
all text between  and 
, as long as the expressions in which \f(CW$row\fR or \f(CW$cnt\fR occurs are defined. .Sp Embperl repeats all text between and , as long as the expressions in which \f(CW$col\fR or \f(CW$cnt\fR occurs are defined. .Sp See also \*(L"$tabmode\*(R" (below) for end-of-table criteria. .Sp Examples: (see eg/x/table.htm for more examples) .Sp .Vb 8 \& [\- @k = keys %ENV \-] \& \& \& \& \& \& \&
[+ $i=$row +][+ $k[$row] +][+ $ENV{$k[$i]} +]
.Ve .Sp This will show all entries in array \f(CW@k\fR (which contains the keys from \&\f(CW%ENV\fR), so the whole environment is displayed (as in the \fBwhile\fR example), with the first column containing the zero-based index, the second containing the content of the variable name, and the third the environment variable's value. .Sp This could be used to display the result of a database query if you have the result in an array. You may provide as many columns as you need. It is also possible to call a 'fetch' subroutine in each table row. .IP "\fB\s-1DIR\s0\fR, \fB\s-1MENU\s0\fR, \fB\s-1OL\s0\fR, \fB\s-1UL\s0\fR, \fB\s-1DL\s0\fR, \fB\s-1SELECT\s0\fR, \fB/DIR\fR, \fB/MENU\fR, \fB/OL\fR, \fB/UL\fR, \fB/DL\fR, \fB/SELECT\fR" 4 .IX Item "DIR, MENU, OL, UL, DL, SELECT, /DIR, /MENU, /OL, /UL, /DL, /SELECT" Lists and dropdowns or list boxes are treated exactly as one\- dimensional tables. Only \*(L"$row\*(R", \*(L"$maxrow\*(R", \*(L"$col\*(R", \*(L"$maxcol\*(R" and \*(L"$tabmode\*(R" are honored. \f(CW$col\fR and \f(CW$maxcol\fR are ignored. See eg/x/lists.htm for an example. .IP "\fB\s-1OPTION\s0\fR" 4 .IX Item "OPTION" Embperl checks if there is a value from the form data for a specific option in a menu. If so, this option will be pre-selected. .Sp Example: .Sp <\s-1FORM\s0 METHOD=\*(L"\s-1POST\*(R"\s0>

Select Tag

.Sp .Vb 3 \& If you request this document with list.htm?SEL1=x \& you can specify that the element which has a value \& of x is initially selected \& \&

\& .Ve .IP "\fB\s-1INPUT\s0\fR" 4 .IX Item "INPUT" The \s-1INPUT\s0 tag interacts with the hashes \f(CW%idat\fR and \f(CW%fdat\fR. If the input tag has no value and a key exists with the same text as the \&\s-1NAME\s0 attribute of the input tag, Embperl will generate a \s-1VALUE\s0 attribute with the corresponding value of the hash key. All values of <\s-1INPUT\s0> tags are stored in the hash \f(CW%idat\fR, with \s-1NAME\s0 as the hash key and \s-1VALUE\s0 as the hash value. Special processing is done for TYPE=RADIO and TYPE=CHECKBOX. If the \s-1VALUE\s0 attribute contains the same text as the value of the hash the \s-1CHECKED\s0 attribute is inserted, else it is removed. .Sp So, if you specify, as the \s-1ACTION URL,\s0 the file which contains the form itself, the form will be redisplayed with same values as entered the first time. (See eg/x/neu.htm for an example.) .IP "\fB\s-1TEXTAREA\s0\fR, \fB/TEXTAREA\fR" 4 .IX Item "TEXTAREA, /TEXTAREA" The \f(CW\*(C`TEXTAREA\*(C'\fR tag is treated exactly like other input fields. .IP "\fB\s-1META\s0 HTTP\-EQUIV=\fR" 4 .IX Item "META HTTP-EQUIV=" 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. .Sp This can also be used to set http headers. When running under mod_perl http-headers can also be set by the function \fBheader_out\fR .Sp .Vb 1 \& Example of how to set a http header: \& \& \& \& This is the same as using the Apache function \& \& [\- $req_rec \-> header_out("Language" => "DE"); \-] .Ve .IP "\fBA\fR, \fB\s-1EMBED\s0\fR, \fB\s-1IMG\s0\fR, \fB\s-1IFRAME\s0\fR, \fB\s-1FRAME\s0\fR, \fB\s-1LAYER\s0\fR" 4 .IX Item "A, EMBED, IMG, IFRAME, FRAME, LAYER" The output of perl blocks inside the \f(CW\*(C`HREF\*(C'\fR attribute of the \f(CW\*(C`A\*(C'\fR Tags and the \&\f(CW\*(C`SRC\*(C'\fR attribute of the other Tags are \s-1URL\s0 escaped instead of \s-1HTML\s0 escaped. (see also \f(CW$escmode\fR). Also, when inside such a \s-1URL,\s0 \fIEmbperl\fR expands array and hash references to \s-1URL\s0 parameter syntax. Example: .Sp .Vb 4 \& [\- \& $A = { A => 1, B => 2 } ; # Hashreference \& @A = (X, 9, Y, 8, Z, 7) \& \-] \& \& \& .Ve .Sp is expanded by \fIEmbperl\fR to .Sp .Vb 2 \& \& .Ve .SH "Variable scope and cleanup" .IX Header "Variable scope and cleanup" The scope of a variable declared with \fBmy\fR or \fBlocal\fR ends at the end of the enclosing [+/\- ... \-/+] block; the [+/\- ... \-/+] blocks act much like Perl's { ... } in that regard. .PP Global variables (everything not declared with \fBmy\fR or \fBlocal\fR) 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 \fB\s-1EMBPERL_PACKAGE\s0\fR. (See also \&\*(L"(Safe\-)Namespaces and opcode restrictions\*(R".) .PP Since a \s-1CGI\s0 script is always a process of its own, you don't need to worry about that when you use Embperl as a \s-1CGI\s0 script. .PP If you need to declare variables which need to live longer than just one \&\s-1HTTP\s0 request (for example, a database handle), you must either put it's name in the hash \f(CW%CLEANUP\fR or declare them in another package (i.e., \f(CW$Persistent::handle\fR instead of \f(CW$handle\fR). .PP If you want to use the strict pragma, you can do this by using the \fBvar\fR metacommand to declare your variables. .PP \&\f(CW\*(C`NOTE:\*(C'\fR Bacause Apache::DBI has its own namespace, this module will work together with Embperl to maintain your persistent database connection. .PP You can disable the automatic cleanup of global variables with \&\fB\s-1EMBPERL_OPTIONS\s0\fR or the \fBcleanup\fR parameter of the \fBExecute\fR function. .PP You can define exceptions to the cleanup rule with the hash \fB\f(CB%CLEANUP\fB\fR. .PP If you like to do your own cleanup you can define a subroutine \fB\s-1CLEANUP\s0\fR in your document. This will be called right before the variables are cleaned up, but after the connection to the client is closed. .PP .Vb 1 \& EXAMPLE: \& \& [! sub CLEANUP { close FH ; } !] .Ve .SH "Predefined variables" .IX Header "Predefined variables" Embperl has some special variables which have a predefined meaning. .ie n .SS "%ENV" .el .SS "\f(CW%ENV\fP" .IX Subsection "%ENV" Contains the environment as seen from a \s-1CGI\s0 script. .ie n .SS "$epreq" .el .SS "\f(CW$epreq\fP" .IX Subsection "$epreq" Contains a reference to the Embperl request object. This is the same as adding \f(CW\*(C`$epreq = shift\*(C'\fR at the top of each page. .ie n .SS "$epapp" .el .SS "\f(CW$epapp\fP" .IX Subsection "$epapp" Contains a reference to the Embperl application object. This is the same as \f(CW\*(C`$epreq \-\*(C'\fR app> would return. .ie n .SS "%fdat" .el .SS "\f(CW%fdat\fP" .IX Subsection "%fdat" Contains all the form data sent to the script by the calling form. The \s-1NAME\s0 attribute builds the key and the \s-1VALUE\s0 attribute is used as the hash value. Embperl doesn't care if it is called with the \s-1GET\s0 or \&\s-1POST\s0 method, but there may be restrictions on the length of parameters using \s-1GET\s0 \*(-- not from Embperl, but perhaps from the web server, especially if you're using Embperl's \s-1CGI\s0 mode \*(-- it is safer to use \&\s-1POST.\s0 .PP If multiple fields with the same name are sent to a Embperl page, they will put in the same hash element and separated be tabs. You can split it up in an array, by writing: .PP .Vb 1 \& @array = split (/\et/, $fdat{\*(Aqfieldname\*(Aq}) ; .Ve .PP Embperl also supports \s-1ENCTYPE\s0 multipart/form\-data, which is used for file uploads. The entry in \f(CW%fdat\fR corresponding to the file field will be a filehandle, as with \s-1CGI\s0.pm. (Embperl uses \s-1CGI\s0.pm internally to process forms encoded with multipart/form\-data.) .PP File upload example: .PP .Vb 1 \& HTML page: \& \&
\& \&
\& \& Embperl ACTION: \& \& [\- if (defined $fdat{ImageName}) { \& open FILE, "> /tmp/file.$$"; \& print FILE $buffer \& while read($fdat{ImageName}, $buffer, 32768); \& close FILE; \& } \& \-] .Ve .PP When you have installed \s-1CGI\s0.pm 2.46 or above, you may also retrieve the filename (local filename, as it was on the browser side) and the information provided by the \s-1CGI\s0.pm uploadInfo function. To get the filename, simply print out the value of the corresponding \f(CW%fdat\fR entry, instead of using it as a filehandle. To get the \fBuploadInfo\fR use the fieldname with a dash in front of it: .PP .Vb 1 \& Example: \& \& # ImageName is the NAME of the field, you must replace it with whatever \& # name is given in your HTML code \& Filename: [+ $fdat{ImageName} +]
\& Content\-Type: [+ $fdat{\-ImageName} \-> {\*(AqContent\-Type\*(Aq} +]
.Ve .PP \&\fB\s-1NOTE:\s0\fR The way \fBuploadInfos\fR are accessed before 1.2b11 is not supported anymore. .PP \&\fB\s-1NOTE:\s0\fR This works the other way as well: any input fields with names that are \&\f(CW%fdat\fR keys, and without values, will have their values automatically set to the appropriate \f(CW%fdat\fR value. See \*(L"\s-1HTML\s0 Tags\*(R" \f(CW\*(C`INPUT/OPTION/TEXTAREA\*(C'\fR. .ie n .SS "@ffld" .el .SS "\f(CW@ffld\fP" .IX Subsection "@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. .ie n .SS "%idat" .el .SS "\f(CW%idat\fP" .IX Subsection "%idat" Contains all the values from all input tags processed so far. .ie n .SS "%udat (only 1.2b1 or higher)" .el .SS "\f(CW%udat\fP (only 1.2b1 or higher)" .IX Subsection "%udat (only 1.2b1 or higher)" You can use \fB\f(CB%udat\fB\fR to store per user data. As long as you don't use \f(CW%udat\fR, nothing happens, but as soon as you write anything to \f(CW%udat\fR, Embperl creates a session id and sends it via a cookie to the browser. The data you have written to \f(CW%udat\fR 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 fills the \f(CW%udat\fR hash from Apache::Session with the same values as you have stored for that user. (See also \*(L"Session handling\*(R") .ie n .SS "%mdat (only 1.2b2 or higher)" .el .SS "\f(CW%mdat\fP (only 1.2b2 or higher)" .IX Subsection "%mdat (only 1.2b2 or higher)" You can use \fB\f(CB%mdat\fB\fR to store per module/page data. As long as you don't use \f(CW%mdat\fR, nothing happens, but as soon as you write anything to \f(CW%mdat\fR, Embperl creates a session id and stores the data via Apache::Session. The next time any user hits the same Embperl page, Embperl fill the \f(CW%mdat\fR hash from Apache::Session with the same values as you have stored within the last request to that page. (See also \*(L"Session handling\*(R") .ie n .SS "$row, $col" .el .SS "\f(CW$row\fP, \f(CW$col\fP" .IX Subsection "$row, $col" Row and column counts for use in dynamic tables. (See \*(L"\s-1HTML\s0 tag table\*(R".) .ie n .SS "$maxrow, $maxcol" .el .SS "\f(CW$maxrow\fP, \f(CW$maxcol\fP" .IX Subsection "$maxrow, $maxcol" Maximum number of rows or columns to display in a table. To prevent endless loops, \f(CW$maxrow\fR defaults to 100 and \f(CW$maxcol\fR to 10. (See \*(L"\s-1HTML\s0 tag table\*(R".) .ie n .SS "$cnt" .el .SS "\f(CW$cnt\fP" .IX Subsection "$cnt" Contains the number of table cells displayed so far. (See \*(L"\s-1HTML\s0 tag table\*(R".) .ie n .SS "$tabmode" .el .SS "\f(CW$tabmode\fP" .IX Subsection "$tabmode" Determines how the end of a dynamic table is detected. Tables are always limited to the size specified in \f(CW$maxrow\fR and \f(CW$maxcol\fR, but can be ended early when the row ($row) and column ($col) variables become undefined. \f(CW$tabmode\fR operates as follows: .IP "\fB\f(CB$tabmode\fB = 1\fR" 4 .IX Item "$tabmode = 1" End table looping when any one of the expressions in the table row using \f(CW$row\fR returns undefined. The row containing the undefined expression is \fBnot\fR displayed. Only those expressions are observed which contain an access to the variable \f(CW$row\fR. .IP "\fB\f(CB$tabmode\fB = 2\fR" 4 .IX Item "$tabmode = 2" End when an expression with \f(CW$row\fR becomes undefined. The row containing the undefined expression \fBis\fR displayed. .IP "\fB\f(CB$tabmode\fB = 4\fR" 4 .IX Item "$tabmode = 4" End when \f(CW$maxrow\fR rows have been displayed. .PP \&\fBend of row\fR .IP "\fB\f(CB$tabmode\fB = 16\fR" 4 .IX Item "$tabmode = 16" End table column looping when any one of the expressions in the table column using \f(CW$col\fR returns undefined. The column containing the undefined expression is \fBnot\fR displayed. Only those expressions are observed which contain an access to the variable \f(CW$col\fR. .IP "\fB\f(CB$tabmode\fB = 32\fR" 4 .IX Item "$tabmode = 32" End when an expression with \f(CW$col\fR becomes undefined. The column containing the undefined expression \fBis\fR displayed. .IP "\fB\f(CB$tabmode\fB = 64\fR" 4 .IX Item "$tabmode = 64" End when \f(CW$maxcol\fR columns have been displayed. .PP The default is \fB17\fR, which is correct for all sort of arrays. You should rarely need to change it. The two values can be added together. .ie n .SS "$escmode" .el .SS "\f(CW$escmode\fP" .IX Subsection "$escmode" Turn \s-1HTML\s0 and \s-1URL\s0 escaping on and off. The default is on ($escmode = 3). .PP \&\fB\s-1NOTE:\s0\fR Normally you can disable escaping by preceding the item that normally is escaped with a backslash. While this is a handy thing, it could be very dangerous in situations, where content that is inserted by some user is redisplayed, because they can enter arbitrary \s-1HTML\s0 and precede them with a backslash to avoid correct escaping when their input is redisplayed again. To avoid this problem, add 4 to the values below. This will cause Embperl to ignore the backslash when it does output escaping at all. (only 1.3b4 and above) .PP \&\fB\s-1NOTE 2:\s0\fR If you want to output binary data, you must set the escmode to zero. (only 1.3b6 and above) .IP "\fB\f(CB$escmode\fB = 8 (or 15)\fR (2.0b4 and above)" 4 .IX Item "$escmode = 8 (or 15) (2.0b4 and above)" The result of a Perl expression is always XML-escaped (e.g., `>' becomes `>' and ' become '). .IP "\fB\f(CB$escmode\fB = 3 (or 7)\fR" 4 .IX Item "$escmode = 3 (or 7)" The result of a Perl expression is HTML-escaped (e.g., `>' becomes `>') in normal text and URL-escaped (e.g., `&' becomes `%26') within of \f(CW\*(C`A\*(C'\fR, \f(CW\*(C`EMBED\*(C'\fR, \f(CW\*(C`IMG\*(C'\fR, \f(CW\*(C`IFRAME\*(C'\fR, \f(CW\*(C`FRAME\*(C'\fR and \f(CW\*(C`LAYER\*(C'\fR tags. .IP "\fB\f(CB$escmode\fB = 2 (or 6)\fR" 4 .IX Item "$escmode = 2 (or 6)" The result of a Perl expression is always URL-escaped (e.g., `&' becomes `%26'). .IP "\fB\f(CB$escmode\fB = 1 (or 5)\fR" 4 .IX Item "$escmode = 1 (or 5)" The result of a Perl expression is always HTML-escaped (e.g., `>' becomes `>'). .IP "\fB\f(CB$escmode\fB = 0\fR" 4 .IX Item "$escmode = 0" No escaping takes place. .PP \&\fB\s-1SEE ALSO:\s0\fR Configuration directive \s-1EMBPERL_INPUT_ESCMODE\s0 (was optRawInput in Embperl 1.3.x) .ie n .SS "$req_rec" .el .SS "\f(CW$req_rec\fP" .IX Subsection "$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 \s-1API.\s0 See \fBperldoc Apache2::RequestRec\fR for more information. .SS "\s-1LOG\s0" .IX Subsection "LOG" This is the filehandle of the Embperl logfile. By writing `print \s-1LOG\s0 \&\*(L"something\*(R"' you can add lines to the logfile. \s-1NOTE:\s0 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. .PP Example: print \s-1LOG\s0 \*(L"[$$]ABCD: your text\en\*(R" ; .PP If you are writing a module for use under Embperl you can say .PP .Vb 1 \& tie *LOG, \*(AqEmbperl::Log\*(Aq; .Ve .PP to get a handle by which you can write to the Embperl logfile. .SS "\s-1OUT\s0" .IX Subsection "OUT" This filehandle is tied to Embperl's output stream. Printing to it has the same effect as using the [+ ... +] block. (See also optRedirectStdout) .ie n .SS "@param" .el .SS "\f(CW@param\fP" .IX Subsection "@param" Will be setup by the \fB'param'\fR parameter of the \fBExecute\fR function. Could be used to pass parameters to an Embperl document and back. (see Execute for further docs) .ie n .SS "%http_headers_out (only 1.2b10 and above)" .el .SS "\f(CW%http_headers_out\fP (only 1.2b10 and above)" .IX Subsection "%http_headers_out (only 1.2b10 and above)" You can put any http headers you want to send into this hash. .PP If you set a location header, Embperl will automatically set the status to 301 (Redirect). Example: .PP .Vb 1 \& [\- $http_headers_out{\*(AqLocation\*(Aq} = "http://www.ecos.de/embperl/" \-] .Ve .PP however, it is possible to specify a two element array for Location, the second element of which gives the desired \s-1HTTP\s0 status: .PP .Vb 1 \& [\- $http_headers_out{Location} = [ "http://www.ecos.de/embperl/", 303 ]; \-] .Ve .PP Starting with version 1.3.2 all headers with the exception of \&\*(L"Content-Type\*(R" can take multiple values. For instance, if you wanted to set two cookies, you can proceed as follows: .PP .Vb 2 \& [\- $http_headers_out{\*(AqSet\-Cookie\*(Aq} = \& [\*(Aqname=cook1;value=2;\*(Aq,\*(Aqname=cook2;value=b\*(Aq] ; \-] .Ve .PP If you supply multiple values for \*(L"Location\*(R" or \*(L"Content-Type\*(R" via an array reference, then Embperl will simply use the first in the list. Empty arrays will be ignored. For instance, the following will neither change the status to 301 nor create a Location: line in the \s-1HTTP\s0 headers: .PP .Vb 1 \& [\- $http_headers_out{\*(AqLocation\*(Aq} = [] ; \-] .Ve .PP see also \s-1META\s0 HTTP\-EQUIV= .ie n .SS "$optXXX $dbgXXX" .el .SS "\f(CW$optXXX\fP \f(CW$dbgXXX\fP" .IX Subsection "$optXXX $dbgXXX" All options (see \*(L"\s-1EMBPERL_OPTIONS\*(R"\s0) and all debugging flags (see \*(L"\s-1EMBPERL_DEBUG\*(R"\s0) can be read and most of them can be set by the corresponding variables. See \*(L"perldoc Config\*(R". .PP .Vb 1 \& Example: \& \& [\- $dbgInput = 1 \-] \& \& \& [\- $dbgInput = 0 \-] \& \& \& [+ $dbgCmd +] # Output the state of the dbgCmd flag .Ve .ie n .SS "%CLEANUP" .el .SS "\f(CW%CLEANUP\fP" .IX Subsection "%CLEANUP" Embperl cleanups up only variables with are defined within the Embperl page. If you want Embperl to cleanup additional variables you can add them to the hash \f(CW%CLEANUP\fR, with the key set to the variable name and the value set to one. The other way you could prevent Embperl from cleaning up some variables, is by adding them to this hash, with values of zero. .ie n .SS "%CLEANUPFILE (1.2b6+)" .el .SS "\f(CW%CLEANUPFILE\fP (1.2b6+)" .IX Subsection "%CLEANUPFILE (1.2b6+)" Same purpose as \f(CW%CLEANUP\fR, but you may add filenames. All variables defined inside that file will be cleaned up. .SH "Session handling" .IX Header "Session handling" From 1.2b1 and higher Embperl is able to handle per user sessions for you. You can store any data in the \f(CW%udat\fR hash and if the same user requests an Embperl document again, you will see the same values in that hash again. .PP From 1.2b2 and higher Embperl is able to handle per module/page persistent data for you. You can store any data in the \f(CW%mdat\fR hash and if any request comes to the same Embperl document, you will see the same values in that hash again. .PP Session handling has changed from 1.3.3 to 1.3.4 and 2.0b3 to 2.0b4. You must either install Apache::SessionX or set .PP .Vb 1 \& PerlSetEnv EMBPERL_SESSION_HANDLER_CLASS "Embperl::Session" .Ve .PP to get the old behaviour. If you have Apache::SessionX installed, you don't have to make additional configuration, otherwise you must do the following things. You are also able to override the Apache::SessionX defaults, by using the following parameters: .PP To configure \fIEmbperl\fR to do session management for you, you must have installed \fIApache::Session\fR (\fB1.53 or higher\fR) and tell Embperl which storage and locker classes you would like to use for \&\fIApache::Session\fR. This is done by setting the environment variable \&\f(CW\*(C`EMBPERL_SESSION_CLASSES\*(C'\fR. If you want to use a MySQL database for storing your sessions, you may have a \&\fBstartup.pl\fR for your httpd which looks like this: .PP .Vb 5 \& BEGIN \& { \& $ENV{EMBPERL_SESSION_CLASSES} = "MySQL Semaphore" ; \& $ENV{EMBPERL_SESSION_ARGS} = "DataSource=dbi:mysql:session UserName=test" ; \& } ; \& \& use Embperl ; .Ve .PP or you may put this in the httpd/srm.conf: .PP .Vb 3 \& PerlSetEnv EMBPERL_SESSION_CLASSES "MySQL Semaphore" \& PerlSetEnv EMBPERL_SESSION_ARGS "DataSource=dbi:mysql:session UserName=test" \& PerlModule Embperl ; .Ve .PP Refer to the \fIApache::Session\fR docs (e.g. \fIApache::Session::Store::MySQL\fR) on how to setup your database tables. .PP \&\f(CW\*(C`EMBPERL_SESSION_ARGS\*(C'\fR is a space separated list of name/value pairs, which gives additional arguments for Apache::Session classes. .PP Here is an example for using a filesystem based storage: .PP PerlSetEnv \s-1EMBPERL_SESSION_CLASSES\s0 \*(L"File Semaphore\*(R" PerlSetEnv \s-1EMBPERL_SESSION_ARGS\s0 \*(L"Directory=/path/to/your/sessions\*(R" .PP Refer to the \fIApache::Session\fR docs to find out which other storage/locker methods are available. .PP \&\f(CW\*(C`EMBPERL_SESSION_CLASSES\*(C'\fR can (optionally) take two more classnames, which specify the class for serialization (Default: \f(CW\*(C`Storable\*(C'\fR) and for generating the id (Default: \f(CW\*(C`MD5\*(C'\fR). .PP \&\fB\s-1NOTE:\s0\fR The above configuration works only with \fIApache::Session\fR 1.52 and \fIEmbperl\fR 1.3b5 or above. Older versions of Embperl only support \fIApache::Session\fR 1.0x, which has different parameters for \f(CW\*(C`EMBPERL_SESSION_CLASSES\*(C'\fR (e.g. \f(CW\*(C`$ENV{EMBPERL_SESSION_CLASSES} = "DBIStore SysVSemaphoreLocker" ; \*(C'\fR) \&\fIApache::Session\fR 1.0x still works with this Embperl version. .PP Now you are able to use the \f(CW%udat\fR and \f(CW%mdat\fR hashes for your user/module sessions. As long as you don't touch \f(CW%udat\fR or \f(CW%mdat\fR, Embperl will not create any session, and Apache::Session is not loaded. As soon as you store any value to \f(CW%udat\fR, Embperl will create a new session and send a cookie to the browser to maintain its id, while the data is stored by Apache::Session. (Further version may also be able to use \&\s-1URL\s0 rewriting for storing the id). When you modify \f(CW%mdat\fR, Embperl will store the data via Apache::Session and retrieve it when the next request comes to the same page. .SS "Functions/Methods for session handling" .IX Subsection "Functions/Methods for session handling" .ie n .SS "Embperl::Req::SetupSession ($req_rec, $uid, $sid, $app_param) [1.3b6+]" .el .SS "Embperl::Req::SetupSession ($req_rec, \f(CW$uid\fP, \f(CW$sid\fP, \f(CW$app_param\fP) [1.3b6+]" .IX Subsection "Embperl::Req::SetupSession ($req_rec, $uid, $sid, $app_param) [1.3b6+]" This can be used from a script that will later call Embperl::Execute to preset the session so it's available to the calling script. .ie n .IP "$req_rec" 4 .el .IP "\f(CW$req_rec\fR" 4 .IX Item "$req_rec" Apache request record when running under mod_perl, \f(CW\*(C`undef\*(C'\fR otherwise. .ie n .IP "$uid" 4 .el .IP "\f(CW$uid\fR" 4 .IX Item "$uid" Session \s-1ID\s0 of the user session. If not given it is taken from the session cookie or out of the query_string. .ie n .IP "$sid" 4 .el .IP "\f(CW$sid\fR" 4 .IX Item "$sid" Session \s-1ID\s0 of the state session. If not given it is taken out of the query_string. .ie n .IP "$app_param" 4 .el .IP "\f(CW$app_param\fR" 4 .IX Item "$app_param" SetupSession tries to figure out the correct Application object for this request, in case this is not possible you can pass parameters for the Application object as a hash ref. To pass the name of the application object to use, try to pass: .Sp .Vb 1 \& { appname => \*(Aqmyappname\*(Aq } .Ve .PP Returns a reference to \f(CW%udat\fR or, if call in an array context, a reference to \f(CW%udat\fR \&\f(CW%mdat\fR and \f(CW%sdat\fR. See also \f(CW\*(C`CleanupSession\*(C'\fR. .ie n .SS "Embperl::Req::GetSession / $r \-> GetSession [1.3b6+]" .el .SS "Embperl::Req::GetSession / \f(CW$r\fP \-> GetSession [1.3b6+]" .IX Subsection "Embperl::Req::GetSession / $r -> GetSession [1.3b6+]" Returns a reference to \f(CW%udat\fR or, if called in an array context, a reference to \f(CW%udat\fR and \f(CW%mdat\fR. This could be used by modules that are called from inside an Embperl page, where the session management is already setup. If called as a method \f(CW$r\fR must be a Embperl::Req object, which is passed as first parameter to every Embperl page in \f(CW@_\fR . .ie n .SS "Embperl::Req::CleanupSession ($req_rec, $app_param) [1.3b6+]" .el .SS "Embperl::Req::CleanupSession ($req_rec, \f(CW$app_param\fP) [1.3b6+]" .IX Subsection "Embperl::Req::CleanupSession ($req_rec, $app_param) [1.3b6+]" Must be called at the end of a script by scripts that use \f(CW\*(C`SetupSession\*(C'\fR, but do not call Embperl::Execute. .ie n .IP "$req_rec" 4 .el .IP "\f(CW$req_rec\fR" 4 .IX Item "$req_rec" Apache request record when running under mod_perl, \f(CW\*(C`undef\*(C'\fR otherwise. .ie n .IP "$app_param" 4 .el .IP "\f(CW$app_param\fR" 4 .IX Item "$app_param" CleanupSession tries to figure out the correct Application object for this request, in case this is not possible you can pass parameters for the Application object as a hash ref. To pass the name of the application object to use, try to pass: .Sp .Vb 1 \& { appname => \*(Aqmyappname\*(Aq } .Ve .ie n .SS "Embperl::Req::DeleteSession / $r \-> DeleteSession [1.3b6+]" .el .SS "Embperl::Req::DeleteSession / \f(CW$r\fP \-> DeleteSession [1.3b6+]" .IX Subsection "Embperl::Req::DeleteSession / $r -> DeleteSession [1.3b6+]" Deletes the session data and removes the cookie from the browser. If called as a method \f(CW$r\fR must be a Embperl::Req object, which is passed as first parameter to every Embperl page in \f(CW@_\fR . .ie n .SS "Embperl::Req::RefreshSession / $r \-> RefreshSession [1.3b6+]" .el .SS "Embperl::Req::RefreshSession / \f(CW$r\fP \-> RefreshSession [1.3b6+]" .IX Subsection "Embperl::Req::RefreshSession / $r -> RefreshSession [1.3b6+]" Triggers a resend of the cookie. Normally the cookie is only sent the first time. If called as a method \f(CW$r\fR must be a Embperl::Req object, which is passed as first parameter to every Embperl page in \f(CW@_\fR . .ie n .SS "Embperl::Req::SetSessionCookie ($req_rec, $app_param) [1.3b7+]" .el .SS "Embperl::Req::SetSessionCookie ($req_rec, \f(CW$app_param\fP) [1.3b7+]" .IX Subsection "Embperl::Req::SetSessionCookie ($req_rec, $app_param) [1.3b7+]" Must be called by scripts that use \f(CW\*(C`SetupSession\*(C'\fR, but do not call Embperl::Execute. This is necessary to set the cookie for the user session id, in case a new session is created, which is normally done by Embperl::Execute. .PP SetSessionCookie does only set the cookie for the user session and it works only when running under mod_perl. It does \fBnot\fR set session id if no cookies are used. Also it does not care about the state session. .ie n .IP "$req_rec" 4 .el .IP "\f(CW$req_rec\fR" 4 .IX Item "$req_rec" Apache request record when running under mod_perl, \f(CW\*(C`undef\*(C'\fR otherwise. .ie n .IP "$app_param" 4 .el .IP "\f(CW$app_param\fR" 4 .IX Item "$app_param" SetupSessionCookie tries to figure out the correct Application object for this request, in case this is not possible you can pass parameters for the Application object as a hash ref. To pass the name of the application object to use, try to pass: .Sp .Vb 1 \& { appname => \*(Aqmyappname\*(Aq } .Ve .SH "Recipes" .IX Header "Recipes" Starting with 2.0b4 Embperl introduces the concept of recipes. A recipe basically tells Embperl how a component should be build. While before 2.0b4 you could have only one processor that works on the request (the Embperl processor \- you're also able to define different syntaxes), now you can have multiple of them arranged in a pipeline or even a tree. While you are able to give the full recipe when calling Execute, this is not very convenient, so normally you will only give the name of a recipe, either as parameter 'recipe' to Execute or as \s-1EMBPERL_RECIPE\s0 in your httpd.conf. Of course you can have different recipes for different locations and/or files. A recipe is constructed out of providers. A provider can either be read from some source or do some processing on a source. There is no restriction on what sort of data a provider has as in\- and output \- you just have to make sure that output format of a provider matches the input format of the next provider. In the current implementation Embperl comes with a set of built-in providers: .IP "file" 4 .IX Item "file" read file data .IP "memory" 4 .IX Item "memory" get data from a scalar .IP "epparse" 4 .IX Item "epparse" parse file into a Embperl tree structure .IP "epcompile" 4 .IX Item "epcompile" compile Embperl tree structure .IP "eprun" 4 .IX Item "eprun" execute Embperl tree structure .IP "eptostring" 4 .IX Item "eptostring" convert Embperl tree structure to string .IP "libxslt-parse-xml" 4 .IX Item "libxslt-parse-xml" parse xml source for libxslt .IP "libxslt-compile-xsl" 4 .IX Item "libxslt-compile-xsl" parse and compile stylesheet for libxslt .IP "libxslt" 4 .IX Item "libxslt" do an xsl transformation via libxslt .IP "xalan-parse-xml" 4 .IX Item "xalan-parse-xml" parse xml source for xalan .IP "xalan-compile-xsl" 4 .IX Item "xalan-compile-xsl" parse and compile stylesheet for xalan .IP "xalan" 4 .IX Item "xalan" do an xsl transformation via xalan .PP There is a C interface, so new custom providers can be written, but what makes it really useful is that the next release of Embperl will contain a Perl interface, so you can write your own providers in Perl. .PP The default recipe is named Embperl and contains the following providers: .PP .Vb 10 \& +\-\-\-\-\-\-\-\-\-\-\-+ \& + file + \& +\-\-\-\-\-\-\-\-\-\-\-+ \& | \& v \& +\-\-\-\-\-\-\-\-\-\-\-+ \& + epparse + \& +\-\-\-\-\-\-\-\-\-\-\-+ \& | \& v \& +\-\-\-\-\-\-\-\-\-\-\-+ \& + epcompile + \& +\-\-\-\-\-\-\-\-\-\-\-+ \& | \& v \& +\-\-\-\-\-\-\-\-\-\-\-+ \& + eprun + \& +\-\-\-\-\-\-\-\-\-\-\-+ .Ve .PP This cause Embperl to behave like it has done in the past, when no recipes existed. .PP Each intermediate result could be cached. So for example you are able to cache the already parsed \s-1XML\s0 or compiled stylesheet in memory, without the need to reparse/recompile it over and over again. .PP Another nice thing about recipes is that they are not static. A recipe is defined by a recipe object. When a request comes in, Embperl calls the get_recipe method of the application object, which by default calls the get_recipe of the named recipe object, which should return a array that describes what Embperl has to do. The get_recipe methods can of course build the array dynamically, looking, for example, at the request parameters like filename, formvalues, mime type or whatever. For example if you give a scalar as input the Embperl recipe replaces the file provider with a memory provider. Additionally you can specify more then one recipe (separated by spaces). Embperl will call all the new methods in turn until the first one that returns undef. This way you can create recipes that are known for what they are responsible. One possibility would be to check the file extension and only return the recipe if it matches. Much more sophisticated things are possible... .PP See perldoc Embperl::Recipe for how to create your own provider. .SH "XML, XSLT" .IX Header "XML, XSLT" As mentioned above, Embperl now contains a provider for doing \s-1XSLT\s0 transformations. More \s-1XML\s0 will come in the next releases. The easiest thing is to use the \s-1XSLT\s0 stuff thru the predefined recipes: .IP "EmbperlLibXSLT" 4 .IX Item "EmbperlLibXSLT" the result of Embperl will run thru the Gone libxslt .IP "EmbperlXalanXSLT" 4 .IX Item "EmbperlXalanXSLT" the result of Embperl will run thru Xalan-C .IP "EmbperlXSLT" 4 .IX Item "EmbperlXSLT" the result of Embperl will run thru the \s-1XSL\s0 transformer given by xsltproc or \s-1EMBPERL_XSLTPROC\s0 .IP "LibXSLT" 4 .IX Item "LibXSLT" run source thru the Gone libxslt .IP "XalanXSLT" 4 .IX Item "XalanXSLT" run source thru Xalan-C .IP "\s-1XSLT\s0" 4 .IX Item "XSLT" run source thru the \s-1XSL\s0 transformer given by xsltproc or .IP "\s-1EMBPERL_XSLTPROC\s0" 4 .IX Item "EMBPERL_XSLTPROC" .PP For example, including the result of an \s-1XSLT\s0 transformation into your html page could look like this: .PP .Vb 2 \& Include XML via XSLT \& \& \&

Start xml

\& [\- Execute ({inputfile => \*(Aqfoo.xml\*(Aq, recipe => \*(AqEmbperlXalanXSLT\*(Aq, xsltstylesheet => \*(Aqfoo.xsl\*(Aq}) ; \-] \&

END

\& \& \& .Ve .PP As you already guessed, the xsltstylesheet parameter gives the name of the xsl file. You can also use the \s-1EMBPERL_XSLTSTYLESHEET\s0 configuration directive to set it from your configuration file. .PP By setting \s-1EMBPERL_ESCMODE\s0 (or \f(CW$escmode\fR) to 15 you get the correct escaping for \s-1XML.\s0 .SH "Form Validation" .IX Header "Form Validation" Embperl comes with the ability to validate form data. Rules can be defined how the data from forms should be validated. This done by the module Embperl::Form::Validate. This module is able to do client side verification by generation JavaScript code and server side verification by providing a Perl method to validate the data. Embperl::Form::Validate comes with a lot of standard tests and you can extent it by providing your own test classes, which can inherit from the shipped test classes. .PP For further details see perldoc Embperl::Form::Validate. .SH "Caching" .IX Header "Caching" Embperl caches a lot of intermediate results by default to speed up generation of pages. (For example compiled Perl code and compiled \s-1XSLT\s0 templates) .PP With Embperl is also possible to cache the output of pages or components. This is controlled by parameters passed to the providers via recipes or as configuration directives inside the page, passed to Execute or in your httpd.conf. .PP See Emperl_Cache_* and Embperl_Expires_* in Config.pod. .SH "Internationalisation (I18N)" .IX Header "Internationalisation (I18N)" Starting with 2.0b6 Embperl has buildin support for multi-language applications. There are two things to do. First inside your pages marks which parts are translateable, by using the [= =]. Inside the [= =] blocks you could either put id, which are symbolic names for the text, or you put the text in your primary lanaguage inside the blocks. An example code could look like: .PP [= heading =] .PP .PP Now you run the embpmsgid.pl utility, which extracts all the ids from your page: .PP .Vb 1 \& perl embpmsgid.pl \-l de \-l en \-d msg.pl foo.htm .Ve .PP This will create a file msg.pl which contains empty definitions for 'en' and 'de' with all the ids found in the page. If the file msg.pl already exists, the definitions are added. You can give more then one filename to the commandline. The format of the msg.pl file is written with Data::Dumper, so it can be easily read in via 'do' and postprocessed. As next step fill the empty definition with the correct translation. The last thing to do, is tell Embperl which language set to use. You do this inside the init method of the application object. Create an application object, which reads in the message and when the init method is called, pass the correct one to Embperl. There are tow methods \f(CW$r\fR \-> message and \f(CW$r\fR \-> default_message. Both returns a array ref on which you can push your message hashs. Embperl consults first the message array and if not found afterwards the default_message array for the correct message. Because both are arrays you can push multiple message sets on it. This is handy when your application object calls it's base class, which also may define some messages. Starting with version 2.3.0 it is also possible, to add a code ref instead of a hash ref to the arrays. The code is than called with the key as argument and must return the translated text. .PP Here is an example: .PP .Vb 1 \& package My::App ; \& \& @ISA = (\*(AqEmbperl::App\*(Aq) ; \& \& %messages = \& ( \& \*(Aqde\*(Aq => \& { \& \*(Aqheading\*(Aq => \*(Aq\e[:U]berschrift\*(Aq, \& \*(Aqbar\*(Aq => \*(AqAbsenden\*(Aq, \& }, \& \*(Aqen\*(Aq => \& { \& \*(Aqheading\*(Aq => \*(AqHeading\*(Aq, \& \*(Aqbar\*(Aq => \*(AqSubmit\*(Aq, \& }, \& ) ; \& \& sub init \& { \& my $self = shift ; \& my $r = $self \-> curr_req ; \& \& $lang = $r \-> param \-> language || \*(Aqde\*(Aq ; \& push @{$r \-> messages}, $messages{$lang} ; \& push @{$r \-> default_messages}, $messages{\*(Aqen\*(Aq} if ($lang ne \*(Aqen\*(Aq) ; \& } \& \& # Code ref works too... \& @{$r \-> messages} = (\e&ecos::I18L::translate::gettext) ; \& \& # and gettext is defined as \& sub gettext \& { \& my ($key) = @_ ; \& \& return "translated text" ; \& } \& \& \& \& \& 1 ; .Ve .PP Just load this package and set \s-1EMBPERL_APP_HANDLER_CLASS\s0 to My::App, then Embperl will call the init method on the start of the request. .PP If you are using Embperl::Object, you may instead save it as a file in your document hiearchie make the filename know to Embperl::Object with the \&\s-1EMBPERL_OBJECT_APP\s0 directive and Embperl::Object will retrieve the correct application file, just in the same way it retrieves other files. .PP \&\s-1NOTE:\s0 When using with Embperl::Object, don't make a package declaration at the top of your application object, Embperl::Object assign it's own namespace to the application object. .PP In case you need to retrieve a text inside your Perl code, you can do this with \f(CW$r\fR \-> gettext('bar') .SH "Encoding/UTF\-8" .IX Header "Encoding/UTF-8" Requires Embperl 2.1.0 and up. .PP \&\fIEmbperl\fR tries to do the right thing to handle \s-1ISO\-8859\-1\s0 and \s-1UTF\-8\s0 out of the box. There are three places where encoding comes into places: .IP "Posted form data" 4 .IX Item "Posted form data" .PD 0 .IP "Output escaping" 4 .IX Item "Output escaping" .IP "Source code" 4 .IX Item "Source code" .PD .PP While the first two things are handled by Embperl itself, the third item is currently left to handle by Perl. .PP Perl carries for each string value a flag that tells if the string is \s-1UTF\-8\s0 or not. Embperl uses this flag. .PP Posted form data is examined. If a string contains valid \s-1UTF\-8\s0 characters Perl's internal \s-1UTF\-8\s0 flag is set. You can disable setting the \s-1UTF\-8\s0 flag by setting \f(CW\*(C`optFormDataNoUtf8\*(C'\fR in \f(CW\*(C`EMBPERL_OPTIONS\*(C'\fR. .PP Output escaping is done based on the \s-1UTF\-8\s0 flag. In case the \s-1UTF\-8\s0 flags is set characters above 127 are not escaped. To get the correct appearance in your browser you also have to specify the encoding as \s-1UTF\-8\s0 in your content-type http header. .PP If the \s-1UTF\-8\s0 flag is not set the output escaping is done based on the setting of \f(CW\*(C`EMBPERL_OUTPUT_ESC_CHARSET\*(C'\fR, which defaults to \&\s-1ISO\-8859\-1\s0 (latin1). \s-1ISO\-8859\-2\s0 (latin2) is also selectable. .PP If you wish to have your Perl source code in \s-1UTF\-8,\s0 you have to add a \f(CW\*(C`use utf8;\*(C'\fR at the top of each page. .PP Please note that not all modules sets Perl's internal \s-1UTF\-8\s0 flag correctly. At the time of this writing for example \&\s-1DBI\s0 and Net::LDAP does not set this flag. You have to correct it manualy, for example by using \f(CW\*(C`Encode::_utf8_on\*(C'\fR. .SH "Error trapping" .IX Header "Error trapping" When an error occurs inside an Embperl page, Embperl will display an error page, containing the error message. .PP Sometimes you want to have a different behaviour. One possibility is to let Apache display a custom error page (of course only when you run under mod_perl). .PP To get this working you need to set the option \f(CW\*(C`optReturnError\*(C'\fR (262144) in your httpd.conf in the \f(CW\*(C`EMBPERL_OPTIONS\*(C'\fR directive. .PP With this option set, Embperl sends no output in case of an error. It returns the error back to Apache or the calling program. When running under mod_perl this gives you the chance to use the Apache \fIErrorDocument\fR directive to show a custom error-document. Inside the ErrorDocument you can retrieve the error messages with .PP .Vb 1 \& $errors = $req_rec \-> prev \-> pnotes(\*(AqEMBPERL_ERRORS\*(Aq) ; .Ve .PP where \f(CW$errors\fR is a array reference. .PP If you want to trap exceptions in a Embperl document, that you call via Execute, you can do this by passing an array to Execute, which receives all error/warning messages and/or all error objects. .PP .Vb 3 \& [\- \& Execute ({inputfile => \*(Aqfoo.epl\*(Aq, errors => \e@errors}) ; \& \-] \& \& [$if @errors$] \& The following errors had occurred:
\& [$foreach $err (@errors)$] \& [+ $err +]
\& [$endforeach$] \& [$endif$] .Ve .PP In case you call \f(CW\*(C`die\*(C'\fR inside the executed page and pass an object (or a reference) to \f(CW\*(C`die\*(C'\fR instead of a string this will also show up in \f(CW@errors\fR. The last object passed to \f(CW\*(C`die\*(C'\fR is also available via \f(CW\*(C`$epreq \-\*(C'\fR errobj>. .PP \&\f(CW\*(C`$epreq \-\*(C'\fR error> can be used to test if an error occurred so far during the current request. You can also set \f(CW\*(C`$epreq \-\*(C'\fR error> to false to reset Embperl's internal error condition. .PP If the option \f(CW\*(C`optReturnError\*(C'\fR or an error array is passed to a component the error flag is reset after the execution of component. .PP If an error array is passed to a component, the errors inside the component are not added to the overall errors of the request and therefore will not cause Embperl to display an error page. .PP An more seldom used option is \f(CW\*(C`optDisableEmbperlErrorPage\*(C'\fR (2), which tells tells Embperl not to send its own errorpage in case of failure, but instead show as much of the page as possible. Errors are only logged to the log file. .SH "Utility Functions" .IX Header "Utility Functions" .ie n .SS "MailFormTo($MailTo, $Subject, $ReturnField)" .el .SS "MailFormTo($MailTo, \f(CW$Subject\fP, \f(CW$ReturnField\fP)" .IX Subsection "MailFormTo($MailTo, $Subject, $ReturnField)" Sends the content of the hash \f(CW%fdat\fR in the order specified by \f(CW@ffld\fR to the given \fB\f(CB$MailTo\fB\fR addressee, with a subject of \fB\f(CB$Subject\fB\fR. If you specify \f(CW$ReturnField\fR the value of that formfield will be used as \fBReturn-Path\fR. Usually, this will be the field where the user enters his e\-mail address in the form. .PP If you specify the following example code as the action in your form .PP .Vb 2 \&
.Ve .PP The content of the form will be mailed to the given e\-mail address. .PP MailFormTo uses \*(L"\s-1EMBPERL_MAILHOST\*(R"\s0 as \s-1SMTP\s0 server or \fBlocalhost\fR if non given. .PP Example: .PP .Vb 10 \& \& \& Feedback \& \& \& [\- MailFormTo(\*(Aqwebmaster@domain.xy\*(Aq, \& \*(AqMail from WWW Form\*(Aq, \*(Aqemail\*(Aq) \-] \& Your data has been successfully sent! \& \& .Ve .PP This will send an email with all the form fields to webmaster@domain.xy, with the Subject 'Mail from \s-1WWW\s0 Form' and will set the Return-Path of the mail to the address which was entered in the field with the name 'email'. .PP \&\fB\s-1NOTE:\s0\fR You must have Net::SMTP (from the libnet package) installed to use this function. .SS "exit" .IX Subsection "exit" \&\fBexit\fR will override the normal Perl exit in every Embperl document. Calling exit will immediately stop any further processing of that file and send the already-done work to the output/browser. .PP \&\fB\s-1NOTE 1:\s0\fR If you are inside of an Execute, Embperl will only exit this Execute, but the file which called the file containing the exit with Execute will continue. .PP \&\fB\s-1NOTE 2:\s0\fR If you called exit with an argument it exits the whole request e.g. exit (200). .PP \&\fB\s-1NOTE 3:\s0\fR If you write a module which should work with Embperl under mod_perl, you must use Apache::exit instead of the normal Perl exit (as always when running under mod_perl). .SH "Performance" .IX Header "Performance" To get the best performance 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 \fBnever\fR enable \fBdbgFlushOutput\fR or \fBdbgFlushLog\fR 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. .PP Preloading of page can save memory, because preloaded page can be shared between child processes. See \*(L"perldoc Config\*(R" for more details. .PP Also take a look at \fBmod_perl_tuning.pod\fR for general ideas about performance. .SH "Bugs" .IX Header "Bugs" None known. .SH "Compatibility" .IX Header "Compatibility" I have tested Embperl successfully .SS "on Linux 2.x/3.x with" .IX Subsection "on Linux 2.x/3.x with" .IP "perl5.005_03, 5.6.x, 5.8.x, 5.10.x, 5.12.x, 5.14.x, 5.16.x, 5.18.x" 4 .IX Item "perl5.005_03, 5.6.x, 5.8.x, 5.10.x, 5.12.x, 5.14.x, 5.16.x, 5.18.x" .PD 0 .IP "apache_1.3.0 \- apache_1.3.31, apache 2.0.x, apache 2.2.x, apache 2.4.x" 4 .IX Item "apache_1.3.0 - apache_1.3.31, apache 2.0.x, apache 2.2.x, apache 2.4.x" .IP "apache_ssl (Ben \s-1SSL\s0)" 4 .IX Item "apache_ssl (Ben SSL)" .IP "Stronghold 2.2" 4 .IX Item "Stronghold 2.2" .IP "Stronghold 2.4.1" 4 .IX Item "Stronghold 2.4.1" .IP "Apache_1.3.x with mod_ssl 2.x.x" 4 .IX Item "Apache_1.3.x with mod_ssl 2.x.x" .PD .PP I know from other people that it works on many other \s-1UNIX\s0 systems .SS "on Windows \s-1NT 4.0\s0 with" .IX Subsection "on Windows NT 4.0 with" .IP "perl5.004_04" 4 .IX Item "perl5.004_04" .PD 0 .IP "perl5.005" 4 .IX Item "perl5.005" .IP "perl5.6.1" 4 .IX Item "perl5.6.1" .IP "perl5.8.x" 4 .IX Item "perl5.8.x" .IP "apache_1.3.0 \- apache_1.3.31" 4 .IX Item "apache_1.3.0 - apache_1.3.31" .PD .SS "on Windows 95/98 with" .IX Subsection "on Windows 95/98 with" .IP "perl5.004_02 (binary distribution, only Offline Mode)" 4 .IX Item "perl5.004_02 (binary distribution, only Offline Mode)" .PD 0 .IP "perl5.005_02 + apache_1.3.6" 4 .IX Item "perl5.005_02 + apache_1.3.6" .PD .SH "Support" .IX Header "Support" .SS "Feedback and Bug Reports" .IX Subsection "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 Embperl mailing list. If you have a site that is using Embperl, I would love to mention it in list of sites using Embperl. Please drop me a mail with a short description, if your site uses Embperl. .PP The Embperl mailing list (embperl@perl.apache.org) is available for Embperl users and developers to share ideas, solve problems and discuss things related to Embperl To subscribe to this list, send mail to embperl\-subscribe@perl.apache.org. To unsubscribe send email to embperl\-unsubscribe@perl.apache.org . .PP There is an archive for the Embperl mailing list at http://mail\-archives.apache.org/mod_mbox/perl\-embperl .PP For mod_perl related questions you may search the mod_perl mailing list archive at http://mail\-archives.apache.org/mod_mbox/perl\-modperl .SS "Commerical Support" .IX Subsection "Commerical Support" You can get free support on the Embperl mailing list (see above). If you need commercial support, ecos can provide it for you. We offer: .IP "\(bu" 4 Consulting and assistance for you and your programmers .IP "\(bu" 4 Planning of your dynamic website .IP "\(bu" 4 Creating of parts or a whole website .IP "\(bu" 4 Fixing bugs in Embperl (also available for mod_perl) .IP "\(bu" 4 Adding new features .PP You can reach us via http://www.ecos.de or info@ecos.de .SS "How to Support the Development of Embperl" .IX Subsection "How to Support the Development of Embperl" If you use and like Embperl and want to support it's ongoing development you have two possibilities: .IP "1." 4 Send me patches for things you like to see in Embperl .IP "2." 4 Donate money to Embperl. See http://perl.apache.org/donate.htm .IP "3." 4 Buy commercial support (see above). Also you \fBmay\fR get the same answers to your questions on the mailing list, by buying the commercial support you not only buy support for yourself and can be sure you get an answer, you also give us the possibility to put more power in the further development of Embperl. .SH "Links and Download" .IX Header "Links and Download" .SS "Information" .IX Subsection "Information" mod_perl http://perl.apache.org/ .PP Embperl http://perl.apache.org/embperl/ .PP Embperl (german) http://www.ecos.de/embperl/ .PP DBIx::Recordset http://search.cpan.org/~grichter/ .PP Apache web server http://www.apache.org/ .SS "Download" .IX Subsection "Download" mod_perl http://perl.apache.org/dist/ .PP Apache Perl Modules http://www.perl.com/CPAN/modules/by\-module/Apache/ .PP Embperl http://www.embperl.org/downloads .PP DBIx::Recordset http://search.cpan.org/~grichter/ .PP \&\s-1PPM\s0 for ActiveState .PP \&\- Perl 5.6.x http://theoryx5.uwinnipeg.ca/ppmpackages/ .PP \&\- Perl 5.8.x http://theoryx5.uwinnipeg.ca/ppms .PP \&\fBInformations on how to install Embperl can be found in\fR \s-1INSTALL\s0.pod .SS "\s-1SVN\s0" .IX Subsection "SVN" The latest developments are available via \s-1SVN.\s0 Look at \*(L"perldoc \s-1SVN\s0.pod\*(R" for a detailed description. .SH "Syntaxmodes for various editors" .IX Header "Syntaxmodes for various editors" .SS "Emacs" .IX Subsection "Emacs" From: Erik Arneson [erik@mind.net] .PP Here's the amount of documentation I've got right now. .PP They need to get mmm.el from this \s-1URL:\s0 http://mmm\-mode.sourceforge.net/ .PP Then download my mmm\-embperl.el from this one: http://www.aarg.net/erik/mmm\-embperl.el .PP The documentation for using these is included in those two elisp files. .SS "\s-1VIM\s0" .IX Subsection "VIM" Vim Syntaxfile for Vim 5.x & 6.x from Lukas Zapletal with syntax highliting for JavaScript, VBScript, Perl+Embperl, \s-1CSS\s0 and \s-1HTML,\s0 yellow background for Perl`s code (like M$ Interdev) and working Perl folding can be found at http://vim.sourceforge.net/script.php?script_id=61 .PP Vim Syntaxfile from Steve Willer can be found at http://www.interlog.com/~willer/embperl.vim .PP Vim Syntaxfile from Kee Hinckley can be found at http://www.somewhere.com/software/ .SS "Dreamweaver" .IX Subsection "Dreamweaver" Dreamweaver extension which tells Dreamweaver not to touch Embperl code can be found at http://www.somewhere.com/software/ .SH "AUTHOR" .IX Header "AUTHOR" G. Richter (richter at embperl dot org) .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBperl\fR\|(1), mod_perl, Apache httpd