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