The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML::Mason::Subclassing - Documentation on Subclassing Internal Mason classes</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:root@localhost" />
</head>

<body style="background-color: white">


<!-- INDEX BEGIN -->
<div name="index">
<p><A NAME="__index__"></a></p>

<ul>

	<li><A HREF="#name">NAME</a></li>
	<li><A HREF="#description">DESCRIPTION</a></li>
	<li><A HREF="#class__container">Class::Container</a></li>
	<li><A HREF="#subclassable_classes">SUBCLASSABLE CLASSES</a></li>
	<li><A HREF="#constructors">CONSTRUCTORS</a></li>
	<li><A HREF="#request">Request</a></li>
	<ul>

		<li><A HREF="#what_to_subclass">What to Subclass?</a></li>
		<li><A HREF="#the_exec___method">The <code>exec()</code> method</a></li>
		<li><A HREF="#subrequests">Subrequests</a></li>
		<li><A HREF="#examples">Examples</a></li>
	</ul>

	<li><A HREF="#resolver_and_componentsource">Resolver and ComponentSource</a></li>
	<li><A HREF="#lexer">Lexer</a></li>
	<li><A HREF="#compiler">Compiler</a></li>
	<li><A HREF="#apachehandler">ApacheHandler</a></li>
	<li><A HREF="#cgihandler">CGIHandler</a></li>
	<li><A HREF="#using_subclasses">USING SUBCLASSES</a></li>
</ul>

<hr name="index" />
</div>
<!-- INDEX END -->

<p>
</p>
<hr />
<h1><A NAME="name">NAME</a></h1>
<p>HTML::Mason::Subclassing - Documentation on Subclassing Internal Mason classes</p>
<p>
</p>
<hr />
<h1><A NAME="description">DESCRIPTION</a></h1>
<p>This is the deep voodoo guide, for folks who want to create their own
custom subclasses for parts of Mason, such as the Request or Interp
objects.</p>
<p>
</p>
<hr />
<h1><A NAME="class__container">Class::Container</a></h1>
<p>A number of modules in Mason are subclasses of <code>Class::Container</code>.
This module was originally part of the Mason core as
<code>HTML::Mason::Container</code>, but Ken Williams decided to release it separately on CPAN.</p>
<p>It was created to encapsulate some common behaviors for Mason objects
such as parameter validation and the creation of &quot;contained&quot; objects.</p>
<p>Basically, any Mason object which takes parameters to its constructor
<strong>must</strong> inherit from this module.  Of course, since all of the classes
that you might consider subclassing already inherit from
<code>Class::Container</code>, you won't need to inherit from it directly.
However, you may need to use some of its methods.</p>
<p>So before you go further we highly recommend familiarizing yourself
with <code>Class::Container</code> and its methods.  Also feel free to look at
some of the Mason core modules to see how <code>Class::Container</code> is used
within Mason itself.</p>
<p>
</p>
<hr />
<h1><A NAME="subclassable_classes">SUBCLASSABLE CLASSES</a></h1>
<p>The following classes have been designed with subclassing in mind:</p>
<ul>
<li><strong><A NAME="html_mason_request" class="item">HTML::Mason::Request</a></strong>

<p>This object is your old friend <code>$m</code>.  The request contains
information about the current request context, and provides methods
for calling other components.</p>
</li>
<li><strong><A NAME="html_mason_resolver" class="item">HTML::Mason::Resolver</a></strong>

<p>The resolver's job is to translate a component paths into an actual
component.  Mason comes with a single Resolver subclass,
<code>HTML::Mason::Resolver::File</code>, which is used to translate component
paths into filesystem paths.</p>
</li>
<li><strong><A NAME="html_mason_componentsource" class="item">HTML::Mason::ComponentSource</a></strong>

<p>An object of this class represents a component's source.  These
objects are instantiated by the resolver when it finds a component
matching a given path.</p>
</li>
<li><strong><A NAME="html_mason_lexer" class="item">HTML::Mason::Lexer</a></strong>

<p>The lexer is responsible for parsing a component.  Creating a new
lexer would allow you to change Mason's component syntax.</p>
</li>
<li><strong><A NAME="html_mason_compiler" class="item">HTML::Mason::Compiler</a></strong>

<p>The compiler takes the parsed chunks from the lexer and gives them
meaning.  The default compiler, <code>HTML::Mason::Compiler::ToObject</code>,
turns a Mason component into a Mason &quot;object file&quot;, which contains
actual Perl code.</p>
</li>
<li><strong><A NAME="html_mason_apachehandler" class="item">HTML::Mason::ApacheHandler</a></strong>

