.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.01 (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 .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . 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 "HTML::Mason::FAQ 3pm" .TH HTML::Mason::FAQ 3pm 2024-03-05 "perl v5.38.2" "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 HTML::Mason::FAQ \- Frequently asked questions .SH "AUTOHANDLERS, METHODS, ATTRIBUTES, INHERITANCE" .IX Header "AUTOHANDLERS, METHODS, ATTRIBUTES, INHERITANCE" .SS "Can I set a page's inheritance dynamically at request time (e.g. based on URL arguments)?" .IX Subsection "Can I set a page's inheritance dynamically at request time (e.g. based on URL arguments)?" No. Inheritance is a fixed property of a component, determined once when the component is loaded. Dynamic inheritance is on the todo list. .SS "How can I tell Mason to use autohandlers or dhandlers when calling one component from another component (i.e. internal redirect)?" .IX Subsection "How can I tell Mason to use autohandlers or dhandlers when calling one component from another component (i.e. internal redirect)?" Usually this situation arises when a top-level component makes a run-time decision to use a second component as the "real" page, and calls it via <& &> or \f(CW$m\fR\->comp. .PP Autohandlers and dhandlers are only triggered for the top-level component of a request. In 1.1, you can use an Apache internal redirect or a Mason subrequest ($m\->subexec) to solve the problem. .SS "I added a simple autohandler to a directory and now my pages don't appear." .IX Subsection "I added a simple autohandler to a directory and now my pages don't appear." Make sure to include a call to \f(CW$m\fR\->call_next somewhere in the autohandler. .SS "Where does a dhandler inherit from? Can I change it to inherit based on the URL path?" .IX Subsection "Where does a dhandler inherit from? Can I change it to inherit based on the URL path?" A dhandler's inheritance is determined by its location in the hierarchy, not by the URL that invoked it. .PP Consider a site with the following components: .PP .Vb 3 \& /autohandler \& /dhandler \& /products/autohandler .Ve .PP and suppose a request comes in for /products/index.html. /dhandler will handle the request but will still inherit from /autohandler. .PP This is not always the desired behavior, but there is no easy way to change it. If you want /products/* requests to use /products/autohandler, you'll need to create /products/dhandler as well. .SS "Can I change the value of an attribute dynamically, based on the request?" .IX Subsection "Can I change the value of an attribute dynamically, based on the request?" No, attributes are static. The closest thing to a dynamic attribute is a method. If you've been using an attribute widely and don't want to change it to a method everywhere, consider using an attribute/method combination. Suppose your attribute is called 'bgcolor'. Create a default method called 'bgcolor' in the autohandler: .PP .Vb 5 \& <%method bgcolor> \& <%init> \& return $m\->base_comp\->attr(\*(Aqbgcolor\*(Aq); \& <%init> \& %method> .Ve .PP Then replace every other .PP .Vb 1 \& $m\->base_comp\->attr(\*(Aqbgcolor\*(Aq); .Ve .PP with .PP .Vb 1 \& $m\->base_comp\->call_method(\*(Aqbgcolor\*(Aq) .Ve .PP or .PP .Vb 1 \& <& SELF:bgcolor &> .Ve .PP Now you can leave the attribute definitions alone, but define a method if and when you need a dynamically computed value. .SS "When using multiple component roots and autohandlers, does every autohandler in every root get called, and in what or" .IX Subsection "When using multiple component roots and autohandlers, does every autohandler in every root get called, and in what or" Mason will try each autohandler path in turn, e.g. .PP .Vb 4 \& /foo/bar/baz/autohandler \& /foo/bar/autohandler \& /foo/autohandler \& /autohandler .Ve .PP For each path, it will search all of the component roots, and only run the *first* autohandler found. Some of the autohandlers might come from one root and some from another. However, there is no way that multiple autohandlers would be run for the same path (/foo/autohandler, for example.) There is also no way for /foo/autohandler in root 1 to explicitly call /foo/autohandler in root 2. .PP People sometimes ask for this behavior to be changed. We feel it's a bad idea because multiple component roots, right now, are very clean in both behavior and implementation. Trying to run multiple autohandlers for the same path would require a complex set of precedence rules that would almost certainly lead to unpredictable behavior. (Think about multiple versions of multiple autohandlers at different directory levels, and trying to predict which order they'd run in.) .SH CACHING .IX Header "CACHING" .SS "When I change a component I don't always see the results in the output. How do I invalidate Mason code caches?" .IX Subsection "When I change a component I don't always see the results in the output. How do I invalidate Mason code caches?" Mason employs two kinds of code caching. First, Mason caches loaded components in memory. Second, Mason keeps an object file (a compiled version of the component) for every loaded component under data_root/obj. .PP Before executing a memory-cached component, Mason compares the stored timestamp with the timestamp of the source file. If the source file has a later timestamp, Mason will load the component from the filesystem. .PP Similarly, before using an object file, Mason compares the modified timestamp of the source and object files. If the source file has a later timestamp, then it is reparsed and the object file is overwritten. .PP The system is designed so that you will immediately see the effects of source file changes. There are several ways for this system to breakdown; most are easy to avoid once you know about them. .PP * If you copy or move in a component source file from elsewhere, it will retain the original file's timestamp, which may be earlier than the object file. .PP * If you use tar, rsync, rdist or similar programs to transfer components, the timestamps of the created files may not be updated to the current time. Check the program's documentation for timestamp-related options. .PP * If you use a shared file system like NFS, the timestamps of locally created files may not jibe with timestamps of NFS files due to differences in machine clocks. .PP * If you ftp files onto a running server, Mason may read the file while it is incomplete. If the ftp then completes within the same second, Mason will not notice the change, and won't ever read the complete file. .PP When in doubt, touching the source files (with the Unix touch command, or by re-saving in an editor) should force Mason to reload the component. If that does not work, try removing the object files and/or restarting the server to clear the memory cache. However, these remedies should be necessary only to diagnose the caching problem, not for normal Mason operation. On a normal Mason system cache expiration should just work "as expected". .SS "Mason code caching breaks down often in my situation. Couldn't you do something smarter than just comparing the timestamps?" .IX Subsection "Mason code caching breaks down often in my situation. Couldn't you do something smarter than just comparing the timestamps?" When coming up with invalidation schemes, we must consider efficiency as well as failure predictability. The current scheme does fail in certain situations, but those situations are very predictable. If you incorrectly use tar or copy or another technique mentioned above, you'll see the cache invalidation failure very quickly. .PP Some alternatives that have been suggested: .PP * Compare the sizes of the files as well as timestamps, or use the more liberal "source timestamp != object timestamp". This would indeed increase the chance of catching a change. But it would still fail occasionally (e.g. when changing a single character, or when copying an old-timestamp file that just happens to match the current timestamp), resulting in intermittent, head-scratching errors. In our opinion, it is better to fail miserably up front and be forced to fix your system than to have a mostly-working system that fails once a week. This is especially true when you are relying on Mason's cache invalidation on a production system. .PP * Comparing MD5 or other signatures of the content. This would be very accurate, but would require reading and processing the source file instead of just performing a stat. This extra expense reduces the effectiveness of the cache. .PP The bottom line: If you are relying on Mason's cache invalidation on a production system, you should take the time and build in the appropriate infrastructure to ensure that source file timestamps are always up-to-date after they are copied/untarred into place. .SS "When I change code in a library file I don't see the results. How can I get Mason to reread the library files?" .IX Subsection "When I change code in a library file I don't see the results. How can I get Mason to reread the library files?" mod_perl processes, in general, do not automatically reread your library files. You either have to stop and start the server whenever you change a library file, or install something like Apache::Reload which will automate their reloading. However, see ApacheReload for important usage information. .SS "Once I've made an error in a component, the error keeps appearing in the logs, no matter how many times I fix it and reload!" .IX Subsection "Once I've made an error in a component, the error keeps appearing in the logs, no matter how many times I fix it and reload!" Are you using Apache::Reload in its default (!ReloadAll) mode? If so, see ApacheReload for details. .SS "Do data cache files expire automatically when a component or its dependencies change?" .IX Subsection "Do data cache files expire automatically when a component or its dependencies change?" Unfortunately they do not. This is on the to-do list. .PP With Mason 1.1x and beyond, you can use the following idiom to say ``expire when my component source file changes'': .PP .Vb 4 \& $m\->cache(..., \& expire_if=>sub { \& (stat($m\->current_comp\->source_file))[9] > $_[0]\->get_created_at \& } ) .Ve .PP With Mason <= 1.05, the idiom looks like: .PP .Vb 4 \& $m\->cache(..., \& expire_if=>sub { \& (stat($m\->current_comp\->source_file))[9] > $_[0] \& } ) .Ve .SH COMPONENTS .IX Header "COMPONENTS" .SS "What is a component?" .IX Subsection "What is a component?" A component is a file that contains some combination of text (typically HTML), perl code and HTML::Mason directives. .PP Some components are accessed directly by web browsers. These are called top-level components. A top-level component might consist purely of static HTML. .PP Other components are support components, which are called by top-level components or other support components. These components are analogous to perl subroutines \-\- they allow you to create small packages of code that you can reuse throughout your project. .SS "How do components communicate with each other?" .IX Subsection "How do components communicate with each other?" Components can return values to their callers, just like subroutines. .PP Some components may have very simple return values. As an example, consider a component called isNetscape which returns a true value when the client's browser is Netscape and undef when it is not. The isNetscape component could then be used easily in an \fBif()\fR or other control statement. .PP Of course, components can also return strings of text, arrays, hashes or other arbitrarily complex perl data structures. .SS "How do I use modules in components?" .IX Subsection "How do I use modules in components?" Technically you can just say "use module-name" at the beginning of a component. The disadvantages of this method are that: .PP * the module will be used separately by every httpd child process, costing both time and memory. .PP * it is difficult to keep track of all the modules being used on a site. .PP A more efficient method is to put the use line in the handler.pl or use the PerlModule directive. If you want components to be able to refer to symbols exported by the module, you need to use the module inside the HTML::Mason::Commands package. See the "External modules" section of the Administrator's Guide: .SS "Can I define subroutines in components?" .IX Subsection "Can I define subroutines in components?" Defining a named subroutine in a <%perl> or <%init> section does not work reliably because such a definition would end up residing inside another subroutine, and Perl doesn't like that. .PP You can technically define named subroutines inside the <%once> section of any component, but we highly discourage this, because all components are executed in the same namespace. This makes it easy to create two subroutines with the same name in two different components. .PP Consider the following options: .PP * If the routine is going to display HTML, use a separate component or a <%def> subcomponent. .PP * If the subroutine is only of use in your component, use an anonymous subroutine defined in <%once>. Even though you could define the anonymous subroutine in any section, a <%once> is recommended, both for performance and to avoid nested-anonymous-subroutine leaks in Perl <=5.6. Example: .PP .Vb 5 \& <%once> \& my $foo = sub { \& ... \& }; \& %once> \& \& ... \& \& % $foo\->() .Ve .PP * If the subroutine is of interest to more than just your component, have you considered putting it in a module? .PP Note that calling a component, while reasonably fast, is about an order of magnitude slower than calling an equivalent subroutine. So if you're going to call the routine many times in a loop, you may wish to use the anonymous subroutine for performance reasons. Benchmark for yourself. .SS "Does Mason set the current working directory (""."") for me?" .IX Subsection "Does Mason set the current working directory (""."") for me?" Mason does not touch the working directory, as this would entail an unnecessary performance hit for the majority of users that don't need it. .PP In an Apache environment, the working directory will be set in a more-or-less random way, depending on such seemingly irrelevant factors as whether you started the server in single-process mode or not. In a non-Apache environment the working directory will be whatever it was before Mason started executing. .PP Often people expect the working directory to be the directory of the current component. You can, instead, get that directory manually with .PP .Vb 1 \& $m\->current_comp\->source_dir .Ve .SS "How do I exit from all components including the ones that called me?" .IX Subsection "How do I exit from all components including the ones that called me?" Use \f(CW$m\fR\->abort, documented in the Request manual: .SS "Why does my output have extra newlines/whitespace and how can I get rid of it?" .IX Subsection "Why does my output have extra newlines/whitespace and how can I get rid of it?" Any newlines that are not either inside a tag or on a %\-line will become part of the output. Since browsers ignore extra whitespace this is not generally a problem, but there are situations where it matters, e.g. within
tags. .PP First, for components that only return a value and shouldn't output *any* content, you should always use <%init>: .PP .Vb 3 \& <%args> \& $foo \& %args> \& \& This content will be ignored. \& \& <%init> \& my $bar = $dbh\->selectrow_array("SELECT bar FROM t WHERE foo=?", $foo); \& return $bar; \& %init> .Ve .PP In components that do display content, there are various strategies. To eliminate selected newlines, use the backslash. For example, .PP .Vb 7 \&\& foo\e \& % if (1) { \& bar\e \& % } \& baz \&.Ve .PP outputs "foobarbaz" with no newlines. .PP To prevent a component from outputting any newlines, use a filter: .PP .Vb 3 \& <%filter> \& s/\en//g; \& %filter> .Ve .PP To emit binary data without the risk of inserting extra whitespace, surround your code with \f(CW$m\fR\->clear_buffer and \f(CW$m\fR\->abort, to suppress any preceding and following content: .PP .Vb 9 \& <%init> \& $m\->clear_buffer; \& my $fh = IO::File\->new(\*(Aq< binary_file\*(Aq) or die $!; \& my $buffer; \& while (read $fh, $buffer, 8192) { \& $m\->print($buffer); \& } \& $m\->abort; \& %init> .Ve .PP At some point Mason will probably offer a "reasonable" whitespace removal feature, controlled by parameter. .SS "I'm trying to generate an image or other binary file, but it seems to be getting corrup" .IX Subsection "I'm trying to generate an image or other binary file, but it seems to be getting corrup" This is almost always caused by unwanted whitespace at the beginning or end of your binary data. Put a \f(CW$m\fR\->clear_buffer before, and an \f(CW$m\fR\->abort after, your code. See the last part of the answer above. .PP In Apache 1.0 a real working example looks like this: .PP .Vb 3 \& my $fh; \& my $fileName = \*(Aq/tmp/mypic.jpg\*(Aq; \& open ( $fh, $fileName ) or die $!; \& \& $m\->clear_buffer(); \& $r\->content_type( \*(Aqimage/jpeg\*(Aq ); # set mime\-type \& $r\->send_http_header; \& $r\->send_fd ( $fh ); \& close ( $fh ); .Ve .PP In Apache 2.0 use: .PP .Vb 1 \& use Apache2::Const qw(HTTP_OK) \& \& my $fileName = \*(Aqsomeimage.jpg\*(Aq; \& $m\->clear_buffer(); \& $r\->content_type( \*(Aqimage/jpeg\*(Aq ); \& $r\->sendfile( $fileName ) \& $r\->abort( Apache2::Const::HTTP_OK ); .Ve .SS "How do I put comments in components?" .IX Subsection "How do I put comments in components?" * Put general comments in the <%doc> section. .PP * In the <%init> and <%cleanup> sections, and in a <%perl> block, use standard Perl comments ('#'). .PP * In Mason 1.3 and beyond, use <%# %> for single or multi-line comments anywhere outside of Perl sections. Before 1.3, this syntax isn't guaranteed to work; one alternative is to begin a line with %#. .PP * If you are producing HTML, you can use standard HTML comments delimited by . The difference is that these comments will appear in the final output. .SS "What's a good way to temporarily comment out code in a component?" .IX Subsection "What's a good way to temporarily comment out code in a component?" For HTML, you might be tempted to surround the section with . But be careful! Any code inside the section will still execute. Here's a example of commenting out a call to an ad server: .PP .Vb 3 \& \& \-\-> .Ve .PP The ad will still be fetched and counted, but not displayed! .PP A better way to block out a section is if (0): .PP .Vb 3 \& % if (0) { \& ... \& % } .Ve .PP Code blocked out in this way will neither be executed nor displayed, and multiple if (0) blocks can be nested inside each other (unlike HTML comments). .PP Another way to block out code is with a <%doc> tag or a <%# %> comment, although these not cannot be nested. .SS "How can I capture the output of a component (and modify it, etc.) instead of having it automatically output?" .IX Subsection "How can I capture the output of a component (and modify it, etc.) instead of having it automatically output?" Use \f(CW$m\fR\->scomp, documented in the Request manual: .SS "Can I use globals in components?" .IX Subsection "Can I use globals in components?" All HTML::Mason components run in the same package (HTML::Mason::Commands), so if you set a global variable in one you'll be able to read it in all the others. The only problem is that Mason by default parses components with strict mode on, so you'll get a warning about the global (and Mason considers all such warnings fatal). To avoid errors, simply declare your globals via the MasonAllowGlobals parameter. .PP .Vb 2 \& PerlSetVar MasonAllowGlobals $dbh \& PerlAddVar MasonAllowGlobals $user .Ve .PP If you have a handler.pl file, you can also declare global variables in the \fBhandler()\fR subroutine as long as you explicitly put them in the HTML::Mason::Commands package. .PP .Vb 2 \& package HTML::Mason::Commands; \& use vars qw(...); .Ve .PP or use the Parser allow_globals parameter. .PP Alternatively you can turn off strict entirely by passing: .PP .Vb 1 \& use_strict => 0 .Ve .PP when you create the Parser object. Then you can use all the globals you want. Doing this is terribly silly, however, and is bound to get you in trouble down the road. .SS "How do I share variables between components?" .IX Subsection "How do I share variables between components?" First, you can pass variables from one component to another. .PP Second, you can use globals. All components run in the same package (HTML::Mason::Commands as of this writing), so globals in this package are visible to all components. See the previous question. .PP There is no way to share a variable between just a few components; this is a limitation of Perl's scoping rules. You can make a variable /visible/ to only certain components using 'our' declarations: .PP .Vb 3 \& <%once> \& our ($shared_var); \& %once> .Ve .PP See the Perl documentation on 'our' to make sure you understand what this is doing. .PP The <%shared> section is /not/ for sharing variables among different file components. It is for sharing variables among the subcomponents and methods of a single file component. .ie n .SS "Why does the order of output get mixed up when I use print or $r\->print?" .el .SS "Why does the order of output get mixed up when I use print or \f(CW$r\fP\->print?" .IX Subsection "Why does the order of output get mixed up when I use print or $r->print?" This should no longer happen with Mason 1.10+. For those users still using older versions of Mason, read the following: .PP Since your server is most likely in batch mode, all Mason output gets buffered til the end of the request. print and \f(CW$r\fR\->print circumvent the buffer and thus come out before other Mason output. .PP Solution: don't use print or \f(CW$r\fR\->print. Use \f(CW$m\fR\->out if you must output inside a Perl section. See the section on output mode in the Administrator's Guide. .PP and the section on \f(CW$m\fR\->out in the Request manual. .SS "Why doesn't my <%cleanup> code run every time the component runs?" .IX Subsection "Why doesn't my <%cleanup> code run every time the component runs?" A <%cleanup> block is equivalent to a \f(CW\*(C`<%perl>\*(C'\fR block at the end of the component. This means it will NOT execute if the component explicitly returns, or if an abort or error occurs in that component or one of its children. .PP If you need code that is guaranteed to run when the component or request exits, consider using a mod_perl cleanup handler, or creating a custom class with a DESTROY method. .ie n .SS "Is <%args> exactly like %ARGS, and do I need to worry about it?" .el .SS "Is <%args> exactly like \f(CW%ARGS\fP, and do I need to worry about it?" .IX Subsection "Is <%args> exactly like %ARGS, and do I need to worry about it?" Mason allows you to predeclare arguments to components by specifying variables to hold those arguments in an <%args>%args> section. Because these are perl variables that you are predeclaring, they must have legal perl identifier names \-\- they can't, for example, contain periods. .PP If you want to pass arguments that are not identified with legal perl names, you must manually pull those arguments out of the \f(CW%ARGS\fR hash that mod_perl sets up for you. Why would you want to name your arguments un-legally, you ask? Well, just for starters, the form input element will pass arguments clickable.x and clickable.y to the action url automatically. If you want to access these, you'd have to use \f(CW$ARGS\fR{clickable.x} and \f(CW$ARGS\fR{clickable.y} rather than trying to declare them in <%args>. .SS "Why does Mason display the wrong line numbers in errors?" .IX Subsection "Why does Mason display the wrong line numbers in errors?" Due to limitations in the 1.0x parser, Mason can only display line numbers relative to object files. .PP In 1.1 and on, error line numbers correctly reflect the component source. .SS "How can I get a list of components matching a path pattern?" .IX Subsection "How can I get a list of components matching a path pattern?" Use the resolver's glob_path method: .PP .Vb 1 \& my @paths = $m\->interp\->resolver\->glob_path(\*(Aq/some/comp/path/*\*(Aq); .Ve .PP This will work even with multiple component roots; you'll get a combined list of all matching component paths in all component roots. .ie n .SS "Can I access $m (the request object) from outside a component, e.g. inside a subroutine?" .el .SS "Can I access \f(CW$m\fP (the request object) from outside a component, e.g. inside a subroutine?" .IX Subsection "Can I access $m (the request object) from outside a component, e.g. inside a subroutine?" In 1.1x and on, use .PP .Vb 1 \& my $m = HTML::Mason::Request\->instance; .Ve .PP Before 1.1x, use .PP .Vb 1 \& my $m = HTML::Mason::Commands::m; .Ve .SS "How can I make the |h escape flag work with my Russian/Japanese/other\-non\-western encoding?" .IX Subsection "How can I make the |h escape flag work with my Russian/Japanese/other-non-western encoding?" The |h flag is implemented with [=HTML::Entities::encode_html]. This function, by default, escapes control chars and high-bit chars as well as <, >, &, and ". This works well for ISO\-8559\-1 encoding but not with other encodings. .PP To make |h escape just <, >, &, and ", which is often what people want, put the following in your Apache configuration: .PP .Vb 1 \& PerlSetVar MasonEscapeFlags "h => \e&HTML::Mason::Escapes::basic_html_escape" .Ve .PP Or, in a top-level autohandler: .PP .Vb 1 \& $m\->interp\->set_escape( h => \e&HTML::Mason::Escapes::basic_html_escape ); .Ve .SS "When using multiple component roots, is there a way to explicitly call a component in a specific root?" .IX Subsection "When using multiple component roots, is there a way to explicitly call a component in a specific root?" Multiple component roots were designed to work just like Perl's \f(CW@INC\fR. A given component path matches exactly one file, the first file found in an ordered search through the roots. There is no way to explicitly ask for a file in a specific root. .PP People sometimes ask for the ability to do this. We feel it's a bad idea because it would endanger the cleanliness of multiple component roots in both behavior and implementation. As it stands now, the rules are very easy to understand and the implementation is very clean and isolated; only the resolver really needs know about multiple component roots. .PP If you want to be able to explicitly refer to components in a given root, put an extra subdirectory between the root and the components. e.g. put your components in .PP .Vb 1 \& /usr/local/htdocs/global/global/... .Ve .PP then add the root as .PP .Vb 1 \& [\*(Aqglobal\*(Aq, \*(Aq/usr/local/htdocs/global\*(Aq] .Ve .PP Now you can prefix a path with /global to refer to any component in that root. .PP Alternatively, [http://search.cpan.org/dist/MasonX\-Request\-ExtendedCompRoot MasonX::Request::ExtendedCompRoot] is a subclass of Mason that does allow you to call components in a specific component root. .SS "Is there a syntax checker like perl \-c for components?" .IX Subsection "Is there a syntax checker like perl -c for components?" It is impossible to write a truly generic standalone script to syntax check components, because components rely on certain globals and modules to be present in their environment. Mason may report compile errors from such a script even though they would not occur in your normal web environment. .PP The best you can do is write a standalone script that mimics your web environment as much as possible \- in particular, declaring the same globals and loading the same modules. Instead of actually executing components, your script need only load them with \f(CW$interp\fR\->\fBload()\fR. This method will throw a fatal error if a component fails to load. .SH "HTTP AND HTML" .IX Header "HTTP AND HTML" .SS "How do I access GET or POST arguments?" .IX Subsection "How do I access GET or POST arguments?" GET and POST arguments are automatically parsed and placed into named component arguments just as if you had called the component with <& &> or \f(CW$m\fR\->comp. So you can get at GET/POST data by pre-declaring argument names and/or using the \f(CW%ARGS\fR hash which is always available. .SS "How can I access the raw content of a POST in a Mason component?" .IX Subsection "How can I access the raw content of a POST in a Mason component?" It depends on your environment as to what you can do. .PP Apache/mod_perl has an easier way of doing it than CGI/FCGi, which uses FakeApache. As you can see from the comment, since FakeApache implements read, I couldn't get it to be completely dynamic: .PP .Vb 10 \& my $inputText; \& # FakeApache implements read, so we can\*(Aqt automatically tell \& # if we\*(Aqre in mod_perl or FCGI \& if (0 && $r\->can(\*(Aqread\*(Aq)){ \& $r\->read( $inputText, $r\->headers_in\->{\*(AqContent\-length\*(Aq} ); \& } \& else { \& my %params = $r\->params; \& my $posted_content = $params{POSTDATA} || $params{keywords}; \& $posted_content ||= join \*(Aq\*(Aq, %params if ($r\->method eq \*(AqPOST\*(Aq); \& $posted_content = join \*(Aq\*(Aq, @$posted_content if (ref $posted_content eq \*(AqARRAY\*(Aq); \& $inputText = $posted_content \& } .Ve .PP \&\-\- Gareth Kirwan .PP Probably \f(CW$r\fR\->params does not work. there is no such method in 'man Apache' .PP \&\-\- Rajesh Kumar Mallah. .SS "What happens if I include query args in a POST?" .IX Subsection "What happens if I include query args in a POST?" As of Mason 1.01, query string and POST arguments are always combined. .SS "Should I use CGI.pm to read GET/POST arguments?" .IX Subsection "Should I use CGI.pm to read GET/POST arguments?" No! HTML::Mason automatically parses GET/POST arguments and places them in declared component arguments and \f(CW%ARGS\fR (see previous question). If you create a CGI object in the usual way for a POST request, it will hang the process trying to read \f(CW$r\fR\->content a second time. .SS "Can I use CGI.pm to output HTML constructs?" .IX Subsection "Can I use CGI.pm to output HTML constructs?" Yes. To get a new CGI object, use .PP .Vb 1 \& my $query = new CGI(\*(Aq\*(Aq); .Ve .PP You have to give the empty string argument or CGI will try to read GET/POST arguments. .PP To print HTML constructs returned by CGI functions, just enclose them in <%%>, e.g. .PP .Vb 1 \& <% $query\->radio_group(...) %> .Ve .SS "How do I modify the outgoing HTTP headers?" .IX Subsection "How do I modify the outgoing HTTP headers?" Use the usual Apache.pm functions, such as \f(CW$r\fR\->header_out. See the "Sending HTTP Headers" section in the Component Developer's Guide. .SS "How do I do an external redirect?" .IX Subsection "How do I do an external redirect?" In Mason 1.0x, use code like this: .PP .Vb 8 \& $m\->clear_buffer; \& # The next two lines are necessary to stop Apache from re\-reading \& # POSTed data. \& $r\->method(\*(AqGET\*(Aq); \& $r\->headers_in\->unset(\*(AqContent\-length\*(Aq); \& $r\->content_type(\*(Aqtext/html\*(Aq); \& $r\->header_out(\*(AqLocation\*(Aq => $location); \& $m\->abort(301); .Ve .PP In Mason 1.1x, use the [=$m\->redirect] method. .PP See the next question if your redirect isn't producing the right status code. .ie n .SS "When trying to use $m\->redirect I get 'Can't locate object method ""redirect"" via package ""HTML::Mason::!ApacheHandler""'." .el .SS "When trying to use \f(CW$m\fP\->redirect I get 'Can't locate object method ""redirect"" via package ""HTML::Mason::!ApacheHandler""'." .IX Subsection "When trying to use $m->redirect I get 'Can't locate object method ""redirect"" via package ""HTML::Mason::!ApacheHandler""'." \&\f(CW$m\fR\->redirect is supported only in Mason 1.1x and on. Check your Mason version by putting .PP .Vb 1 \& Version = <% $HTML::Mason::VERSION %> .Ve .PP in a component. .SS "Why isn't my status code reaching users' browsers?" .IX Subsection "Why isn't my status code reaching users' browsers?" If you are using a handler.pl, your \fBhandler()\fR routine should always return the error code that handle_request($r) produces. Otherwise, things like \f(CW$m\fR\->\fBabort()\fR will not work correctly. So a very, very simple \fBhandler()\fR routine would look like this: .PP .Vb 4 \& sub handler { \& my $r = shift; \& $ah\->handle_request($r); \& } .Ve .PP If you are using \f(CW$m\fR\->abort or \f(CW$m\fR\->redirect and there is an \fBeval()\fR wrapped directly or indirectly around the call, you must take care to propagate abort exceptions after the \fBeval()\fR. This looks like: .PP .Vb 8 \& eval { $m\->comp(\*(Aq...\*(Aq) }; \& if ($@) { \& if ($m\->aborted) { \& die $@; \& } else { \& # deal with non\-abort exceptions \& } \& } .Ve .SS "How can I handle file uploads under Mason?" .IX Subsection "How can I handle file uploads under Mason?" The basic HTML for an upload form looks like: .PP .Vb 4 \&