Tài liệu Embedding Perl in HTML with Mason Chapter 2: Components- P1 pptx

17 403 0
Tài liệu Embedding Perl in HTML with Mason Chapter 2: Components- P1 pptx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Chapter 2: Components- P1 As mentioned in Chapter 1, the basic building block of Mason is called a component. A component consists of text of any sort as well as Mason- specific markup syntax. This chapter briefly introduces some core Mason concepts and then goes into the nitty-gritty of component syntax. In this chapter we'll introduce you to the syntax of Mason components, but we won't spend much time on semantics. In most of the sections, we refer to other parts of the book where you can find out more about each concept. Mason from 10,000 Feet In order to put Mason into perspective, a basic understanding of how Mason processes a request is helpful. Each request is defined by an initial component path and a set of arguments to be passed to that component. Requests are handled by the Interpreter object. You can use it directly or its API can be called by the ApacheHandler or CGIHandler modules provided with Mason. The Interpreter asks the Resolver to fetch the requested component from the filesystem. Then the Interpreter asks the Compiler to create a "compiled" representation of the component. Mason's compilation process consists of turning Mason source code into Perl code, which is then executed in order to create an object representing the component. Mason stores this generated Perl code on disk, so that it doesn't need to go through the parsing and compilation process for every request, and stores the compiled code in an LRU (least recently used) cache in memory. Once Mason has an object representing the initial component, it creates a request object and tells it to execute that component. The initial component might call several other components during the request. Any output a component generates is sent to STDOUT, which is a reasonable default for most environments in which Mason might be used. Of course, it is possible to change this default and send output elsewhere. Several parameters can change how elements of this process happen, and you can replace the core Mason classes with your own customized subclasses for specialized behavior. When using the ApacheHandler module, all of these parameters can be specified in the web server's configuration file. If a fatal error occurs during any part of this process, Mason throws an exception via Perl's built-in die() function. In a mod_perl or CGI environment, Mason will make sure that this exception is handled in a reasonable way, by showing the error in the browser and/or recording the error in the server's error log. You can also catch exceptions in your own code and handle them as you please. Core Concepts Before diving into component syntax, it is important to understand a few basic Mason concepts, with the key concepts highlighted in italics. First there is the component . A component is a combination of text and Mason-specific markup. The markup sections may contain Perl code or special Mason directives. A component can correspond to a single web page, but more often a page is built up from several components. However, a component always corresponds to a single file. A component is usually expected to generate output of some sort, whether HTML, an email message, or an image file. Components are closely analogous to Perl subroutines. The component root is a directory or list of directories on the filesystem under which Mason expects to find all of your components. This is important in determining how component calls are resolved. If you ask Mason to execute the component /view/books.comp , Mason needs to know where to find such a thing. If your component root is /var/www/mason , Mason will look for a file called /var/www/mason/view/books.comp . The process of resolving a component path to a component can actually be a bit more complex than that, because you may actually specify multiple directories in which to search for components or use another storage mechanism altogether. We'll leave those complexities aside for now. 1 When running under Apache, either via mod_perl or CGI, Mason will default to using the web server's document root as the component root. Mason may also be used in ways that don't require a component root at all, such as from a standalone perl script. Since the focus of this book is on building sites, we will generally assume that there is a component root unless we mention otherwise. It is very important to understand that component paths, like URL paths, always use the forward slash (/) as their directory separator, no matter what operating system Mason is running on. In other words, a component path can be thought of as a unique identifier for a particular component, in much the same way that a URL is a unique identifier for a particular resource. Also much like a URL, a component path usually corresponds to a file on disk with a related path, but it needn't necessarily. Basic Component Syntax Mason parses components by taking the text of a component and translating it into actual Perl code. This Perl code, when executed, creates a new HTML::Mason::Component object. This object, in turn, can be used to generate the text originally found in the component. In a sense, this inverts the component, turning it from text with embedded Perl into Perl with embedded text. The markup language Mason uses can give certain parts of the component special semantics, just like any other markup language such as XML or HTML. In this case, the syntax is used to tell Mason that certain parts of the component's text represent either Perl code, special instructions for Mason, or in some cases both. The markup language used for Mason components contains a simple tag to do in-place substitution of Perl expressions, a way to mark a single line as being a line of Perl, and a set of block tags, most of which contain Perl code that is given a special meaning based on the particular tag being used (see Table 2-1) . Tag Name Contains <% . %> Substitution Perl that is evaluated and sent as output % . Perl line A single line of Perl code 2 <%perl> . </%perl> Perl block Perl code <& . &> Component call A call to another component, possibly with arguments <%init> . </%init> init block Perl code that executes before the main body of the component <%args> . </%args> args block A component's input argument declarations Table 2-1. A portion of Mason's markup language Substitution Tags: <% %> The simplest kind of Mason tag is the substitution tag, used to insert the results of a Perl expression into your text. This tag is quite similar to those found in other templating systems. A simple example might look like this: % $cd_count = 207; # this is embedded Perl You have <% $cd_count %> CDs. The output of this example would be: You have 207 CDs. The contents of the tag are evaluated in a list context and joined together just as if they had been passed as arguments to Perl's built-in print() function. It is possible, and often desirable, to put more complicated Perl expressions into your substitution tags. For example, to handle plurals properly, the second line in the previous example could be rewritten as: You have <% $cd_count %> CD<% $cd_count != 1 ? 's': '' %> This could output any of the following, depending on the value of the $cd_count variable: You have 207 CDs. You have 1 CD. You have 0 CDs. The contents of the substitution tag are evaluated as Perl code, so whitespace is ignored, meaning <%$cd_count%> would be perfectly valid, though perhaps a bit difficult to read. Our style is to always include whitespace in a substitution tag. Escaping substitutions One very useful feature provided by Mason is the ability to escape the contents of a tag before it is sent as output. Escaping is the process of making unsafe characters safe. In a web context, safe means that we do not generate output that could be mistaken for HTML. In addition, we may need to do URL-style escaping as well. Substitution escaping is indicated with a pipe (|) followed by one or more escape flags placed before the close of the tag. Currently, there are three valid escape flags, h for HTML entity escaping (i.e., > into &gt; ), u for URI escaping (i.e., > into %3E ), and n for no escaping. The HTML and URI escape flags can be combined (i.e., hu) or used separately. An example might look like: Name: <% $name | h %> Homepage: <a href="redirect?url=<% $homepage | u %>"> The HTML escaping mode escapes the string using the HTML::Entities module, which means that all control and high-bit characters are escaped, as well as the greater-than and l ess-than signs (< and >), the ampersand (&), and the double quote character ("). HTML escaping is particularly useful when you're populating a page with data from an external data source like a database. For instance, consider the following code: <textarea name="foo"><% $foo_data %></textarea> If $foo_data contains the string </textarea>, your HTML will be broken. Guard against this possibility by escaping the output: <textarea name="foo"><% $foo_data | h %></textarea> Mason uses HTML::Entities internally but does not provide a way to tell HTML::Entities not to escape certain characters. By default, HTML::Entities assumes that you are using the ISO-8859-1 character set and escapes characters accordingly. If you are generating text for another character set, such as Big5, you will need to override the way this escaping is done. The URI escaping mode escapes any character besides alphanumerics, the underscore ( _ ), dash ( - ), and period ( . ). The "no escape" escaping mode is used when you have set a default escaping mode via the default_escape_flags parameter (see Chapter 6 for details). The n flag turns off the default escaping for the substitution tag in which it is used. If you want to escape using a different mode than the default, you can combine the n escape with another flag, for example: # default is 'u' <% $contains_html | nh %> The use of spaces around the pipe is optional. The purist will note that $variable | h is perfectly valid Perl syntax for obtaining the value of $variable bitwise OR'ed against the output of the h subroutine (or perhaps the bareword string h ), and therefore this valid Perl construct has a different meaning in <% %> tags than it has in other Perl environments. If you really mean to do the bitwise OR (in which case we strongly suspect you really shouldn't mean to), a workaround looks like this: <% ($variable | h) %> No doubt this will cause much consternation among those who write code that involves OR-ing together variables and the output of subroutines with single character names, who are being made second-class citizens in the Mason world. Sorry, but we're standing firm here. As of version 1.14, Mason supports user-defined escapes so that you can create your own escaping flags, or override existing flags. This is not documented in the book at present, so please see the documentation for the HTML::Mason::Interp module in a recent release of Mason for details. Embedded Perl: % Lines and <%perl> Blocks There are two ways to embed Perl code into text with Mason. The first, the Perl line, is a line that starts with a percent sign ( % ). The rest of that line (up to the newline character) is interpreted as Perl code. This percent sign cannot be preceded by any horizontal whitespace such as spaces or tabs. A typical use of these lines is to implement Perl control structures. For example: % foreach my $person (@people) { Name: <% $person->{name} %> Age: <% $person->{age} %> Height: <% $person->{height} %> Weight: <% $person->{weight} %> % } You can put any valid piece of Perl code on these lines. It is possible to use a Perl line for a larger chunk of code too -- the previous code could have been equivalently written like the following: % foreach my $person (@people) { % print "Name: ", $person->{name}, "\n"; % print "Age: ", $person->{age}, "\n"; % print "Height: ", $person->{height}, "\n"; % print "Weight: ", $person->{weight}, "\n"; % } If you have more than a few lines of Perl code in a row, however, it is probably best to use a Perl block instead. A Perl block is equivalent to a bunch of Perl lines in a row. It begins with the start tag <%perl> and ends with the end tag </%perl>. The contents of these blocks may be any valid Perl code. You may want to use this tag if you need to do some data processing in the midst of your text. For example: <%perl> my @words = $sentence =~ /\b(\S+)\b/g; my @small_words = grep { length $_ <= 3 } @words; my @big_words = grep { length $_ > 3 } @words; </%perl> There were <% scalar @words %> in the sentence. The big words were: % foreach my $word (@big_words) { <% $word %> % } The small words were: % foreach my $word (@small_words) { <% $ [...]... called with content will be covered in more depth in Chapter 5 Other Named Blocks Mason has a variety of other named blocks These all have the same start and end tag syntax as < %perl> blocks, and most of them contain plan Perl However, these other blocks are interpreted as having special meanings by Mason If any of these blocks, or a < %perl> block, is immediately followed by a newline, then that newline... The $m variable contains the HTML: :Mason: :Request object for the current request, and you may use the $m->comp() method in Perl code just as you would use a tag in the component body.3 In fact, in the current version of Mason, the tag is implemented internally with the $m->comp() method So the following two lines are equivalent to each other: 640, admin => 1 &> % $m->comp('menu',... from having to do this all over the place: < %perl> This is the start of the component blocks This is one of the most commonly used Mason blocks The Perl code it contains is run before any other code except for code in or blocks It is run every time the component is called Using this block achieves the same effect as putting a < %perl> ... the result of Perl expression like $component in the example In addition, component calls can take arguments (like width and admin in the third example) just like a Perl subroutine internally, they actually are subroutines How does Mason figure out which component calls are specified directly and which indirectly? It applies some simple parsing rules In a component call tag, if the first nonwhitespace... pleasing, because it allows you to isolate code at the bottom of a component, out of the way of the component's main body The block is typically used for doing things like checking arguments, creating objects, or retrieving data from a database The variables created here are used in substitutions and perl lines throughout the rest of the component It is currently degrees ... menu, width => 640, admin => 1 &> % $m->comp('menu', width => 640, admin => 1); Notice how we used a Perl line, starting with a %, to embed the $m>comp() call in the component In this section we have been intentionally vague about how a Perl expression "specifies" a component There are two ways it may do so: it may either evaluate to a string that gives the path to the component or evaluate to a component... special characters mentioned in the previous paragraph, however, it is necessary to do something to force Mason to see it as Perl An easy way to do this is to wrap the Perl expression in parentheses or to prefix it with Perl' s no-op unary plus operator (+) For example: An alternative to the syntax for calling other components is... < /html> The menu component might contain a navigation bar used on all the pages for a site Other example calls might look like this: 640, admin => 1 &> These calls illustrate several facets of Mason' s component call tag First, the component can be specified either directly using its name in plain text or indirectly as the result of Perl expression... ), Mason assumes that this text is a plain text component path rather than a Perl expression In that case, everything up to the first comma or end of the tag (&>), whichever comes first, is assumed to be a string specifying the component path Anything after a comma, if present, will be considered a list of arguments to pass to the called component If the first nonwhitespace character is something... component call contains a Perl expression (perhaps a variable or function call) whose value indicates the desired component These rules may seem a little arcane, but they manage to capture most people's expectations pretty well Most of the time you can just specify the component in the most natural way, and it will just work If you want to use a Perl expression (the "indirect" syntax) starting with one of . generate the text originally found in the component. In a sense, this inverts the component, turning it from text with embedded Perl into Perl with embedded text Perl: % Lines and < %perl& gt; Blocks There are two ways to embed Perl code into text with Mason. The first, the Perl line, is a line that starts with a

Ngày đăng: 14/12/2013, 12:15

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan