aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Reaction/UI/Controller/Root.pm
blob: bea629caf5334be6917b677bf50ae6b1ea3776c3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package Reaction::UI::Controller::Root;

use Reaction::Class;
use Reaction::UI::Window;

BEGIN { extends 'Reaction::UI::Controller'; }

__PACKAGE__->config(
  view_name => 'XHTML',
  content_type => 'text/html',
);

has 'view_name' => (isa => 'Str', is => 'rw', required => 1);
has 'content_type' => (isa => 'Str', is => 'rw', required => 1);
has 'window_title' => (
  isa => 'Str', is => 'rw', predicate => 'has_window_title'
);

sub begin :Private {
  my ($self, $ctx) = @_;
  $ctx->stash(
    window => Reaction::UI::Window->new(
      ctx => $ctx,
      view_name => $self->view_name,
      content_type => $self->content_type,
      ($self->has_window_title
         ? (title => $self->window_title)
           : ()),
    )
  );
  my $focus_stack = $ctx->stash->{window}->focus_stack;
  $focus_stack->loc_prefix('r-vp');
  $ctx->stash(focus_stack => $focus_stack);
}

sub end :Private {
  my ($self, $ctx) = @_;
  $ctx->stash->{window}->flush;
}

sub error_404 :Private {
  my ($self, $c) = @_;
  $c->res->body("Error 404: Not Found");
  $c->res->status(404);
  $c->res->content_type('text/plain');
}

sub error_403 :Private {
  my ($self, $c) = @_;
  $c->res->body("Error 403: Forbidden");
  $c->res->status(403);
  $c->res->content_type('text/plain');
}

1;

=head1 NAME

Reaction::UI::Controller::Root - Base component for the Root Controller

=head1 SYNOPSIS

  package MyApp::Controller::Root;
  use base 'Reaction::UI::Controller::Root';

  __PACKAGE__->config(
    view_name => 'Site',
    window_title => 'Reaction Test App',
    namespace => ''
  );

  # Create UI elements:
  $c->self->push_viewport('Reaction::UI::ViewPort', %args);

  # Access the window title in a template:
  [% window.title %]

=head1 DESCRIPTION

Using this module as a base component for your L<Catalyst> Root
Controller provides automatic creation of a L<Reaction::UI::Window>
object containing an empty L<Reaction::UI::FocusStack> for your UI
elements. The stack is also resolved and rendered for you in the
C<end> action.

At the C<begin> of each request, the Window object is
created using the configured L</view_name>, L</content_type> and
L</window_title>. These thus should be directly changed on the stashed
window object at runtime, if needed.

=head1 ATTRIBUTES

=head2 view_name

=over

=item Arguments: $viewname?

=back

Set or retrieve the classname of the view used to render the UI. Can
also be set by a call to config. Defaults to 'XHTML'.

=head2 content_type

=over

=item Arguments: $contenttype?

=back

Set or retrieve the content type of the page created. Can also be set
by a call to config or in a config file. Defaults to 'text/html'.

=head2 window_title

=over

=item Arguments: $windowtitle?

=back

Set or retrieve the title of the page created. Can also be set by a
call to config or in a config file. No default.

=head1 ACTIONS

=head2 begin

Stuffs a new L<Reaction::UI::Window> object into the stash, using the
L</view_name> and L</content_type> provided in the
L<configuration|/SYNOPSIS>.

Make sure you call this base C<begin> action if writing your own.

=head2 end

Draws the UI via the L<Reaction::UI::Window/flush> method.

=head1 METHODS

=head2 error_404

Sets $c->res (the L<Catalyst::Response>) body, status and content type
to output a 404 (File not found) error.

=head2 error_403

Sets $c->res (the L<Catalyst::Response>) body, status and content type
to output a 403 (Forbidden) error.


=head1 AUTHORS

See L<Reaction::Class> for authors.

=head1 LICENSE

See L<Reaction::Class> for the license.

=cut