<p>The ApacheHandler class is the bridge between the mod_perl world and
Mason, primarily Mason's Interp class.</p>
<p>It also provides its own <A HREF="#html_mason_request"><code>HTML::Mason::Request</code></a> and
<code>HTML::Resolver::File</code> subclasses which implement some mod_perl
specific behaviors and features.</p>
</li>
<li><strong><A NAME="html_mason_interp" class="item">HTML::Mason::Interp</a></strong>

<p>The Interp is the core of Mason, and is primarily responsible for
making all the other objects do their jobs.</p>
</li>
</ul>
<p>
</p>
<hr />
<h1><A NAME="constructors">CONSTRUCTORS</a></h1>
<p>If you choose to override the constructor, which is always <code>new</code> with
Mason objects, that you make sure to call the superclass's constructor
and that you use the object returned by it.  A good boilerplate for an
overridden constructor looks something like this:</p>
<pre>
  sub new
  {
      my $class = shift;</pre>
<pre>
      my $self = $class-&gt;SUPER::new(@_);</pre>
<pre>
      $self-&gt;_do_some_init;</pre>
<pre>
      return $self;
  }</pre>
<p>
</p>
<hr />
<h1><A NAME="request">Request</a></h1>
<p>
</p>
<h2><A NAME="what_to_subclass">What to Subclass?</a></h2>
<p>One important thing to know about this class is that it is actually
several classes.  The first, <A HREF="#html_mason_request"><code>HTML::Mason::Request</code></a>, is used when
ApacheHandler is not loaded.  The other,
<code>HTML::Mason::Request::ApacheHandler</code>, is loaded by ApacheHandler and
used to provide some mod_perl specific features.  Similar, the
CGIHandler class provides its own request subclass,
<code>HTML::Mason::Request::CGIHandler</code>.</p>
<p>It is impossible to know which one of these to subclass at compile
time, since it is possible that your subclass will be loaded before
either ApacheHandler or CGIHandler.</p>
<p>To handle this, simply call the <code>alter_superclass()</code> method in your
constructor, like this:</p>
<pre>
  sub new
  {
      my $class = shift;</pre>
<pre>
      $class-&gt;alter_superclass( $HTML::Mason::ApacheHandler::VERSION ?
                                'HTML::Mason::Request::ApacheHandler' :
                                $HTML::Mason::CGIHandler::VERSION ?
                                'HTML::Mason::Request::CGI' :
                                'HTML::Mason::Request' );</pre>
<pre>
      my $self = $class-&gt;SUPER::new(@_);</pre>
<pre>
      ...</pre>
<pre>
      return $self;
  }</pre>
<p>It is quite important that you do this as these handler-specific
subclasses provide important functionality.  The <code>alter_superclass()</code>
method is implemented in the
<a HREF="Request.html"><A HREF="#html_mason_request"><code>HTML::Mason::Request</code></a></a> base class, and will
do the right thing even in cases of multiple inheritance.  It also
cooperates with <code>Class::Container</code> to make sure that it sees changes
to the inheritance hierarchy.</p>
<p>
</p>
<h2><A NAME="the_exec___method">The <code>exec()</code> method</a></h2>
<p>The <code>exec</code> method is called in order to execute a request, and is the
method that you are most likely to want to override.</p>
<p>However, if you do override it we suggest that you make sure to call
the parent class's <code>exec</code> method to implement the actual component
execution and there is no need for you to re-implement them.</p>
<p>Since the <code>exec()</code> method is scalar/list context-sensitive, your
<code>exec</code> method will need to preserve that.  Here is a boilerplate:</p>
<pre>
  sub exec
  {
      my $self = shift;</pre>
<pre>
      ... # do something cool</pre>
<pre>
      my @r;
      if (wantarray)
      {
          @r = $self-&gt;SUPER::exec(@_);
      }
      else
      {
          $r[0] = $self-&gt;SUPER::exec(@_);
      }</pre>
<pre>
      ... # maybe do some cleanup</pre>
<pre>
      return wantarray ? @r : $r[0];
  }</pre>
<p>
</p>
<h2><A NAME="subrequests">Subrequests</a></h2>
<p>Your custom request class will also be used to implement subrequests,
which are implemented by calling <code>exec</code> just like any other method.
If you only want to do certain things in <code>exec</code> for the first
request, you can simply check the value of <code>$self-&gt;is_subrequest</code>.</p>
<p>
</p>
<h2><A NAME="examples">Examples</a></h2>
<p>See the <code>MasonX::Request::WithApacheSession</code> module on CPAN.</p>
<p>
</p>
<hr />
<h1><A NAME="resolver_and_componentsource">Resolver and ComponentSource</a></h1>
<p>The resolver takes a component path and figures out what component
that path corresponds to.</p>
<p>All resolver classes must implement two methods, <code>get_info</code> and
<code>glob_path</code>.  The first takes a component path and returns a new
<A HREF="#html_mason_componentsource"><code>HTML::Mason::ComponentSource</code></a> object.  This object contains
information about the component, such as its last modified time and
its source.  See the
<a HREF="ComponentSource.html"><A HREF="#html_mason_componentsource"><code>HTML::Mason::ComponentSource</code></a></a>
documentation for more details.</p>
<p>You may choose to provide your own ComponentSource subclass as well,
if your resolver implementation can take advantage of it.</p>
<p>The <code>glob_path</code> method is responsible for translating a component
path like <em class="file">/foo/*/bar</em> into a list of component paths that match that
glob pattern.</p>
<p>
</p>
<hr />
<h1><A NAME="lexer">Lexer</a></h1>
<p>The rationale for providing your own lexer would be to extend or
replace Mason's syntax.</p>
<p>The lexer is called by the compiler via its <code>lex</code> method.  The
arguments it receives are the component name, source, and the compiler
object.  See the <a HREF="Compiler.html">Compiler class</a> documentation
for details on what methods the lexer can call.</p>
<p>
</p>
<hr />
<h1><A NAME="compiler">Compiler</a></h1>
<p>See the <a HREF="Compiler.html">Compiler class</a> documentation for
details on what methods a subclass of this class needs to provide.</p>
<p>If you simply want to tweak Mason's existing behavior, you will
probably want to subclass <code>HTML::Mason::Compiler::ToObject</code>, which is
the default Compiler class.  For example, if you wanted to do
something like make attributes dynamic, you could override the
<code>_flags_or_attr()</code> method in ToObject.</p>
<p>If you want to drastically change the behavior, you can subclass
<A HREF="#html_mason_compiler"><code>HTML::Mason::Compiler</code></a> instead.  An example of this would be
creating a compiler that generates <code>EmbPerl</code> or <code>Apache::ASP</code> as
output.</p>
<p>
</p>
<hr />
<h1><A NAME="apachehandler">ApacheHandler</a></h1>
<p>The methods that you are most likely to want to subclass are
documented in the <a HREF="ApacheHandler.html"><code>ApacheHandler class</code></a>
documentation.</p>
<p>Providing an ApacheHandler subclass gives you a chance to do your own
client parameter parsing, as well as the capability of providing a
different way of handling requests.</p>
<p>
</p>
<hr />
<h1><A NAME="cgihandler">CGIHandler</a></h1>
<p>Like the ApacheHandler, you could subclass this module in order to
provide your own argument processing or to step in and provide a
different way to handle requests.</p>
<p>
</p>
<hr />
<h1><A NAME="using_subclasses">USING SUBCLASSES</a></h1>
<p>When using your custom subclasses, we recommend that you take
advantage of Mason's ability to construct subclassed object on the
fly.</p>
<p>For example, if you're subclassed the Interp object, you can still let
the ApacheHandler object create the Interp object for you, as long as
you give it the appropriate <A HREF="Params.html#interp_class">interp_class</a> parameter.  This is
important because Mason may internally set up certain defaults for
contained objects.  For example, the ApacheHandler, by default, will
tell the Interp object to use the
<code>HTML::Mason::Request::ApacheHandler</code> Request subclass.  If you
create an Interp object manually and you want to use that Interp
object with ApacheHandler, you'll have to specify the same Request
class.</p>
<p>For example:</p>
<pre>
  my $interp =
      My::Interp-&gt;new
          ( request_class  =&gt; 'HTML::Mason::Request::ApacheHandler',
            my_new_interp_param =&gt; 42,
          );</pre>
<pre>
  my $ah = HTML::Mason::ApacheHandler-&gt;new( interp =&gt; $interp );</pre>
<p>It is far easier to simply do this:</p>
<pre>
  my $ah =
      HTML::Mason::ApacheHandler-&gt;new
          ( interp_class =&gt; 'My::Interp',
            my_new_interp_param =&gt; 42,
          );</pre>
<p>Your new parameter, <code>my_new_interp_param</code>, will still be passed to
the <code>My::Interp</code> constructor, but this also gives ApacheHandler a
chance to set various parameters for the Interp object.  Of course,
you can still override these defaults explicitly:</p>
<pre>
  my $ah =
      HTML::Mason::ApacheHandler-&gt;new
          ( interp_class =&gt; 'My::Interp',
            resolver_class =&gt; 'My::Resolver'.
            my_new_interp_param =&gt; 42,
          );</pre>
<p>If you need access to the interp object's methods directly, it will be
always be available via <code>$ah-&gt;interp</code>.</p>

</body>

</html>