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