pass args to ::TT along to all the manually instantiated Template components.
[scpubgit/HTML-String.git] / lib / HTML / String / TT.pm
CommitLineData
ed99cbb4 1package HTML::String::TT;
2
3use strictures 1;
51eaef0b 4
586054e0 5BEGIN {
6 if ($INC{"Template.pm"} and !$INC{"UNIVERSAL/ref.pm"}) {
7 warn "Template was loaded before we could load UNIVERSAL::ref"
8 ." - this means you're probably going to get weird errors."
9 ." To avoid this, use HTML::String::TT before loading Template."
10 }
11 require UNIVERSAL::ref;
12}
13
51eaef0b 14use HTML::String;
15use HTML::String::TT::Directive;
16use Safe::Isa;
ed99cbb4 17use Template;
18use Template::Parser;
19use Template::Stash;
ed99cbb4 20
4f4204a3 21BEGIN {
22 my $orig_blessed = Template::Stash->can('blessed');
23 no warnings 'redefine';
24 *Template::Stash::blessed = sub ($) {
25 my $val = $orig_blessed->($_[0]);
26 return undef if defined($val) and $val eq 'HTML::String::Value';
27 return $val;
28 };
29}
30
ed99cbb4 31sub new {
32 shift;
efe5868f 33 my @args = (ref($_[0]) eq 'HASH' ? %{$_[0]} : @_);
ed99cbb4 34 Template->new(
35 PARSER => Template::Parser->new(
efe5868f 36 FACTORY => 'HTML::String::TT::Directive',
37 @args,
ed99cbb4 38 ),
efe5868f 39 STASH => Template::Stash->new( @args,),
51eaef0b 40 FILTERS => { no_escape => sub {
41 $_[0]->$_isa('HTML::String::Value')
42 ? HTML::String::Value->new(map $_->[0], @{$_[0]->{parts}})
43 : HTML::String::Value->new($_)
44 } },
efe5868f 45 @args,
ed99cbb4 46 );
47}
48
491;
d86bdf82 50
51__END__
52
53=head1 NAME
54
55HTML::String::TT - HTML string auto-escaping for L<Template Toolkit|Template>
56
57=head1 SYNOPSIS
58
59 my $tt = HTML::String::TT->new(\%normal_tt_args);
60
61or, if you're using L<Catalyst::View::TT>:
62
63 use HTML::String::TT; # needs to be loaded before TT to work
64
65 __PACKAGE__->config(
66 CLASS => 'HTML::String::TT',
67 );
68
69Then, in your template -
70
71 <h1>
72 [% title %] <-- this will be automatically escaped
73 </h1>
74 <div id="main">
75 [% some_html | no_escape %] <-- this won't
76 </div>
77 [% html_var = '<foo>'; html_var %] <-- this won't anyway
78
79(but note that the C<content> key in wrappers shouldn't need this).
80
81=head1 DESCRIPTION
82
83L<HTML::String::TT> is a wrapper for L<Template Toolkit|Template> that
84installs the following overrides:
85
86=over 4
87
88=item * The directive generator is replaced with
89L<HTML::String::TT::Directive> which ensures L<HTML::String::Overload> is
90active for the template text.
91
92=item * The stash is forced to be L<Template::Stash> since
93L<Template::Stash::XS> gets utterly confused if you hand it an object.
94
95=item * A filter C<no_escape> is added to mark outside data that you don't
96want to be escaped.
97
98=back
99
100The override happens to B<all> of the plain strings in your template, so
101even things declared within directives such as
102
103 [% html_var = '<h1>' %]
104
105will not be escaped, but any string coming from anywhere else will be. This
106can be a little bit annoying when you then pass it to things that don't
107respond well to overloaded objects, but is essential to L<HTML::String>'s
108policy of "always fail closed" - I'd rather it throws an exception than
109lets a value through unescaped, and if you care about your HTML not having
110XSS (cross site scripting) vulnerabilities then I hope you'll agree.
111
112We mark a number of TT internals namespaces as "don't escape when called by
113these", since TT has a tendency to do things like
114
115 open FH, "< $name";
116
117which really don't work if it gets converted to C<&quot; $name> while you
118aren't looking.
119
120Additionally, since TT often calls C<ref> to decide e.g.
121if something is a string or a glob, it's important that L<UNIVERSAL::ref>
122is loaded before TT is. We check to see if the latter is loaded and the
123former not, and warn loudly that you're probably going to get weird errors.
124
125This warning is not joking. "Probably" is optimistic. Load this module first.
126
127=head1 FILTERS
128
129=head2 no_escape
130
131The C<no_escape> filter marks the filtered input to not be escaped,
132so that you can provide HTML chunks from externally and still render them
133within the TT code.
134
135=head1 AUTHORS
136
137See L<HTML::String> for authors.
138
139=head1 COPYRIGHT AND LICENSE
140
141See L<HTML::String> for the copyright and license.
142
143=cut