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