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