package Mason::Component;
BEGIN {
$Mason::Component::VERSION = '2.20';
}
use Moose; # no Mason::Moose - don't want StrictConstructor
use MooseX::HasDefaults::RO;
use Method::Signatures::Simple;
use Log::Any;
use Scalar::Util qw(weaken);
with 'Mason::Filters::Standard';
# Passed attributes
#
has 'args' => ( init_arg => undef, lazy_build => 1 );
has 'm' => ( required => 1, weak_ref => 1 );
__PACKAGE__->meta->make_immutable();
method BUILD ($params) {
# Make a copy of params and re-weaken m
#
$self->{_orig_params} = $params;
weaken $self->{_orig_params}->{m};
}
method cmeta () {
return $self->can('_class_cmeta') ? $self->_class_cmeta : undef;
}
method _build_args () {
my $orig_params = $self->{_orig_params};
return {
map { ( $_, $orig_params->{$_} ) }
grep { $_ ne 'm' } keys(%$orig_params)
};
}
# Default handle - call render
#
method handle () {
$self->render(@_);
}
# Default render - call wrap
#
method render () {
$self->wrap(@_);
}
# Top wrap
#
method wrap () {
inner();
}
# By default, do not allow path_info
#
method allow_path_info () {
return 0;
}
# Shorcut for skipping wrap
#
method no_wrap ($class:) {
$class->meta->add_method( 'render' => sub { $_[0]->main(@_) } );
}
1;
=pod
=head1 NAME
Mason::Component - Mason Component base class
=head1 DESCRIPTION
Every Mason component corresponds to a unique class that inherits, directly or
indirectly, from this base class.
A new instance of the component class is created whenever a component is called
- whether via a top level request, C<< <& &> >> tags, or an << $m->comp >>
call. A component instance is only valid for the Mason request in which it was
created.
We leave this class as devoid of built-in methods as possible, allowing you to
create methods in your own components without worrying about name clashes.
=head1 STRUCTURAL METHODS
This is the standard call chain for the page component (the initial component
of a request).
handle -> render -> wrap -> main
In many cases only C<main> will actually do anything.
=over
=item handle
This is the top-most method called on the page component. Its job is to decide
how to handle the request, e.g.
=over
=item *
throw an error (e.g. permission denied)
=item *
take some action and redirect (e.g. if handling a form in a web environment)
=item *
defer to another component via C<< $m->go >>
=item *
render the page
=back
It should not output any content itself. By default, it simply calls
L<render|/render>.
=item render
This method is invoked from L<handle|/handle> on the page component. Its job is
to output the full content of the page. By default, it simply calls
L<wrap|/wrap>.
=item wrap
This method is invoked from L<render|/render> on the page component. By
convention, C<wrap> is an L<augmented|Moose::Manual::MethodModifiers/INNER AND
AUGMENT> method, with each superclass calling the next subclass. This is
useful for cascading templates in which the top-most superclass generates the
surrounding content.
<%augment wrap>
<h3>Subtitle section</h3>
<div class="main">
<% inner() %>
</div>
</%augment>
By default, C<wrap> simply calls C<< inner() >> to go to the next subclass, and
then L<main|/main> at the bottom subclass.
To override a component's parent wrapper, a component can define its own
C<wrap> using C<method> instead of C<augment>:
<%method wrap>
<h3>Parent wrapper will be ignored</h3>
<% inner() %>
</%method>
To do no wrapping at all, call the component class method L</no_wrap>:
<%class>
CLASS->no_wrap;
</%class>
=item main
This method is invoked when a non-page component is called, and from the
default L<wrap|/wrap> method as well. It consists of the code and output in the
main part of the component that is not inside a C<< <%method> >> or C<<
<%class> >> tag.
=back
=head1 CLASS METHODS
=over
=item no_wrap
A convenience method that redefines L<render|/render> to call L<main|/main>
instead of L<wrap|/wrap>, thus skipping any content wrapper inherited from
parent.
<%class>
CLASS->no_wrap;
</%class>
=item allow_path_info
This method is called when the request path has a path_info portion, to
determine whether the path_info is allowed. Default is false. See
L<Mason::Manual::RequestDispatch/Partial Paths|Mason::Manual::RequestDispatch>.
<%class>
CLASS->allow_path_info(1);
</%class>
=back
=head1 OTHER METHODS
=over
=item args
Returns the hashref of arguments passed to this component's constructor, e.g.
the arguments passed in a L<component call|/CALLING COMPONENTS>.
=item cmeta
Returns the L<Mason::Component::ClassMeta> object associated with this
component class, containing information such as the component's path and source
file.
my $path = $self->cmeta->path;
=item m
Returns the current request. This is also available via C<< $m >> inside Mason
components.
=back
=head1 SEE ALSO
L<Mason|Mason>
=head1 AUTHOR
Jonathan Swartz <swartz@pobox.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Jonathan Swartz.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
__END__