📄 ch06_04.htm
字号:
<?label 6.4. Embperl?><html><head><title>Embperl (CGI Programming with Perl)</title><link href="../style/style1.css" type="text/css" rel="stylesheet" /><meta name="DC.Creator" content="Scott Guelich, Gunther Birznieks and Shishir Gundavaram" /><meta scheme="MIME" content="text/xml" name="DC.Format" /><meta content="en-US" name="DC.Language" /><meta content="O'Reilly & Associates, Inc." name="DC.Publisher" /><meta scheme="ISBN" name="DC.Source" content="1565924193L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="CGI Programming with Perl" /><meta content="Text.Monograph" name="DC.Type" /></head><body bgcolor="#ffffff"><img src="gifs/smbanner.gif" alt="Book Home" usemap="#banner-map" border="0" /><map name="banner-map"><area alt="CGI Programming with Perl" href="index.htm" coords="0,0,466,65" shape="rect" /><area alt="Search this book" href="jobjects/fsearch.htm" coords="467,0,514,18" shape="rect" /></map><div class="navbar"><table border="0" width="515"><tr><td width="172" valign="top" align="left"><a href="ch06_03.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0" /></a></td><td width="171" valign="top" align="center"><a href="index.htm">CGI Programming with Perl</a></td><td width="172" valign="top" align="right"><a href="ch06_05.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr></table></div><hr align="left" width="515" /><h2 class="sect1">6.4. Embperl</h2><p>SSI and HTML::Template are simple template solutions that allow youto add basic tags to static and dynamic HTML files. The <a name="INDEX-1399" /> <a name="INDEX-1,400" /><a name="INDEX-1401" />HTML::Embperl module, often referred tosimply as Embperl, takes a different approach; it<a name="INDEX-1402" />parses HTML files for<a name="INDEX-1403" />Perlcode, allowing you to shift your code into your HTML documents. Thisapproach is similar to Java Server Pages or Microsoft's ASPtechnology that moves programming languages into documents. There areactually several modules available for embedding Perl within HTMLdocuments, including Embperl, ePerl, HTML::EP, HTML::Mason, andApache::ASP. We'll look at Embperl and Mason in this chapter.</p><p>The theory behind moving code into HTML pages is somewhat differentfrom the standard reason for using HTML templates. Both strategiesattempt to separate the interface from the program logic, but theydraw the lines at different places (see <a href="ch06_04.htm#ch06-40200">Figure 6-2</a>). Basic template solutions like HTML::Templatedraw the line between HTML and all code, at least as much aspossible. For Embperl and similar solutions, the logic for creatingthe page is folded into the HTML for the page, but common<a name="INDEX-1404" />business rules are collected intomodules that can be shared across pages. <em class="emphasis">Businessrules</em> are those core elements of your application or<a name="INDEX-1405" />applications thatare separate from the interface, data management, etc. Of course, inpractice not everyone creates as many modules as the model suggests,and you can create modules like this with any of the approaches (asthe dotted lines suggest). Thus, the model for complex templatesolutions like Embperl and ASP often end up looking like CGI.pm,except that instead of including HTML in the code, the code isincluded in the HTML. This isn't a bad thing, of course. BothCGI.pm and Embperl are excellent solutions for tying together HTMLand program code, and you should choose whatever solution makes themost sense to you for each project. The point is simply that thosewho argue about the different approaches of using CGI.pm versustemplates sometimes are not as far apart as they may seem; theextremes of each seem more alike than different.<a href="#FOOTNOTE-8">[8]</a></p><blockquote><a name="FOOTNOTE-8" /><p>[8]Jason Hunter (author of <em class="emphasis">Java ServletProgramming</em> from O'Reilly & Associates) made asimilar argument from a Java perspective. His article, "TheProblem with JSP," is available at <a href="http://www.servlets.com/soapbox/problems-jsp.html">http://www.servlets.com/soapbox/problems-jsp.html</a>.</p></blockquote><a name="ch06-40200" /><div class="figure"><img width="355" src="figs/cgi2.0602.gif" height="109" alt="Figure 6-2" /></div><h4 class="objtitle">Figure 6-2. Approaches for separating interfaces from code</h4><a name="ch06-10-fm2xml" /><div class="sect2"><h3 class="sect2">6.4.1. Configuration</h3><p><a name="INDEX-1406" /><a name="INDEX-1407" /> <a name="INDEX-1,408" />Embperlcan be used in a variety of ways. You can call Embperl from your CGIscripts and have it parse a template file, just as you would withHTML::Template. In this mode, it simply gives you much more powerthan the latter since you can include full Perl expressions in thetemplate (at the expense of making your templates more complex).However, because you have the entire Perl language at your disposalinside your template files, it really isn't necessary to havean additional CGI script initiate the request. Thus, Embperl can beconfigured as a handler so that your template files can become thetarget of HTTP requests; this works similar to the way that the SSIhandler allows <em class="filename">.shtml</em> files to be the target forHTTP requests.</p><p>Embperl can also be used with or without<em class="emphasis">mod_perl</em>. It is optimized for<em class="emphasis">mod_perl</em>, but it is written in C as well asPerl, so the compiled C code does run faster than a comparable Perlmodule would if you are not using <em class="emphasis">mod_perl</em>.</p><a name="ch06-11-fm2xml" /><div class="sect3"><h3 class="sect3">6.4.1.1. Execute</h3><p>To call Embperl from your CGI scripts, use its<tt class="function">Execute</tt> function and pass it the path to thetemplate along with any parameters to use when parsing the template.For example,</p><blockquote><pre class="code">my $template = "/usr/local/apache/htdocs/templates/welcome.epl";HTML::Embperl::Execute( $template, $time, $greeting );</pre></blockquote><p>This parses <em class="filename">welcome.epl</em>, using the values of<tt class="literal">$time</tt> and <tt class="literal">$greeting</tt> asparameters, and writes the result to STDOUT. Note that we called thefunction as<tt class="function">HTML::Embperl::Execute</tt><a name="INDEX-1409" /><a name="INDEX-1410" /> and not simply<tt class="function">Execute</tt>. Embperl doesn't export anysymbols, nor is it an object-oriented module. Thus, you must fullyqualify the <tt class="function">Execute</tt> function.</p><p>You can also call <tt class="function">Execute</tt> and pass it areference to a hash with named parameters. This gives you moreoptions when using Embperl. For example, you can read the templateinput from a scalar variable instead of a file and you can write theoutput to a file or a variable instead of STDOUT.</p><p>Here is how we can parse the <em class="filename">welcome.epl</em>template and write the result to <em class="filename">welcome.html</em>:</p><blockquote><pre class="code">my $template = "/usr/local/apache/htdocs/templates/welcome.epl";my $output = "/usr/local/apache/htdocs/welcome.html";HTML::Embperl::Execute( { inputfile => $template, param => [ $time, $greeting ], outputfile => $output } );</pre></blockquote><p>Embperl also has options to cache compiled versions of pages whenused with <em class="emphasis">mod_perl</em>. Refer to the Embperldocumentation for the full list of parameters.</p></div><a name="ch06-12-fm2xml" /><div class="sect3"><h3 class="sect3">6.4.1.2. mod_perl</h3><p>If you are using <em class="emphasis">mod_perl</em>, you would registerEmbperl as a handler by adding the following to<em class="filename">httpd.conf</em> (or <em class="filename">srm.conf</em> ifused):</p><blockquote><pre class="code"><Files *.epl> SetHandler perl-script PerlHandler HTML::Embperl Options ExecCGI</files>AddType text/html .epl</pre></blockquote><p>Then any file that has a <em class="filename">.epl</em> suffix will beparsed and executed by Embperl.</p></div><a name="ch06-13-fm2xml" /><div class="sect3"><h3 class="sect3">6.4.1.3. embpcgi.pl</h3><p>If you aren't using <em class="emphasis">mod_perl</em> but want yourEmbperl files to handle requests directly without a CGI script, youcan also use the<em class="filename">embpcgi.pl</em><a name="INDEX-1411" /><a name="INDEX-1412" /> CGI script that is distributed withEmbperl. You place this script in your CGI directory and pass it theURL of the file to parse as part of its path info. For example, youmight have a template file in the following path:</p><blockquote><pre class="code">/usr/local/apache/htdocs/templates/welcome.epl</pre></blockquote><p>To have Embperl handle this file via <em class="filename">embpcgi.pl</em>,you would use the following <a name="INDEX-1413" />URL:</p><blockquote class="simplelist"><p><em class="emphasis">http://localhost/cgi/embpcgi.pl/templates/welcome.epl</em></p></blockquote><p>As a security feature, <em class="filename">embpcgi.pl</em> will onlyhandle files that are located within your web server's documentroot. This prevents someone from trying to get at important fileslike <em class="filename">/etc/passwd</em>. Unfortunately, this means thatpeople can attempt to access your Embperl file directly. For example,someone could view the source to our <em class="filename">welcome.epl</em>file with the following URL:</p><blockquote class="simplelist"><p><em class="emphasis">http://localhost/templates/welcome.epl</em></p></blockquote><p>Allowing people to view the source code of executable files on yourweb server is not a good idea. Thus, if you use<em class="filename">embpcgi.pl</em>, you should create a standarddirectory where you will store your Embperl<a name="INDEX-1414" />templates and disable direct accessto these files. Here is how you would do this for Apache. Add thefollowing directives to <em class="filename">httpd.conf</em> (or<em class="filename">access.conf</em> if used) to disable access to anyfile below the directory named templates:</p><blockquote><pre class="code"><Location /templates> deny from all</Location></pre></blockquote><p>This works by denying access to this directory (and anysubdirectories) to all HTTP request from all web clients.</p></div></div><a name="ch06-14-fm2xml" /><div class="sect2"><h3 class="sect2">6.4.2. Syntax</h3><p>Some HTML editors restrict authors from including tags that they donot recognize as proper HTML tags. This can be a problem when usingthese editors to create HTML templates that often have their ownstyle of custom tags. Embperl was created with this in mind. It doesnot use commands that resemble <a name="INDEX-1415" />HTML tags so you can enter code as text inWYSIWYG editors. Embperl will also interpret any characters that havebeen HTML encoded (such as <tt class="literal">&gt;</tt> instead of<tt class="literal">></tt>) and remove extraneous tags (such as<tt class="literal">&nbsp;</tt> and <BR>) within Perl code beforethat code is evaluated.</p><a name="ch06-15-fm2xml" /><div class="sect3"><h3 class="sect3">6.4.2.1. Embperl code blocks</h3><p>In an Embperl document, <a name="INDEX-1416" /><a name="INDEX-1417" /><a name="INDEX-1418" />Perl commandsare surrounded by a bracket plus another character, which we willrefer to as a <em class="firstterm">bracket pair</em>. As an example,<tt class="literal">[+</tt><a name="INDEX-1419" /> <a name="INDEX-1,420" /> is a starting bracket pair and<tt class="literal">+]</tt> is an ending bracket pair. Embperl supports anumber of bracket pairs and treats the contents differently for each.<a href="ch06_04.htm#ch06-99039">Example 6-10</a> provides a simple Embperl document thatuses most of them.</p><a name="ch06-99039" /><div class="example"><h4 class="objtitle">Example 6-10. simple.epl </h4><blockquote><pre class="code"><HTML><HEAD> <TITLE>A Simple Embperl Document</TITLE></HEAD><BODY BGCOLOR="white"><H2>A Simple Embperl Document</H2>[- $time = localtime -]<P>Here are the details of your request at [+ $time +]:</P><TABLE> <TR> <TH>Name</TH> <TH>Value</TH> </TR> [# Output a row for each environment variable #] [$ foreach $varname ( sort keys %ENV ) $] <TR> <TD><B>[+ $varname +]</B></TD> <TD>[+ $ENV{$varname} +]</TD> </TR> [$ endforeach $]</TABLE></BODY></HTML></pre></blockquote></div><p><a name="INDEX-1421" /><a name="INDEX-1422" /><a name="INDEX-1423" /><a name="INDEX-1424" />Embperlrecognizes blocks of code within the following bracket pairs:</p><dl><dt><b><tt class="literal">[+</tt> ... <tt class="literal">+]</tt></b></dt><dd><p>These brackets are typically used for<a name="INDEX-1425" /><a name="INDEX-1426" />variables and simpleexpressions. Embperl executes the enclosed code and replaces it withthe result of the last expression evaluated. This is evaluated in ascalar context, so something like this:</p><blockquote><pre class="code">[+ @a = ( 'x', 'y', 'z' ); @a +]</pre></blockquote><p>yields an output of "3" (the number of elements in thearray) and not "xyz" or "x y z".</p></dd><dt><b><tt class="literal">[-</tt> ... <tt class="literal">-]</tt></b></dt><dd><p>These brackets are used for most of your <a name="INDEX-1427" />program logicsuch as interfacing with outside modules, assigning values tovariables, etc. Embperl executes the enclosed code and discards theresult.</p></dd><dt><b><tt class="literal">[!</tt> ... <tt class="literal">!]</tt></b></dt><dd><p>These brackets are used with<a name="INDEX-1428" />subroutinesdeclarations and other code that needs to be initialized only once.Embperl treats these bracket pairs just like <tt class="literal">[- ...-]</tt> except that it only executes the enclosed code once.This distinction is most relevant to with<em class="emphasis">mod_perl</em>: because Embperl stays resident betweenHTTP requests, having code run once means once per the life of theweb server child, which may handle a hundred requests (or more). WithCGI, code within this block is only executed once per request. Thesebracket pairs were introduced in Embperl 1.2.</p></dd><dt><b><tt class="literal">[$</tt> ... <tt class="literal">$]</tt></b></dt><dd><p>These brackets are used with Embperl's<a name="INDEX-1429" />meta-commands, such as the<tt class="literal">foreach</tt> and <tt class="literal">endforeach</tt> controlstructure we used in our example. Embperl's meta-commands arelisted in <a href="ch06_04.htm#ch06-63926">Table 6-6</a> later in this chapter.</p></dd><dt><b><tt class="literal">[*</tt> ... <tt class="literal">*]</tt></b></dt><dd><p>These brackets are used when working with<a name="INDEX-1430" /><a name="INDEX-1431" /> <a name="INDEX-1,432" />local variables and for Perl controlstructures. Embperl treats this like <tt class="literal">[- ... -]</tt>except that it executes all the code in the these blocks in a commonscope (sort of, see the <a href="ch06_04.htm#ch06-73315">Section 6.4.2.2, "Variable scope"</a> subsectionbelow). This allows code within these blocks to share local
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -