1HTML::Mason::SubclassinUgs(e3r)Contributed Perl DocumentHaTtMiLo:n:Mason::Subclassing(3)
2
3
4

NAME

6       HTML::Mason::Subclassing - Documentation on Subclassing Internal Mason
7       classes
8

DESCRIPTION

10       This is the deep voodoo guide, for folks who want to create their own
11       custom subclasses for parts of Mason, such as the Request or Interp
12       objects.
13

Class::Container

15       A number of modules in Mason are subclasses of "Class::Container".
16       This module was originally part of the Mason core as
17       "HTML::Mason::Container", but Ken Williams decided to release it
18       separately on CPAN.
19
20       It was created to encapsulate some common behaviors for Mason objects
21       such as parameter validation and the creation of "contained" objects.
22
23       Basically, any Mason object which takes parameters to its constructor
24       must inherit from this module.  Of course, since all of the classes
25       that you might consider subclassing already inherit from
26       "Class::Container", you won't need to inherit from it directly.
27       However, you may need to use some of its methods.
28
29       So before you go further we highly recommend familiarizing yourself
30       with "Class::Container" and its methods.  Also feel free to look at
31       some of the Mason core modules to see how "Class::Container" is used
32       within Mason itself.
33

SUBCLASSABLE CLASSES

35       The following classes have been designed with subclassing in mind:
36
37       •   HTML::Mason::Request
38
39           This object is your old friend $m.  The request contains
40           information about the current request context, and provides methods
41           for calling other components.
42
43       •   HTML::Mason::Resolver
44
45           The resolver's job is to translate a component paths into an actual
46           component.  Mason comes with a single Resolver subclass,
47           "HTML::Mason::Resolver::File", which is used to translate component
48           paths into filesystem paths.
49
50       •   HTML::Mason::ComponentSource
51
52           An object of this class represents a component's source.  These
53           objects are instantiated by the resolver when it finds a component
54           matching a given path.
55
56       •   HTML::Mason::Lexer
57
58           The lexer is responsible for parsing a component.  Creating a new
59           lexer would allow you to change Mason's component syntax.
60
61       •   HTML::Mason::Compiler
62
63           The compiler takes the parsed chunks from the lexer and gives them
64           meaning.  The default compiler, "HTML::Mason::Compiler::ToObject",
65           turns a Mason component into a Mason "object file", which contains
66           actual Perl code.
67
68       •   HTML::Mason::ApacheHandler
69
70           The ApacheHandler class is the bridge between the mod_perl world
71           and Mason, primarily Mason's Interp class.
72
73           It also provides its own "HTML::Mason::Request" and
74           "HTML::Resolver::File" subclasses which implement some mod_perl
75           specific behaviors and features.
76
77       •   HTML::Mason::Interp
78
79           The Interp is the core of Mason, and is primarily responsible for
80           making all the other objects do their jobs.
81

CONSTRUCTORS

83       If you choose to override the constructor, which is always "new" with
84       Mason objects, that you make sure to call the superclass's constructor
85       and that you use the object returned by it.  A good boilerplate for an
86       overridden constructor looks something like this:
87
88         sub new
89         {
90             my $class = shift;
91
92             my $self = $class->SUPER::new(@_);
93
94             $self->_do_some_init;
95
96             return $self;
97         }
98

Request

100   What to Subclass?
101       One important thing to know about this class is that it is actually
102       several classes.  The first, "HTML::Mason::Request", is used when
103       ApacheHandler is not loaded.  The other,
104       "HTML::Mason::Request::ApacheHandler", is loaded by ApacheHandler and
105       used to provide some mod_perl specific features.  Similar, the
106       CGIHandler class provides its own request subclass,
107       "HTML::Mason::Request::CGIHandler".
108
109       It is impossible to know which one of these to subclass at compile
110       time, since it is possible that your subclass will be loaded before
111       either ApacheHandler or CGIHandler.
112
113       To handle this, simply call the "alter_superclass()" method in your
114       constructor, like this:
115
116         sub new
117         {
118             my $class = shift;
119
120             $class->alter_superclass( $HTML::Mason::ApacheHandler::VERSION ?
121                                       'HTML::Mason::Request::ApacheHandler' :
122                                       $HTML::Mason::CGIHandler::VERSION ?
123                                       'HTML::Mason::Request::CGI' :
124                                       'HTML::Mason::Request' );
125
126             my $self = $class->SUPER::new(@_);
127
128             ...
129
130             return $self;
131         }
132
133       It is quite important that you do this as these handler-specific
134       subclasses provide important functionality.  The "alter_superclass()"
135       method is implemented in the "HTML::Mason::Request" base class, and
136       will do the right thing even in cases of multiple inheritance.  It also
137       cooperates with "Class::Container" to make sure that it sees changes to
138       the inheritance hierarchy.
139
140   The exec() method
141       The "exec" method is called in order to execute a request, and is the
142       method that you are most likely to want to override.
143
144       However, if you do override it we suggest that you make sure to call
145       the parent class's "exec" method to implement the actual component
146       execution and there is no need for you to re-implement them.
147
148       Since the "exec()" method is scalar/list context-sensitive, your "exec"
149       method will need to preserve that.  Here is a boilerplate:
150
151         sub exec
152         {
153             my $self = shift;
154
155             ... # do something cool
156
157             my @r;
158             if (wantarray)
159             {
160                 @r = $self->SUPER::exec(@_);
161             }
162             else
163             {
164                 $r[0] = $self->SUPER::exec(@_);
165             }
166
167             ... # maybe do some cleanup
168
169             return wantarray ? @r : $r[0];
170         }
171
172   Subrequests
173       Your custom request class will also be used to implement subrequests,
174       which are implemented by calling "exec" just like any other method.  If
175       you only want to do certain things in "exec" for the first request, you
176       can simply check the value of "$self->is_subrequest".
177
178   Examples
179       See the "MasonX::Request::WithApacheSession" module on CPAN.
180

Resolver and ComponentSource

182       The resolver takes a component path and figures out what component that
183       path corresponds to.
184
185       All resolver classes must implement two methods, "get_info" and
186       "glob_path".  The first takes a component path and returns a new
187       "HTML::Mason::ComponentSource" object.  This object contains
188       information about the component, such as its last modified time and its
189       source.  See the "HTML::Mason::ComponentSource" documentation for more
190       details.
191
192       You may choose to provide your own ComponentSource subclass as well, if
193       your resolver implementation can take advantage of it.
194
195       The "glob_path" method is responsible for translating a component path
196       like /foo/*/bar into a list of component paths that match that glob
197       pattern.
198

Lexer

200       The rationale for providing your own lexer would be to extend or
201       replace Mason's syntax.
202
203       The lexer is called by the compiler via its "lex" method.  The
204       arguments it receives are the component name, source, and the compiler
205       object.  See the Compiler class documentation for details on what
206       methods the lexer can call.
207

Compiler

209       See the Compiler class documentation for details on what methods a
210       subclass of this class needs to provide.
211
212       If you simply want to tweak Mason's existing behavior, you will
213       probably want to subclass "HTML::Mason::Compiler::ToObject", which is
214       the default Compiler class.  For example, if you wanted to do something
215       like make attributes dynamic, you could override the "_flags_or_attr()"
216       method in ToObject.
217
218       If you want to drastically change the behavior, you can subclass
219       "HTML::Mason::Compiler" instead.  An example of this would be creating
220       a compiler that generates "EmbPerl" or "Apache::ASP" as output.
221

ApacheHandler

223       The methods that you are most likely to want to subclass are documented
224       in the "ApacheHandler class" documentation.
225
226       Providing an ApacheHandler subclass gives you a chance to do your own
227       client parameter parsing, as well as the capability of providing a
228       different way of handling requests.
229

CGIHandler

231       Like the ApacheHandler, you could subclass this module in order to
232       provide your own argument processing or to step in and provide a
233       different way to handle requests.
234

USING SUBCLASSES

236       When using your custom subclasses, we recommend that you take advantage
237       of Mason's ability to construct subclassed object on the fly.
238
239       For example, if you're subclassed the Interp object, you can still let
240       the ApacheHandler object create the Interp object for you, as long as
241       you give it the appropriate interp_class parameter.  This is important
242       because Mason may internally set up certain defaults for contained
243       objects.  For example, the ApacheHandler, by default, will tell the
244       Interp object to use the "HTML::Mason::Request::ApacheHandler" Request
245       subclass.  If you create an Interp object manually and you want to use
246       that Interp object with ApacheHandler, you'll have to specify the same
247       Request class.
248
249       For example:
250
251         my $interp =
252             My::Interp->new
253                 ( request_class  => 'HTML::Mason::Request::ApacheHandler',
254                   my_new_interp_param => 42,
255                 );
256
257         my $ah = HTML::Mason::ApacheHandler->new( interp => $interp );
258
259       It is far easier to simply do this:
260
261         my $ah =
262             HTML::Mason::ApacheHandler->new
263                 ( interp_class => 'My::Interp',
264                   my_new_interp_param => 42,
265                 );
266
267       Your new parameter, "my_new_interp_param", will still be passed to the
268       "My::Interp" constructor, but this also gives ApacheHandler a chance to
269       set various parameters for the Interp object.  Of course, you can still
270       override these defaults explicitly:
271
272         my $ah =
273             HTML::Mason::ApacheHandler->new
274                 ( interp_class => 'My::Interp',
275                   resolver_class => 'My::Resolver'.
276                   my_new_interp_param => 42,
277                 );
278
279       If you need access to the interp object's methods directly, it will be
280       always be available via "$ah->interp".
281
282
283
284perl v5.36.0                      2022-07-22       HTML::Mason::Subclassing(3)
Impressum