Projekt

Allgemein

Profil

Herunterladen (3,63 KB) Statistiken
| Zweig: | Markierung: | Revision:
package SL::DB::Helper::AttrHTML;

use strict;

use parent qw(Exporter);
our @EXPORT = qw(attr_html);

sub attr_html {
my ($package, $attributes, %params) = @_;

# Set default parameters:
$params{with_stripped} //= 1;
$params{with_restricted} //= 1;
$params{allowed_tags} //= { map { ($_ => ['/']) } qw(b strong i em u ul ol li sub sup s strike br p div) };
$attributes = [ $attributes ] unless ref($attributes) eq 'ARRAY';

# Do the work
foreach my $attribute (@{ $attributes }) {
_make_stripped( $package, $attribute, %params) if ($params{with_stripped});
_make_restricted($package, $attribute, %params) if ($params{with_restricted});
}
}

sub _make_stripped {
my ($package, $attribute, %params) = @_;

no strict 'refs';
require SL::HTML::Util;

*{ $package . '::' . $attribute . '_as_stripped_html' } = sub {
my ($self, $value) = @_;

return $self->$attribute(SL::HTML::Util->strip($value)) if @_ > 1;
return SL::HTML::Util->strip($self->$attribute);
};
}

sub _make_restricted {
my ($package, $attribute, %params) = @_;

no strict 'refs';
require SL::HTML::Restrict;

my $cleaner = SL::HTML::Restrict->create(%params);

*{ $package . '::' . $attribute . '_as_restricted_html' } = sub {
my ($self, $value) = @_;

return $self->$attribute($cleaner->process($value)) if @_ > 1;
return $cleaner->process($self->$attribute);
};
}

1;
__END__

=pod

=encoding utf8

=head1 NAME

SL::DB::Helper::AttrHTML - Attribute helper for stripping
all/restricting to wanted HTML tags in columns

=head1 SYNOPSIS

# In a Rose model:
use SL::DB::Helper::AttrHTML;
__PACKAGE__->attr_as_html(
'content',
with_stripped => 0,
allowed_tags => { b => [ '/' ], i => [ '/' ] },
);

# Use in HTML templates (no usage of HTML.escape() here!):
<div>
This is the post's content:<br>
[% SELF.obj.content_as_restricted_html %]
</div>

# Writing to it from a form:
<form method="post">
...
[% L.textarea_tag('post.content_as_restricted_html', SELF.obj.content_as_restricted_html) %]
</form>

=head1 OVERVIEW

Sometimes you want an HTML editor on your web page. However, you only
want to allow certain tags. You also need to repeat that stuff when
displaying it without risking HTML/JavaScript injection attacks.

This plugin provides two helper methods for an attribute:
C<attribute_as_stripped_html> which removes all HTML tags, and
C<attribute_as_restricted_html> which removes all but a list of safe
HTML tags. Both are simple accessor methods.

=head1 FUNCTIONS

=over 4

=item C<attr_html $attributes, [%params]>

Package method. Call with the name of the attributes (either a scalar
for a single attribute or an array reference for multiple attributes)
for which the helper methods should be created.

C<%params> can include the following options:

=over 2

=item * C<with_stripped> is a scalar that controls the creation of the
C<attribute_as_stripped_html> method. It is on by default.

=item * C<with_restricted> is a scalar that controls the creation of the
C<attribute_as_restricted_html> method. It is on by default. If it is
on then the parameter C<allowed_tags> contains the tags that are kept
by this method.

=item * C<allowed_tags> must be a hash reference containing the tags
and attributes to keep. It follows the same structural layout as the
C<rules> parameter of L<HTML::Restrict/new>. Only relevant if
C<with_restricted> is trueish. It defaults to allow the following tags
without any attribute safe the trailing slash: C<b i u ul ol li sub
sup strike br p div>.

=back

=back

=head1 BUGS

Nothing here yet.

=head1 AUTHOR

Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>

=cut
(7-7/22)