first part of fix for attributes and roles mess. metclass coompat bug still lurks
[catagits/Reaction.git] / lib / Reaction / UI / Controller / Root.pm
1 package Reaction::UI::Controller::Root;
2
3 use Reaction::Class;
4 use Reaction::UI::Window;
5
6 BEGIN { extends 'Reaction::UI::Controller'; }
7
8 __PACKAGE__->config(
9   view_name => 'XHTML',
10   content_type => 'text/html',
11 );
12
13 has 'view_name' => (isa => 'Str', is => 'rw', required => 1);
14 has 'content_type' => (isa => 'Str', is => 'rw', required => 1);
15 has 'window_title' => (
16   isa => 'Str', is => 'rw', predicate => 'has_window_title'
17 );
18
19 sub begin :Private {
20   my ($self, $ctx) = @_;
21   $ctx->stash(
22     window => Reaction::UI::Window->new(
23       ctx => $ctx,
24       view_name => $self->view_name,
25       content_type => $self->content_type,
26       ($self->has_window_title
27          ? (title => $self->window_title)
28            : ()),
29     )
30   );
31   my $focus_stack = $ctx->stash->{window}->focus_stack;
32   $focus_stack->loc_prefix('r-vp');
33   $ctx->stash(focus_stack => $focus_stack);
34 }
35
36 sub end :Private {
37   my ($self, $ctx) = @_;
38   $ctx->stash->{window}->flush;
39 }
40
41 sub error_404 :Private {
42   my ($self, $c) = @_;
43   $c->res->body("Error 404: Not Found");
44   $c->res->status(404);
45   $c->res->content_type('text/plain');
46 }
47
48 sub error_403 :Private {
49   my ($self, $c) = @_;
50   $c->res->body("Error 403: Forbidden");
51   $c->res->status(403);
52   $c->res->content_type('text/plain');
53 }
54
55 1;
56
57 =head1 NAME
58
59 Reaction::UI::Controller::Root - Base component for the Root Controller
60
61 =head1 SYNOPSIS
62
63   package MyApp::Controller::Root;
64   use base 'Reaction::UI::Controller::Root';
65
66   __PACKAGE__->config(
67     view_name => 'Site',
68     window_title => 'Reaction Test App',
69     namespace => ''
70   );
71
72   # Create UI elements:
73   $c->self->push_viewport('Reaction::UI::ViewPort', %args);
74
75   # Access the window title in a template:
76   [% window.title %]
77
78 =head1 DESCRIPTION
79
80 Using this module as a base component for your L<Catalyst> Root
81 Controller provides automatic creation of a L<Reaction::UI::Window>
82 object containing an empty L<Reaction::UI::FocusStack> for your UI
83 elements. The stack is also resolved and rendered for you in the
84 C<end> action.
85
86 At the C<begin> of each request, the Window object is
87 created using the configured L</view_name>, L</content_type> and
88 L</window_title>. These thus should be directly changed on the stashed
89 window object at runtime, if needed.
90
91 =head1 ATTRIBUTES
92
93 =head2 view_name
94
95 =over
96
97 =item Arguments: $viewname?
98
99 =back
100
101 Set or retrieve the classname of the view used to render the UI. Can
102 also be set by a call to config. Defaults to 'XHTML'.
103
104 =head2 content_type
105
106 =over
107
108 =item Arguments: $contenttype?
109
110 =back
111
112 Set or retrieve the content type of the page created. Can also be set
113 by a call to config or in a config file. Defaults to 'text/html'.
114
115 =head2 window_title
116
117 =over
118
119 =item Arguments: $windowtitle?
120
121 =back
122
123 Set or retrieve the title of the page created. Can also be set by a
124 call to config or in a config file. No default.
125
126 =head1 ACTIONS
127
128 =head2 begin
129
130 Stuffs a new L<Reaction::UI::Window> object into the stash, using the
131 L</view_name> and L</content_type> provided in the
132 L<configuration|/SYNOPSIS>.
133
134 Make sure you call this base C<begin> action if writing your own.
135
136 =head2 end
137
138 Draws the UI via the L<Reaction::UI::Window/flush> method.
139
140 =head1 METHODS
141
142 =head2 error_404
143
144 Sets $c->res (the L<Catalyst::Response>) body, status and content type
145 to output a 404 (File not found) error.
146
147 =head2 error_403
148
149 Sets $c->res (the L<Catalyst::Response>) body, status and content type
150 to output a 403 (Forbidden) error.
151
152
153 =head1 AUTHORS
154
155 See L<Reaction::Class> for authors.
156
157 =head1 LICENSE
158
159 See L<Reaction::Class> for the license.
160
161 =cut