File Coverage

blib/lib/Template/Plugin/LinkTarget.pm
Criterion Covered Total %
statement 48 48 100.0
branch 11 12 91.6
condition 3 4 75.0
subroutine 9 9 100.0
pod 2 2 100.0
total 73 75 97.3


line stmt bran cond sub pod time code
1             package Template::Plugin::LinkTarget;
2              
3             ###############################################################################
4             # Required inclusions.
5             ###############################################################################
6 1     1   80857 use strict;
  1         2  
  1         50  
7 1     1   7 use warnings;
  1         2  
  1         36  
8 1     1   1184 use HTML::Parser;
  1         6907  
  1         51  
9 1     1   9 use HTML::Entities qw(encode_entities);
  1         3  
  1         130  
10 1     1   7 use base qw(Template::Plugin::Filter);
  1         2  
  1         1044  
11              
12             ###############################################################################
13             # Version number.
14             ###############################################################################
15             our $VERSION = '0.02';
16              
17             ###############################################################################
18             # Subroutine: init()
19             ###############################################################################
20             # Initializes the template plugin.
21             ###############################################################################
22             sub init {
23 10     10 1 38672 my $self = shift;
24 10         31 $self->{'_DYNAMIC'} = 1;
25 10   50     91 $self->install_filter( $self->{'_ARGS'}->[0] || 'linktarget' );
26 10         407 return $self;
27             }
28              
29             ###############################################################################
30             # Subroutine: filter($text, $args, $conf)
31             ###############################################################################
32             # Filters the given text, and adds the "target" attribute to links.
33             ###############################################################################
34             sub filter {
35 10     10 1 900 my ($self, $text, $args, $conf) = @_;
36              
37             # Merge the FILTER config with the USE config
38 10         40 $conf = $self->merge_config( $conf );
39              
40             # Get list of "excluded" things (e.g. things we DON'T add targets to)
41 10         85 my @exclude;
42 10 100       38 if ($conf->{'exclude'}) {
43 2         7 @exclude = ref($conf->{'exclude'}) eq 'ARRAY'
44 3 100       14 ? @{$conf->{'exclude'}}
45             : $conf->{'exclude'};
46             }
47              
48             # Get the "target" for links.
49 10   100     45 my $target = $conf->{'target'} || '_blank';
50              
51             # Create a new HTML parser.
52 10         15 my $filtered = '';
53             my $p = HTML::Parser->new(
54 61     61   260 'default_h' => [sub { $filtered .= shift; }, 'text'],
55             'start_h' => [sub {
56 16     16   36 my ($tag, $text, $attr, $attrseq) = @_;
57 16 50       41 if ($tag eq 'a') {
58 16         23 my $should_add = 1;
59 16 100       32 if (grep { $attr->{'href'} =~ /$_/ } @exclude) {
  12         181  
60 5         8 $should_add = 0;
61             }
62 16 100       34 if ($should_add) {
63             # add in our "target" attr, replacing any existing one
64 11 100       33 unless (exists $attr->{'target'}) {
65 10         14 push( @{$attrseq}, 'target' )
  10         19  
66             }
67 11         22 $attr->{'target'} = $target;
68             # rebuild the tag
69 23         244 my @attrs = map { qq{$_="} . encode_entities($attr->{$_}) . qq{"} }
  11         21  
70 11         15 @{$attrseq};
71 11         170 $text = '';
72             }
73             }
74 16         100 $filtered .= $text;
75 10         142 }, 'tag, text, attr, attrseq'],
76             );
77              
78             # Filter the text.
79 10         670 $p->parse( $text );
80 10         42 $p->eof();
81              
82             # Return the filtered text back to the caller.
83 10         173 return $filtered;
84             }
85              
86             1;
87              
88             =head1 NAME
89              
90             Template::Plugin::LinkTarget - TT filter to add "target" attribute to all HTML links
91              
92             =head1 SYNOPSIS
93              
94             [% USE LinkTarget(target="_blank" exclude=['www.example.com']) %]
95             ...
96             [% FILTER linktarget %]
97             Google
98             [% END %]
99             ...
100             [% text | linktarget %]
101              
102             =head1 DESCRIPTION
103              
104             C is a filter plugin for TT, which adds a
105             C attribute to all HTML links found in the filtered text.
106              
107             Through the use of the C option, you can specify URLs that are I
108             given a new C attribute. This can be used to set up a filter that
109             leaves internal links alone but that sets up external links to open in a new
110             browser window. C accepts a list of regular expressions, so you can
111             be as elaborate as you'd like.
112              
113             The C option specifies what target you'd like to give to links,
114             defaulting to "_blank".
115              
116             =head1 METHODS
117              
118             =over
119              
120             =item init()
121              
122             Initializes the template plugin.
123              
124             =item filter($text, $args, $conf)
125              
126             Filters the given text, and adds the "target" attribute to links.
127              
128             =back
129              
130             =head1 AUTHOR
131              
132             Graham TerMarsch (cpan@howlingfrog.com)
133              
134             =head1 COPYRIGHT
135              
136             Copyright (C) 2008, Graham TerMarsch. All Rights Reserved.
137              
138             This is free software; you can redistribute it and/or modify it under the same
139             terms as Perl itself.
140              
141             =head1 SEE ALSO
142              
143             L.
144              
145             =cut