Commit | Line | Data |
30726632 |
1 | package Catalyst::View::Component::SubInclude; |
2 | use Moose::Role; |
3 | |
4 | use Carp qw/croak/; |
7094e990 |
5 | use Catalyst::Utils (); |
956a83d8 |
6 | use Class::MOP (); |
7 | use MooseX::Types::Moose qw/Str HashRef/; |
f91a7d21 |
8 | use namespace::clean -except => 'meta'; |
30726632 |
9 | |
d547aa95 |
10 | with 'Catalyst::Component::ContextClosure'; |
11 | |
ada1ae3c |
12 | =head1 NAME |
13 | |
14 | Catalyst::View::Component::SubInclude - Use subincludes in your Catalyst views |
15 | |
16 | =head1 VERSION |
17 | |
dcdc4ec8 |
18 | Version 0.09 |
ada1ae3c |
19 | |
20 | =cut |
21 | |
dcdc4ec8 |
22 | our $VERSION = '0.09'; |
cc37b7b3 |
23 | $VERSION = eval $VERSION; |
ada1ae3c |
24 | |
25 | =head1 SYNOPSIS |
26 | |
27 | package MyApp::View::TT; |
28 | use Moose; |
29 | |
30 | extends 'Catalyst::View::TT'; |
31 | with 'Catalyst::View::Component::SubInclude'; |
32 | |
33 | __PACKAGE__->config( subinclude_plugin => 'SubRequest' ); |
34 | |
35 | Then, somewhere in your templates: |
36 | |
37 | [% subinclude('/my/widget') %] |
be2a019a |
38 | [% subinclude_using('SubRequest', '/page/footer') %] |
ada1ae3c |
39 | |
40 | =head1 DESCRIPTION |
41 | |
42 | C<Catalyst::View::Component::SubInclude> allows you to include content in your |
43 | templates (or, more generally, somewhere in your view's C<render> processing) |
f81dfa28 |
44 | which comes from another action in your application. It's implemented as a |
4e327756 |
45 | L<Moose::Role|Moose::Role>, so using L<Moose|Moose> in your view is required. |
ada1ae3c |
46 | |
47 | Simply put, it's a way to include the output of a Catalyst sub-request somewhere |
f81dfa28 |
48 | in your page. |
ada1ae3c |
49 | |
6bd0988d |
50 | It's built in an extensible way so that you're free to use sub-requests, |
51 | Varnish ESI (L<http://www.catalystframework.org/calendar/2008/17>) or any other |
ada1ae3c |
52 | sub-include plugin you might want to implement. An LWP plugin seems useful and |
6bd0988d |
53 | might be developed in the future. If you need to address a resource by it's |
54 | public path (i.e. the path part trailing C<http://example.com/myapp> then you |
55 | will need to use L<Catalyst::Plugin::SubRequest> directly, and not this |
56 | component. |
ada1ae3c |
57 | |
be2a019a |
58 | =head1 STASH FUNCTIONS |
ada1ae3c |
59 | |
60 | This component does its magic by exporting a C<subinclude> coderef entry to the |
f81dfa28 |
61 | stash. This way, it's easily accessible by the templates (which is the most |
ada1ae3c |
62 | common use-case). |
63 | |
64 | =head2 C<subinclude( $path, @args )> |
65 | |
f81dfa28 |
66 | This will render and return the body of the included resource (as specified by |
be2a019a |
67 | C<$path>) using the default subinclude plugin. |
68 | |
69 | =head2 C<subinclude_using( $plugin, $path, @args )> |
70 | |
f81dfa28 |
71 | This will render and return the body of the included resource (as specified by |
be2a019a |
72 | C<$path>) using the specified subinclude plugin. |
73 | |
f81dfa28 |
74 | The C<subinclude> function above is implemented basically as a shortcut which |
be2a019a |
75 | calls this function using the default plugin as the first parameter. |
ada1ae3c |
76 | |
77 | =head1 SUBINCLUDE PLUGINS |
78 | |
f81dfa28 |
79 | The module comes with two subinclude plugins: |
e88af283 |
80 | L<SubRequest|Catalyst::Plugin::View::Component::SubRequest>, |
f81dfa28 |
81 | L<Visit|Catalyst::Plugin::View::Component::Visit> and |
ada1ae3c |
82 | L<ESI|Catalyst::Plugin::View::Component::ESI>. |
83 | |
f81dfa28 |
84 | By default, the C<SubRequest> plugin will be used. This can be changed in the |
ada1ae3c |
85 | view's configuration options (either in the config file or in the view module |
f81dfa28 |
86 | itself). |
ada1ae3c |
87 | |
88 | Configuration file example: |
89 | |
90 | <View::TT> |
91 | subinclude_plugin ESI |
92 | </View::TT> |
93 | |
be2a019a |
94 | =head2 C<set_subinclude_plugin( $plugin )> |
95 | |
96 | This method changes the current active subinclude plugin in runtime. It expects |
f81dfa28 |
97 | the plugin suffix (e.g. C<ESI> or C<SubRequest>) or a fully-qualified class |
be2a019a |
98 | name in the C<Catalyst::View::Component::SubInclude> namespace. |
99 | |
100 | =head2 Writing plugins |
101 | |
f81dfa28 |
102 | If writing your own plugin, keep in kind plugins are required to implement a |
11a93ea1 |
103 | class method C<generate_subinclude> with the following signature: |
104 | |
105 | sub generate_subinclude { |
106 | my ($class, $c, @args) = @_; |
107 | } |
108 | |
be2a019a |
109 | The default plugin is stored in the C<subinclude_plugin> which can be changed |
110 | in runtime. It expects a fully qualified class name. |
111 | |
ada1ae3c |
112 | =cut |
113 | |
30726632 |
114 | has 'subinclude_plugin' => ( |
115 | is => 'rw', |
956a83d8 |
116 | isa => Str, |
be2a019a |
117 | ); |
30726632 |
118 | |
119 | around 'new' => sub { |
120 | my $next = shift; |
121 | my $class = shift; |
f81dfa28 |
122 | |
30726632 |
123 | my $self = $class->$next( @_ ); |
f81dfa28 |
124 | |
30726632 |
125 | my $subinclude_plugin = $self->config->{subinclude_plugin} || 'SubRequest'; |
be2a019a |
126 | $self->set_subinclude_plugin( $subinclude_plugin ); |
f81dfa28 |
127 | |
30726632 |
128 | $self; |
129 | }; |
130 | |
1869d781 |
131 | before 'render' => sub { |
30726632 |
132 | my ($self, $c, @args) = @_; |
ab0b6bbd |
133 | |
d547aa95 |
134 | $c->stash->{subinclude} = $self->make_context_closure(sub { $self->_subinclude( @_ ) }, $c); |
135 | $c->stash->{subinclude_using} = $self->make_context_closure(sub { $self->_subinclude_using( @_ ) }, $c); |
30726632 |
136 | }; |
137 | |
be2a019a |
138 | sub set_subinclude_plugin { |
139 | my ($self, $plugin) = @_; |
140 | |
956a83d8 |
141 | my $subinclude_class = blessed $self->_subinclude_plugin_class_instance( $plugin ); |
be2a019a |
142 | $self->subinclude_plugin( $subinclude_class ); |
143 | } |
144 | |
145 | sub _subinclude { |
146 | my ($self, $c, @args) = @_; |
147 | $self->_subinclude_using( $c, $self->subinclude_plugin, @args ); |
148 | } |
149 | |
150 | sub _subinclude_using { |
151 | my ($self, $c, $plugin, @args) = @_; |
956a83d8 |
152 | $plugin = $self->_subinclude_plugin_class_instance($plugin); |
153 | $plugin->generate_subinclude( $c, @args ); |
be2a019a |
154 | } |
155 | |
956a83d8 |
156 | has _subinclude_plugin_class_instance_cache => ( |
157 | isa => HashRef, |
158 | is => 'ro', |
159 | default => sub { {} }, |
160 | ); |
161 | |
162 | sub _subinclude_plugin_class_instance { |
be2a019a |
163 | my ($self, $plugin) = @_; |
f81dfa28 |
164 | |
956a83d8 |
165 | my $class = $plugin =~ /::/ ? $plugin : __PACKAGE__ . '::' . $plugin; |
166 | |
167 | my $cache = $self->_subinclude_plugin_class_instance_cache; |
168 | return $cache->{$plugin} if exists $cache->{$plugin}; |
be2a019a |
169 | |
956a83d8 |
170 | my $plugin_config = Catalyst::Utils::merge_hashes( |
171 | $self->config->{subinclude}->{ALL}||{}, |
172 | $self->config->{subinclude}->{$plugin}||{} |
173 | ); |
f81dfa28 |
174 | |
956a83d8 |
175 | Class::MOP::load_class($class); |
be2a019a |
176 | |
956a83d8 |
177 | return $cache->{$plugin} = $class->new($plugin_config); |
be2a019a |
178 | } |
179 | |
ada1ae3c |
180 | =head1 SEE ALSO |
181 | |
f81dfa28 |
182 | L<Catalyst::Plugin::SubRequest|Catalyst::Plugin::SubRequest>, |
4e327756 |
183 | L<Moose::Role|Moose::Role>, L<Moose|Moose>, |
ada1ae3c |
184 | L<http://www.catalystframework.org/calendar/2008/17> |
185 | |
186 | =head1 BUGS |
187 | |
188 | Please report any bugs or feature requests to |
189 | C<bug-catalyst-view-component-subinclude at rt.cpan.org>, or through the web interface at |
190 | L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst-View-Component-SubInclude>. |
191 | I will be notified, and then you'll automatically be notified of progress on |
192 | your bug as I make changes. |
193 | |
194 | =head1 AUTHOR |
195 | |
196 | Nilson Santos Figueiredo Junior, C<< <nilsonsfj at cpan.org> >> |
197 | |
976b0551 |
198 | =head1 CONTRIBUTORS |
199 | |
200 | Tomas Doran (t0m) C<< <bobtfish@bobtfish.net >>. |
201 | |
ada1ae3c |
202 | =head1 SPONSORSHIP |
203 | |
204 | Development sponsored by Ionzero LLC L<http://www.ionzero.com/>. |
205 | |
206 | =head1 COPYRIGHT & LICENSE |
207 | |
976b0551 |
208 | Copyright (C) 2010 Nilson Santos Figueiredo Junior and the above contributors. |
209 | |
ada1ae3c |
210 | Copyright (C) 2009 Nilson Santos Figueiredo Junior. |
211 | |
212 | Copyright (C) 2009 Ionzero LLC. |
213 | |
214 | This program is free software; you can redistribute it and/or modify it |
215 | under the same terms as Perl itself. |
216 | |
217 | =cut |
218 | |
30726632 |
219 | 1; |