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