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