1 package SL::DB::Helper::AttrHTML;
5 use parent qw(Exporter);
6 our @EXPORT = qw(attr_html);
11 use HTML::Restrict ();
20 %stripper = ( parser => HTML::Parser->new );
22 $stripper{parser}->handler(text => sub { $stripper{text} .= $_[1]; });
26 $stripper{parser}->parse($value);
27 $stripper{parser}->eof;
29 return delete $stripper{text};
33 my ($package, $attributes, %params) = @_;
35 # Set default parameters:
36 $params{with_stripped} //= 1;
37 $params{with_restricted} //= 1;
38 $params{allowed_tags} //= { map { ($_ => ['/']) } qw(b strong i em u ul ol li sub sup s strike br p div) };
39 $attributes = [ $attributes ] unless ref($attributes) eq 'ARRAY';
42 foreach my $attribute (@{ $attributes }) {
43 _make_stripped( $package, $attribute, %params) if ($params{with_stripped});
44 _make_restricted($package, $attribute, %params) if ($params{with_restricted});
49 my ($package, $attribute, %params) = @_;
53 *{ $package . '::' . $attribute . '_as_stripped_html' } = sub {
54 my ($self, $value) = @_;
56 return $self->$attribute(_strip_html($value)) if @_ > 1;
57 return _strip_html($self->$attribute);
61 sub _make_restricted {
62 my ($package, $attribute, %params) = @_;
66 my $cleaner = HTML::Restrict->new(rules => $params{allowed_tags});
68 *{ $package . '::' . $attribute . '_as_restricted_html' } = sub {
69 my ($self, $value) = @_;
71 return $self->$attribute($cleaner->process($value)) if @_ > 1;
72 return $cleaner->process($self->$attribute);
85 SL::DB::Helper::AttrHTML - Attribute helper for stripping
86 all/restricting to wanted HTML tags in columns
91 use SL::DB::Helper::AttrHTML;
92 __PACKAGE__->attr_as_html(
95 allowed_tags => { b => [ '/' ], i => [ '/' ] },
98 # Use in HTML templates (no usage of HTML.escape() here!):
100 This is the post's content:<br>
101 [% SELF.obj.content_as_restricted_html %]
104 # Writing to it from a form:
107 [% L.textarea_tag('post.content_as_restricted_html', SELF.obj.content_as_restricted_html) %]
112 Sometimes you want an HTML editor on your web page. However, you only
113 want to allow certain tags. You also need to repeat that stuff when
114 displaying it without risking HTML/JavaScript injection attacks.
116 This plugin provides two helper methods for an attribute:
117 C<attribute_as_stripped_html> which removes all HTML tags, and
118 C<attribute_as_restricted_html> which removes all but a list of safe
119 HTML tags. Both are simple accessor methods.
125 =item C<attr_html $attributes, [%params]>
127 Package method. Call with the name of the attributes (either a scalar
128 for a single attribute or an array reference for multiple attributes)
129 for which the helper methods should be created.
131 C<%params> can include the following options:
135 =item * C<with_stripped> is a scalar that controls the creation of the
136 C<attribute_as_stripped_html> method. It is on by default.
138 =item * C<with_restricted> is a scalar that controls the creation of the
139 C<attribute_as_restricted_html> method. It is on by default. If it is
140 on then the parameter C<allowed_tags> contains the tags that are kept
143 =item * C<allowed_tags> must be a hash reference containing the tags
144 and attributes to keep. It follows the same structural layout as the
145 C<rules> parameter of L<HTML::Restrict/new>. Only relevant if
146 C<with_restricted> is trueish. It defaults to allow the following tags
147 without any attribute safe the trailing slash: C<b i u ul ol li sub
148 sup strike br p div>.
160 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>