complete overhaul, now with documentation
[catagits/CatalystX-Declare.git] / lib / CatalystX / Declare / Keyword / Controller.pm
1 use MooseX::Declare;
2
3 class CatalystX::Declare::Keyword::Controller 
4     extends MooseX::Declare::Syntax::Keyword::Class
5     with    CatalystX::Declare::DefaultSuperclassing {
6
7
8     use MooseX::MethodAttributes ();
9     use aliased 'CatalystX::Declare::Keyword::Action', 'ActionKeyword';
10     use aliased 'CatalystX::Declare::Controller::RegisterActionRoles';
11     use aliased 'CatalystX::Declare::Controller::DetermineActionClass';
12
13     use Data::Dump qw( pp );
14
15
16     before add_namespace_customizations (Object $ctx, Str $package) {
17
18         MooseX::MethodAttributes->init_meta(for_class => $package);
19         $ctx->add_preamble_code_parts(
20             'use CLASS',
21             sprintf('with qw( %s )', join ' ',
22                 RegisterActionRoles,
23                 DetermineActionClass,
24             ),
25         );
26     }
27
28     method default_superclasses { 'Catalyst::Controller' }
29
30     method auto_make_immutable { 0 }
31
32     method add_with_option_customizations (Object $ctx, $package, ArrayRef $roles, HashRef $options) {
33
34         $ctx->add_cleanup_code_parts(
35             map {
36                 sprintf('Class::MOP::load_class(%s)', pp "$_"),
37                 sprintf('%s->meta->apply(%s->meta)', $_, $package),
38             } @$roles
39         );
40
41         $ctx->add_cleanup_code_parts(
42             sprintf '%s->meta->make_immutable', $package
43         ) unless $options->{is}{mutable};
44     }
45
46     around default_inner () {
47
48         my @modifiers = qw( ); 
49
50         return [
51             ( grep { my $id = $_->identifier; not grep { $id eq $_ } @modifiers } @{ $self->$orig() || [] } ),
52             ActionKeyword->new(identifier => 'action'),
53             ActionKeyword->new(identifier => 'under'),
54             ActionKeyword->new(identifier => 'final'),
55         ];
56     }
57 }
58
59 __END__
60
61 =head1 NAME
62
63 CatalystX::Declare::Keyword::Controller - Declare Catalyst Controllers
64
65 =head1 SYNOPSIS
66
67     controller MyApp::Web::Controller::Example
68        extends MyApp::Web::ControllerBase::CRUD
69        with    MyApp::Web::ControllerRole::Caching {
70     
71
72         $CLASS->config(option_name => 'value');
73
74
75         has attr => (is => 'rw', lazy_build => 1);
76
77         method _build_attr { 'Hello World' }
78
79
80         action base as '';
81
82         final action site, under base {
83             $ctx->response->body( $self->attr );
84         }
85     }
86
87 =head1 DESCRIPTION
88
89 This handler module allows the declaration of Catalyst controllers. The
90 C<controller> keyword is an extension of L<MooseX::Declare/class> with all the
91 bells and whistles, including C<extends>, C<with>, C<method> and modifier
92 declarations.
93
94 In addition to the keywords and features provided by L<MooseX::Declare>, you
95 can also specify your controller's actions declaratively. For the whole truth
96 about the syntax refer to L<CatalystX::Declare::Keyword::Action>.
97
98 For controller roles, please see L<CatalystX::Declare::Keyword::Role>. You can
99 extend controllers with the C<extends> keyword and consume roles via C<with> as
100 usual.
101
102 =head1 SUPERCLASSES
103
104 =over
105
106 =item L<MooseX::Declare::Syntax::Keyword::Class>
107
108 =back
109
110 =head1 ROLES
111
112 =over
113
114 =item L<CatalystX::Declare::DefaultSuperclassing>
115
116 =back
117
118 =head1 METHODS
119
120 These methods are implementation details. Unless you are extending or 
121 developing L<CatalystX::Declare>, you should not be concerned with them.
122
123 =head2 add_namespace_customizations
124
125     Object->add_namespace_customizations (Object $ctx, Str $package)
126
127 This method modifier will initialise the controller with 
128 L<MooseX::MethodAttributes>, import L<CLASS> and add the 
129 L<CatalystX::Declare::Controller::RegisterActionRoles> and
130 L<CatalystX::Declare::Controller::DetermineActionClass> controller roles
131 before calling the original.
132
133 =head2 default_superclasses
134
135     Str Object->default_superclasses ()
136
137 Returns L<Catalyst::Controller> as the default superclass for all declared
138 controllers.
139
140 =head2 auto_make_immutable
141
142     Bool Object->auto_make_immutable ()
143
144 Returns C<0>, indicating that L<MooseX::Declare> should not make this class
145 immutable by itself. We will do that in the L</add_with_option_customizations>
146 method ourselves.
147
148 =head2 add_with_option_customizations
149
150     Object->add_with_option_customizations (
151         Object   $ctx,
152         Str      $package,
153         ArrayRef $roles,
154         HashRef  $options,
155     )
156
157 This hook method will be called by L<MooseX::Declare> when C<with> options were
158 encountered. It will load the specified class and apply them to the controller
159 one at a time. This will change in the future, and they will be all applied 
160 together.
161
162 This method will also add a callback to make the controller immutable to the
163 cleanup code parts unless C<is mutable> was specified.
164
165 =head2 default_inner
166
167     ArrayRef[Object] Object->default_inner ()
168
169 A method modifier around the original. The inner syntax handlers inherited by
170 L<MooseX::Declare::Syntax::Keyword::Class> are extended with instances of the
171 L<CatalystX::Declare::Keyword::Action> handler class for the C<action>, 
172 C<under> and C<final> identifiers.
173
174 =head1 SEE ALSO
175
176 =over
177
178 =item L<CatalystX::Declare>
179
180 =item L<CatalystX::Declare::Keyword::Action>
181
182 =item L<MooseX::Declare/class>
183
184 =back
185
186 =head1 AUTHOR
187
188 See L<CatalystX::Declare/AUTHOR> for author information.
189
190 =head1 LICENSE
191
192 This program is free software; you can redistribute it and/or modify it under 
193 the same terms as perl itself.
194
195 =cut