1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
package FixMyStreet::Template::Variable;
use strict;
use warnings;
use FixMyStreet::Template;
sub op_factory {
my ($op) = @_;
return eval q|sub {
my ($self, $str) = @_;
if ( ref $str eq __PACKAGE__) {
return $self->{value} | . $op . q| $str->{value};
}
else {
return $self->{value} | . $op . q| $str;
}
}|;
}
use overload
'""' => \&html_encoded,
'.' => \&concat,
'.=' => \&concatequals,
'=' => \&clone,
'cmp' => op_factory('cmp'),
'eq' => op_factory('eq'),
'<=>' => op_factory('<=>'),
'==' => op_factory('=='),
'%' => op_factory('%'),
'+' => op_factory('+'),
'-' => op_factory('-'),
'*' => op_factory('*'),
'/' => op_factory('/'),
'**' => op_factory('**'),
'>>' => op_factory('>>'),
'<<' => op_factory('<<'),
;
sub new {
my ($class, $value) = @_;
my $self = bless { value => $value }, $class;
return $self;
}
sub plain {
my $self = shift;
return $self->{value};
}
sub html_encoded {
my $self = shift;
return FixMyStreet::Template::html_filter($self->{value});
}
sub concat {
my ($self, $str, $prefix) = @_;
# Special case where we're _not_ going to html_encode now now
return $self->clone() if not defined $str or $str eq '';
if ( $prefix ) {
return $str . $self->html_encoded();
}
else {
return $self->html_encoded() . $str;
}
}
sub concatequals {
my ($self, $str, $prefix) = @_;
if ( ref $str eq __PACKAGE__) {
$self->{value} .= $str->{value};
return $self;
}
else {
# Special case where we're _not_ going to html_encode now now
return $self->clone() if $str eq '';
# Fix Template::HTML::Variable issue with double output
my $ret = $self->html_encoded . $str;
$self->{value} .= $str;
return $ret;
}
}
sub clone {
my $self = shift;
my $clone = bless { %$self }, ref $self;
return $clone;
}
1;
__END__
=head1 NAME
FixMyStreet::Template::Variable - A "pretend" string that auto HTML encodes;
a copy of Template::HTML::Variable with a bugfix.
=head1 SYNOPSIS
use FixMyStreet::Template::Variable;
my $string = FixMyStreet::Template::Variable->new('< test & stuff >');
print $string, "\n";
# Produces output "< test & stuff >"
=head1 DESCRIPTION
This object provides a "pretend" string to use as part of the
FixMyStreet::Template extension.
It automatically stringifies to an HTML encoded version of what it was created
with, all the while trying to keep a sane state through string concatinations
etc.
=head1 FUNCTIONS
=head2 new()
Takes a single argument which is the string to set this variable to
=head2 plain()
Returns a non HTML-encoded version of the string (i.e. exactly what was passed
to the new() function
=head2 html_encoded()
Returns an HTML encoded version of the string (used by the stringify
overloads)
=head2 concat()
Implementation of overloaded . operator
=head2 concatequals()
Implementation of overloaded .= operator.
The original Template::HTML::Variable has a bug here, whereby it adds the new
string to its internal value, then returns the HTML encoded version of the
whole string with the new string concatenated again (unescaped).
=head2 clone()
Returns a clone of this variable. (used for the implementation of the
overloaded = operator).
=head2 op_factory()
Factory for generating operator overloading subs
=head1 AUTHOR
Martyn Smith, E<lt>msmith@cpan.orgE<gt>
Matthew Somerville, E<lt>matthew@mysociety.orgE<gt>
=head1 LICENSE
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
=cut
|