1 package Catalyst::View::Component::SubInclude;
5 use Catalyst::Utils ();
7 use MooseX::Types::Moose qw/Str HashRef/;
8 use namespace::clean -except => 'meta';
10 with 'Catalyst::Component::ContextClosure';
14 Catalyst::View::Component::SubInclude - Use subincludes in your Catalyst views
22 our $VERSION = '0.07';
26 package MyApp::View::TT;
29 extends 'Catalyst::View::TT';
30 with 'Catalyst::View::Component::SubInclude';
32 __PACKAGE__->config( subinclude_plugin => 'SubRequest' );
34 Then, somewhere in your templates:
36 [% subinclude('/my/widget') %]
37 [% subinclude_using('SubRequest', '/page/footer') %]
41 C<Catalyst::View::Component::SubInclude> allows you to include content in your
42 templates (or, more generally, somewhere in your view's C<render> processing)
43 which comes from another action in your application. It's implemented as a
44 L<Moose::Role|Moose::Role>, so using L<Moose|Moose> in your view is required.
46 Simply put, it's a way to include the output of a Catalyst sub-request somewhere
49 It's built in an extensible way so that you're free to use sub-requests, Varnish
50 ESI (L<http://www.catalystframework.org/calendar/2008/17>) or any other
51 sub-include plugin you might want to implement. An LWP plugin seems useful and
52 might be developed in the future.
54 =head1 STASH FUNCTIONS
56 This component does its magic by exporting a C<subinclude> coderef entry to the
57 stash. This way, it's easily accessible by the templates (which is the most
60 =head2 C<subinclude( $path, @args )>
62 This will render and return the body of the included resource (as specified by
63 C<$path>) using the default subinclude plugin.
65 =head2 C<subinclude_using( $plugin, $path, @args )>
67 This will render and return the body of the included resource (as specified by
68 C<$path>) using the specified subinclude plugin.
70 The C<subinclude> function above is implemented basically as a shortcut which
71 calls this function using the default plugin as the first parameter.
73 =head1 SUBINCLUDE PLUGINS
75 The module comes with two subinclude plugins:
76 L<SubRequest|Catalyst::Plugin::View::Component::SubRequest>,
77 L<Visit|Catalyst::Plugin::View::Component::Visit> and
78 L<ESI|Catalyst::Plugin::View::Component::ESI>.
80 By default, the C<SubRequest> plugin will be used. This can be changed in the
81 view's configuration options (either in the config file or in the view module
84 Configuration file example:
90 =head2 C<set_subinclude_plugin( $plugin )>
92 This method changes the current active subinclude plugin in runtime. It expects
93 the plugin suffix (e.g. C<ESI> or C<SubRequest>) or a fully-qualified class
94 name in the C<Catalyst::View::Component::SubInclude> namespace.
96 =head2 Writing plugins
98 If writing your own plugin, keep in kind plugins are required to implement a
99 class method C<generate_subinclude> with the following signature:
101 sub generate_subinclude {
102 my ($class, $c, @args) = @_;
105 The default plugin is stored in the C<subinclude_plugin> which can be changed
106 in runtime. It expects a fully qualified class name.
110 has 'subinclude_plugin' => (
115 around 'new' => sub {
119 my $self = $class->$next( @_ );
121 my $subinclude_plugin = $self->config->{subinclude_plugin} || 'SubRequest';
122 $self->set_subinclude_plugin( $subinclude_plugin );
127 before 'render' => sub {
128 my ($self, $c, @args) = @_;
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);
134 sub set_subinclude_plugin {
135 my ($self, $plugin) = @_;
137 my $subinclude_class = blessed $self->_subinclude_plugin_class_instance( $plugin );
138 $self->subinclude_plugin( $subinclude_class );
142 my ($self, $c, @args) = @_;
143 $self->_subinclude_using( $c, $self->subinclude_plugin, @args );
146 sub _subinclude_using {
147 my ($self, $c, $plugin, @args) = @_;
148 $plugin = $self->_subinclude_plugin_class_instance($plugin);
149 $plugin->generate_subinclude( $c, @args );
152 has _subinclude_plugin_class_instance_cache => (
155 default => sub { {} },
158 sub _subinclude_plugin_class_instance {
159 my ($self, $plugin) = @_;
161 my $class = $plugin =~ /::/ ? $plugin : __PACKAGE__ . '::' . $plugin;
163 my $cache = $self->_subinclude_plugin_class_instance_cache;
164 return $cache->{$plugin} if exists $cache->{$plugin};
166 my $plugin_config = Catalyst::Utils::merge_hashes(
167 $self->config->{subinclude}->{ALL}||{},
168 $self->config->{subinclude}->{$plugin}||{}
171 Class::MOP::load_class($class);
173 return $cache->{$plugin} = $class->new($plugin_config);
178 L<Catalyst::Plugin::SubRequest|Catalyst::Plugin::SubRequest>,
179 L<Moose::Role|Moose::Role>, L<Moose|Moose>,
180 L<http://www.catalystframework.org/calendar/2008/17>
184 Please report any bugs or feature requests to
185 C<bug-catalyst-view-component-subinclude at rt.cpan.org>, or through the web interface at
186 L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst-View-Component-SubInclude>.
187 I will be notified, and then you'll automatically be notified of progress on
188 your bug as I make changes.
192 Nilson Santos Figueiredo Junior, C<< <nilsonsfj at cpan.org> >>
196 Development sponsored by Ionzero LLC L<http://www.ionzero.com/>.
198 =head1 COPYRIGHT & LICENSE
200 Copyright (C) 2009 Nilson Santos Figueiredo Junior.
202 Copyright (C) 2009 Ionzero LLC.
204 This program is free software; you can redistribute it and/or modify it
205 under the same terms as Perl itself.