Index: t/wrappers.t
===================================================================
--- t/wrappers.t (revision 5650)
+++ t/wrappers.t (working copy)
@@ -1,11 +1,13 @@
#!/usr/bin/perl
-package MyApp::Templates;
+package MyApp::Wrappers;
use strict;
use warnings;
use Template::Declare::Tags;
-use base 'Template::Declare';
+use base 'Template::Declare::Wrapper';
BEGIN {
+ $INC{'MyApp/Wrappers.pm'} = __FILE__;
+
wrapper wrap => sub {
my $code = shift;
my %params = @_;
@@ -19,9 +21,24 @@
};
}
+package MyApp::Templates;
+use strict;
+use warnings;
+use Template::Declare::Tags;
+use MyApp::Wrappers ':wrappers';
+use base 'Template::Declare';
+
+BEGIN {
+ wrapper bq => sub {
+ my $code = shift;
+ blockquote { p { $code->() } };
+ };
+}
+
template inner => sub {
wrap {
h1 { outs "Hello, Jesse, s'up?" };
+ bq { outs outs 'Something profound' }
} user => 'Jesse';
};
@@ -40,7 +57,9 @@
</head>
<body>
<h1>Hello, Jesse, s'up?</h1>
+ <blockquote>
+ <p>Something profound</p>
+ </blockquote>
<div>This is the end, my friend</div>
</body>
</html>', 'Should have the wrapped output';
-
Index: lib/Template/Declare/Tags.pm
===================================================================
--- lib/Template/Declare/Tags.pm (revision 5650)
+++ lib/Template/Declare/Tags.pm (working copy)
@@ -276,39 +276,60 @@
=head2 wrapper WRAPPERNAME => sub { 'Implementation' };
C<wrapper> declares a wrapper subroutine that can be called like a tag sub,
-but can optionally take arguments to be passed to the wrapper sub. For
-example, if you wanted to wrap all of the output of a template in the usual
-HTML headers and footers, you can do something like this:
+but can optionally take arguments to be passed to the wrapper sub. The idea is
+to declare wrappers in one or more helper modules and then use them in your
+template modules. For example, if you wanted to wrap all of the output of a
+template in the usual HTML headers and footers, you can do something like
+this:
+ package MyApp::Wrappers;
+ use Template::Declare::Tags;
+ use base 'Template::Declare::Wrapper';
+
+ wrapper wrap => sub {
+ my $code = shift;
+ my %params = @_;
+ html {
+ head { title { outs "Hello, $params{user}!"} };
+ body {
+ $code->();
+ div { outs 'This is the end, my friend' };
+ };
+ }
+ };
+
+Now C<use> your wrapper module in a template module, passing in the special
+":wrappers" tag which will import all the wrappers you've defined in that
+module. Tempate::Declare::Wrapper is just using L<Exporter|Exporter>, so in
+fact you could also import your wrappers by name. Here's an example that uses
+the ":wrappers" tag. It also, coincidentally, creates its own, unexported
+wrapper, C<bq>, that can just be used in the scope of the module (or by using
+the fully-qualified function name in another module):
+
package MyApp::Templates;
+ use base 'Template::Declare';
+ use MyApp::Wrappers ':wrappers';
use Template::Declare::Tags;
- use base 'Template::Declare';
BEGIN {
- wrapper wrap => sub {
+ wrapper bq => sub {
my $code = shift;
- my %params = @_;
- html {
- head { title { outs "Hello, $params{user}!"} };
- body {
- $code->();
- div { outs 'This is the end, my friend' };
- };
- }
+ blockquote { p { $code->() } };
};
}
- template inner => sub {
+ template howdy => sub {
wrap {
h1 { outs "Hello, Jesse, s'up?" };
+ bq { outs 'Ask not what your country can do for you.' }
} user => 'Jesse';
};
-Note how the C<wrap> wrapper function is available for calling after it has
-been declared in a C<BEGIN> block. Also note how you can pass arguments to the
-function after the closing brace (you don't need a comma there!).
+Note how the C<bq> wrapper function is available for calling after it has been
+declared in a C<BEGIN> block. Also note how you can pass arguments to wrapper
+function calls after the closing brace (you don't need a comma there!).
-The output from the "inner" template will look something like this:
+The output from the "howdy" template will look something like this:
<html>
<head>
@@ -316,6 +337,9 @@
</head>
<body>
<h1>Hello, Jesse, s'up?</h1>
+ <blockquote>
+ <p>Something profound</p>
+ </blockquote>
<div>This is the end, my friend</div>
</body>
</html>
@@ -330,6 +354,21 @@
# Shove the code ref into the calling class.
no strict 'refs';
*{"$template_class\::$wrapper_name"} = sub (&;@) { goto $coderef };
+
+ # Just return unless inheriting from Wrapper.
+ return unless $template_class->isa('Template::Declare::Wrapper');
+
+ # Make things exportabl from Wrapper by tweaking @EXPORT_OK and %EXPORT_TAGS.
+ if (my $ok = *{"$template_class\::EXPORT_OK"}{ARRAY}) {
+ push @{ $ok }, $wrapper_name;
+ } else {
+ *{"$template_class\::EXPORT_OK"} = [$wrapper_name ];
+ }
+ if (my $tags = *{"$template_class\::EXPORT_TAGS"}{HASH}) {
+ push @{ $tags->{wrappers} ||= [] }, $wrapper_name;
+ } else {
+ *{"$template_class\::EXPORT_TAGS"} = { wrappers => [$wrapper_name ] };
+ }
}
=head2 private template TEMPLATENAME => sub { 'Implementation' };
@@ -962,4 +1001,7 @@
}
}
+package Template::Declare::Wrapper;
+use Exporter 'import';
+
1;