1
2
3__END__
4
5=pod
6
7=head1 NAME
8
9Mason::Manual::Plugins - Mason plugins
10
11=head1 DESCRIPTION
12
13A Mason plugin modifies behavior in one or more of Mason's main classes
14simultaneously, using Moose roles. Many Mason features, even some that might be
15considered "core", are implemented with plugins.
16
17=head1 FINDING PLUGINS
18
19By convention plugins live in the "Mason::Plugin::*" namespace, and plugin
20bundles live in the "Mason::PluginBundle::*" namespace. You can find both with
21this search:
22
23    http://search.cpan.org/search?query=Mason%3A%3APlugin&mode=all
24
25=head1 USING PLUGINS
26
27Pass a list of plugin specs to the Mason constructor:
28
29    Mason->new(plugins =>
30            [
31             'OnePlugin',
32             'AnotherPlugin',
33             '+My::Mason::Plugin::AThirdPlugin',
34             '@APluginBundle',
35             '+My::Mason::PluginBundle::AnotherBundle',
36             '-PluginIDontLike',
37            ]);
38
39Each plugin spec can be one of the following;
40
41=over
42
43=item *
44
45A simple name, which will have "Mason::Plugin::" prepended to it.
46
47=item *
48
49A bundle name, prefixed with '@', which will have "Mason::PluginBundle::"
50prepended to it.
51
52=item *
53
54A full plugin or bundle class name prefixed with '+'.
55
56=item *
57
58Any spec prefixed with '-', which means do not include these plugin(s) in the
59final list.
60
61=back
62
63See Mason::t::Plugins::test_plugin_specs in the Mason distribution for some
64examples.
65
66=head1 DEFAULT PLUGINS
67
68Mason will always add the L<@Default|Mason::PluginBundle::Default> bundle
69regardless of whether you pass your own list. You can remove individual default
70plugins that you don't like:
71
72    plugins => ['-DollarDot', ...]
73
74or the whole list:
75
76    plugins => ['-@Default', ...]
77
78=head1 CREATING PLUGINS
79
80Note: If you want to modify behavior for a particular application only, it
81might be more convenient to create L<subclasses|Mason::Manual::Subclasses>.
82
83A plugin consists of the main plugin class and one or more roles. The main
84class currently looks like this:
85
86    package Mason::Plugin::MyPlugin;
87    use Moose;
88    with 'Mason::Plugin';
89
90    # Optional: declare other plugin dependencies
91    method requires_plugins { qw(A @D) }
92
93    1;
94
95    __END__
96
97    =pod
98
99    =head1 NAME
100
101    Mason::Plugin::MyPlugin - My plugin
102
103    ....
104
105Its main responsibilities are to include the role 'Mason::Plugin' and document
106itself. It may also specify a C<requires_plugins> that returns a list of
107dependencies with the same syntax as the C<plugins> parameter to C<Mason->new>.
108
109The real action is in the role classes, which live underneath, and each modify
110a single Mason class:
111
112    package Mason::Plugin::MyPlugin::Interp;
113    use Mason::PluginRole;
114
115    # Modify Mason::Interp
116
117    ...
118
119    package Mason::Plugin::MyPlugin::Compilation;
120    use Mason::PluginRole;
121
122    # Modify Mason::Compilation
123
124    ...
125
126When a plugin is applied, each of its roles will be automatically applied to
127the appropriate Mason class. For example, in the example above
128C<Mason::Plugin::MyPlugin::Interp> and C<Mason::Plugin::MyPlugin::Compilation>
129will be applied to Mason::Interp and Mason::Compilation respectively.
130
131=head2 Pluggable Mason classes
132
133As of this writing the following Mason classes can be modified with plugins:
134
135    Mason::CodeCache
136    Mason::Compilation
137    Mason::Component
138    Mason::Component::ClassMeta
139    Mason::Component::Import
140    Mason::Component::Moose
141    Mason::Interp
142    Mason::Request
143    Mason::Result
144
145=head2 Extra classes in plugin
146
147If you have extra classes in your plugin that aren't automatically providing a
148role to a Mason class, put them in C<Extra.pm> or the C<Extra> subdirectory,
149e.g.
150
151   package Mason::Plugin::MyPlugin::Extra::Utils;
152   ...
153
154That will ensure that your classname will not conflict with a future Mason
155class name.
156
157=head1 CREATING PLUGIN BUNDLES
158
159A plugin bundle just collects one or more plugins and/or other bundles. It
160looks like this:
161
162    package Mason::PluginBundle::MyBundle
163    use Moose;
164    with 'Mason::PluginBundle';
165
166    sub requires_plugins {
167        return (
168            'A',
169            'B',
170            '+My::Plugin::C',
171            '@D',
172            '+My::PluginBundle::E',
173            );
174    }
175
176    1;
177
178    __END__
179
180    =pod
181
182    =head1 NAME
183
184    Mason::PluginBundle::MyBundle - My plugin bundle
185
186    =head1 INCLUDED PLUGINS
187
188    =over
189
190    =item A
191    =item B
192    =item +My::Plugin::C
193    =item @D
194    =item +My::PluginBundle::E
195
196    =back
197
198    ....
199
200The C<requires_plugins> method returns a list of entries, with the same syntax
201as the C<plugins> parameter to C<Mason->new>.
202
203=head1 ACKNOWLEDGEMENTS
204
205Thanks to Ricardo Signes <rjbs@cpan.org> for L<Dist::Zilla|Dist::Zilla> and
206L<Pod::Weaver|Pod::Weaver>, which got me thinking in plugins and lent the
207plugin and bundle name syntax.
208
209=head1 SEE ALSO
210
211L<Mason|Mason>
212
213=head1 AUTHOR
214
215Jonathan Swartz <swartz@pobox.com>
216
217=head1 COPYRIGHT AND LICENSE
218
219This software is copyright (c) 2012 by Jonathan Swartz.
220
221This is free software; you can redistribute it and/or modify it under
222the same terms as the Perl 5 programming language system itself.
223
224=cut
225