Add myself to contributors
[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
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;