Changelog, bump versions
[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
cc37b7b3 18Version 0.07_01
ada1ae3c 19
20=cut
21
cc37b7b3 22our $VERSION = '0.07_01';
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)
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
48in your page.
49
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
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
58stash. This way, it's easily accessible by the templates (which is the most
59common use-case).
60
61=head2 C<subinclude( $path, @args )>
62
4e327756 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
68This will render and return the body of the included resource (as specified by
69C<$path>) using the specified subinclude plugin.
70
71The C<subinclude> function above is implemented basically as a shortcut which
72calls this function using the default plugin as the first parameter.
ada1ae3c 73
74=head1 SUBINCLUDE PLUGINS
75
76The module comes with two subinclude plugins:
e88af283 77L<SubRequest|Catalyst::Plugin::View::Component::SubRequest>,
78L<Visit|Catalyst::Plugin::View::Component::Visit> and
ada1ae3c 79L<ESI|Catalyst::Plugin::View::Component::ESI>.
80
be2a019a 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
83itself).
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
94the plugin suffix (e.g. C<ESI> or C<SubRequest>) or a fully-qualified class
95name in the C<Catalyst::View::Component::SubInclude> namespace.
96
97=head2 Writing plugins
98
11a93ea1 99If writing your own plugin, keep in kind plugins are required to implement a
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;
119
120 my $self = $class->$next( @_ );
121
122 my $subinclude_plugin = $self->config->{subinclude_plugin} || 'SubRequest';
be2a019a 123 $self->set_subinclude_plugin( $subinclude_plugin );
30726632 124
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) = @_;
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 );
be2a019a 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
4e327756 179L<Catalyst::Plugin::SubRequest|Catalyst::Plugin::SubRequest>,
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
195=head1 SPONSORSHIP
196
197Development sponsored by Ionzero LLC L<http://www.ionzero.com/>.
198
199=head1 COPYRIGHT & LICENSE
200
201Copyright (C) 2009 Nilson Santos Figueiredo Junior.
202
203Copyright (C) 2009 Ionzero LLC.
204
205This program is free software; you can redistribute it and/or modify it
206under the same terms as Perl itself.
207
208=cut
209
30726632 2101;