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