File Coverage

blib/lib/Template/Plugin/NoFollow.pm
Criterion Covered Total %
statement 38 38 100.0
branch 9 10 90.0
condition 1 2 50.0
subroutine 8 8 100.0
pod 2 2 100.0
total 58 60 96.6


line stmt bran cond sub pod time code
1             package Template::Plugin::NoFollow;
2              
3             ###############################################################################
4             # Required inclusions.
5             ###############################################################################
6 2     2   113306 use strict;
  2         5  
  2         63  
7 2     2   12 use warnings;
  2         5  
  2         57  
8 2     2   1163 use HTML::Parser;
  2         11563  
  2         72  
9 2     2   16 use base qw(Template::Plugin::Filter);
  2         4  
  2         1110  
10              
11             ###############################################################################
12             # Version number.
13             ###############################################################################
14             our $VERSION = '1.03';
15              
16             ###############################################################################
17             # Subroutine: init()
18             ###############################################################################
19             # Initializes the template plugin.
20             ###############################################################################
21             sub init {
22 11     11 1 32812 my ($self) = @_;
23 11         32 $self->{'_DYNAMIC'} = 1;
24 11   50     90 $self->install_filter( $self->{'_ARGS'}->[0] || 'nofollow' );
25 11         493 return $self;
26             }
27              
28             ###############################################################################
29             # Subroutine: filter($text, $args, $conf)
30             ###############################################################################
31             # Filters the given text, and adds rel="nofollow" to links.
32             ###############################################################################
33             sub filter {
34 11     11 1 940 my ($self, $text, $args, $conf) = @_;
35              
36             # Merge the FILTER config with the USE config
37 11         33 $conf = $self->merge_config( $conf );
38              
39             # Get list of "allowed" things (e.g. things we DON'T mark as nofollow)
40 11         102 my @allow;
41 11 100       47 if ($conf->{'allow'}) {
42             @allow = ref($conf->{'allow'}) eq 'ARRAY'
43 2         5 ? @{$conf->{'allow'}}
44 3 100       13 : $conf->{'allow'};
45             }
46              
47             # Create a new HTML parser.
48 11         20 my $filtered = '';
49             my $p = HTML::Parser->new(
50 62     62   228 'default_h' => [sub { $filtered .= shift; }, 'text'],
51             'start_h' => [sub {
52 16     16   44 my ($tag, $text, $attr) = @_;
53 16 50       41 if ($tag eq 'a') {
54 16         23 my $should_nofollow = 1;
55 16 100       41 if (grep { $attr->{'href'} =~ /$_/ } @allow) {
  11         154  
56 4         20 $should_nofollow = 0;
57             }
58 16 100       35 if ($should_nofollow) {
59             # remove any existing rel="nofollow" attrs
60 12         84 $text =~ s/(<\s*a)([^>]*)\srel\s*=\s*"?nofollow"?([^>]*>)/$1$2$3/gsmi;
61             # add in our rel="nofollow" attr
62 12         99 $text =~ s/(<\s*a)([^>]*>)/$1 rel="nofollow"$2/gsmi;
63             }
64             }
65 16         83 $filtered .= $text;
66 11         86 }, 'tag, text, attr'],
67             );
68              
69             # Filter the text.
70 11         573 $p->parse( $text );
71 11         48 $p->eof();
72              
73             # Return the filtered text back to the caller.
74 11         146 return $filtered;
75             };
76              
77             1;
78              
79             =head1 NAME
80              
81             Template::Plugin::NoFollow - Template Toolkit filter to add rel="nofollow" to all HTML links
82              
83             =head1 SYNOPSIS
84              
85             [% use NoFollow allow=['www.example.com', '^http://example.com/'] %]
86             ...
87             [% FILTER nofollow %]
88             Google
89             [% END %]
90             ...
91             [% text | nofollow %]
92              
93             =head1 DESCRIPTION
94              
95             C is a filter plugin for L, which
96             adds C to all HTML links found in the filtered text.
97              
98             Through the use of the C option, you can specify URLs that are I
99             marked as C. This can be used to set up a filter that leaves
100             internal links alone, and that marks all external links as C.
101             C accepts regular expressions, so you can be as elaborate as you'd like.
102              
103             =head1 METHODS
104              
105             =over
106              
107             =item init()
108              
109             Initializes the template plugin.
110              
111             =item filter($text, $args, $conf)
112              
113             Filters the given text, and adds rel="nofollow" to links.
114              
115             =back
116              
117             =head1 AUTHOR
118              
119             Graham TerMarsch
120              
121             =head1 COPYRIGHT
122              
123             Copyright (C) 2006-2007, Graham TerMarsch. All Rights Reserved.
124              
125             This is free software; you can redistribute it and/or modify it under the same
126             terms as Perl itself.
127              
128             =head1 SEE ALSO
129              
130             L.
131              
132             =cut