aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet
diff options
context:
space:
mode:
authorMatthew Somerville <matthew@mysociety.org>2016-09-16 17:58:16 +0100
committerMatthew Somerville <matthew-github@dracos.co.uk>2016-09-20 17:18:35 +0100
commit148d702917f54327f82e49fe605e5a0d9f2e31ca (patch)
tree465574714026090bda8301a655a1176c5323d426 /perllib/FixMyStreet
parent99abfad00e301e3a261820db0d54470d9c4ef10c (diff)
Use shared Template base for all templates.
Reduce some duplicated code, and as a side effect gives HTML emails our internal html_para filter, allowing single line returns in contact form submissions.
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r--perllib/FixMyStreet/App/View/Email.pm29
-rw-r--r--perllib/FixMyStreet/App/View/Web.pm71
-rw-r--r--perllib/FixMyStreet/Email.pm5
-rw-r--r--perllib/FixMyStreet/Template.pm122
4 files changed, 132 insertions, 95 deletions
diff --git a/perllib/FixMyStreet/App/View/Email.pm b/perllib/FixMyStreet/App/View/Email.pm
index 6073ee814..6d83d3ddf 100644
--- a/perllib/FixMyStreet/App/View/Email.pm
+++ b/perllib/FixMyStreet/App/View/Email.pm
@@ -4,17 +4,14 @@ use base 'Catalyst::View::TT';
use strict;
use warnings;
-use mySociety::Locale;
use FixMyStreet;
+use FixMyStreet::Template;
__PACKAGE__->config(
+ CLASS => 'FixMyStreet::Template',
TEMPLATE_EXTENSION => '.txt',
- INCLUDE_PATH => [ #
- FixMyStreet->path_to( 'templates', 'email', 'default' ),
- ],
- ENCODING => 'utf8',
- render_die => 1,
- expose_methods => ['loc', 'file_exists'],
+ INCLUDE_PATH => [ FixMyStreet->path_to( 'templates', 'email', 'default' ) ],
+ render_die => 1,
);
=head1 NAME
@@ -27,23 +24,5 @@ TT View for FixMyStreet::App.
=cut
-=head2 loc
-
- [% loc('Some text to localize') %]
-
-Passes the text to the localisation engine for translations.
-
-=cut
-
-sub loc {
- my ( $self, $c, @args ) = @_;
- return _(@args);
-}
-
-sub file_exists {
- my ( $self, $c, @args ) = @_;
- -e FixMyStreet->path_to(@args);
-}
-
1;
diff --git a/perllib/FixMyStreet/App/View/Web.pm b/perllib/FixMyStreet/App/View/Web.pm
index 2a3948381..ae06181c8 100644
--- a/perllib/FixMyStreet/App/View/Web.pm
+++ b/perllib/FixMyStreet/App/View/Web.pm
@@ -4,26 +4,24 @@ use base 'Catalyst::View::TT';
use strict;
use warnings;
-use mySociety::Locale;
use FixMyStreet;
+use FixMyStreet::Template;
use Utils;
__PACKAGE__->config(
+ CLASS => 'FixMyStreet::Template',
TEMPLATE_EXTENSION => '.html',
INCLUDE_PATH => [
FixMyStreet->path_to( 'templates', 'web', 'base' ),
],
- ENCODING => 'utf8',
render_die => 1,
expose_methods => [
- 'loc', 'nget', 'tprintf', 'prettify_dt',
+ 'tprintf', 'prettify_dt',
'version', 'decode',
],
FILTERS => {
add_links => \&add_links,
escape_js => \&escape_js,
- html => \&html_filter,
- html_para => \&html_paragraph,
},
COMPILE_EXT => '.ttc',
STAT_TTL => FixMyStreet->config('STAGING_SITE') ? 1 : 86400,
@@ -48,32 +46,6 @@ sub _rendering_error {
return 0;
}
-=head2 loc
-
- [% loc('Some text to localize', 'Optional comment for translator') %]
-
-Passes the text to the localisation engine for translations.
-
-=cut
-
-sub loc {
- my ( $self, $c, $msgid ) = @_;
- return _($msgid);
-}
-
-=head2 nget
-
- [% nget( 'singular', 'plural', $number ) %]
-
-Use first or second srting depending on the number.
-
-=cut
-
-sub nget {
- my ( $self, $c, @args ) = @_;
- return mySociety::Locale::nget(@args);
-}
-
=head2 tprintf
[% tprintf( 'foo %s bar', 'insert' ) %]
@@ -115,7 +87,7 @@ Add some links to some text (and thus HTML-escapes the other text.
sub add_links {
my $text = shift;
$text =~ s/\r//g;
- $text = html_filter($text);
+ $text = FixMyStreet::Template::html_filter($text);
$text =~ s{(https?://)([^\s]+)}{"<a href=\"$1$2\">$1" . _space_slash($2) . '</a>'}ge;
return $text;
}
@@ -148,41 +120,6 @@ sub escape_js {
return $text;
}
-=head2 html_filter
-
-Same as Template Toolkit's html_filter, but escapes ' too, as we don't (and
-shouldn't have to) know whether we'll be used inbetween single or double
-quotes.
-
-=cut
-
-sub html_filter {
- my $text = shift;
- for ($text) {
- s/&/&amp;/g;
- s/</&lt;/g;
- s/>/&gt;/g;
- s/"/&quot;/g;
- s/'/&#39;/g;
- }
- return $text;
-}
-
-=head2 html_paragraph
-
-Same as Template Toolkit's html_paragraph, but converts single newlines
-into <br>s too.
-
-=cut
-
-sub html_paragraph {
- my $text = shift;
- my @paras = split(/(?:\r?\n){2,}/, $text);
- s/\r?\n/<br>\n/ for @paras;
- $text = "<p>\n" . join("\n</p>\n\n<p>\n", @paras) . "</p>\n";
- return $text;
-}
-
my %version_hash;
sub version {
my ( $self, $c, $file ) = @_;
diff --git a/perllib/FixMyStreet/Email.pm b/perllib/FixMyStreet/Email.pm
index 34ac1514c..7d81c9dc5 100644
--- a/perllib/FixMyStreet/Email.pm
+++ b/perllib/FixMyStreet/Email.pm
@@ -10,7 +10,7 @@ use Email::MIME;
use Encode;
use File::Spec;
use POSIX qw();
-use Template;
+use FixMyStreet::Template;
use Digest::HMAC_SHA1 qw(hmac_sha1_hex);
use mySociety::Locale;
use mySociety::Random qw(random_bytes);
@@ -162,8 +162,7 @@ sub send_cron {
my $html_template = get_html_template($template, @include_path);
push @include_path, FixMyStreet->path_to( 'templates', 'email', 'default' );
- my $tt = Template->new({
- ENCODING => 'utf8',
+ my $tt = FixMyStreet::Template->new({
INCLUDE_PATH => \@include_path,
});
$vars->{signature} = _render_template($tt, 'signature.txt', $vars);
diff --git a/perllib/FixMyStreet/Template.pm b/perllib/FixMyStreet/Template.pm
new file mode 100644
index 000000000..f41d11b69
--- /dev/null
+++ b/perllib/FixMyStreet/Template.pm
@@ -0,0 +1,122 @@
+package FixMyStreet::Template;
+use parent Template;
+
+use strict;
+use warnings;
+use FixMyStreet;
+use mySociety::Locale;
+use Attribute::Handlers;
+
+my %FILTERS;
+my %SUBS;
+
+# HASH is where we want to store the thing, either FILTERS or SUBS. SYMBOL is a
+# symbol table ref, where NAME then returns its name (perlref has the gory
+# details). FN is a ref to the function. DATA is an arrayref of any passed in
+# arguments.
+
+sub add_attr {
+ my ($hash, $symbol, $fn, $data) = @_;
+ my $name = $data ? $data->[0] : *{$symbol}{NAME};
+ $hash->{$name} = $fn;
+}
+
+# Create two attributes, Filter and Fn, which you apply to a function to turn
+# them into a template filter or function. You can optionally provide an argument
+# name for what to call the thing in the template if it's not the same as the
+# function name. They're called at the BEGIN stage rather than the default CHECK
+# as this code might be imported by an eval.
+
+sub Filter : ATTR(CODE,BEGIN) {
+ add_attr(\%FILTERS, $_[1], $_[2], $_[4]);
+}
+
+sub Fn : ATTR(CODE,BEGIN) {
+ add_attr(\%SUBS, $_[1], $_[2], $_[4]);
+}
+
+sub new {
+ my ($class, $config) = @_;
+ $config->{FILTERS}->{$_} = $FILTERS{$_} foreach keys %FILTERS;
+ $config->{ENCODING} = 'utf8';
+ $class->SUPER::new($config);
+}
+
+sub process {
+ my ($class, $template, $vars, $output, %options) = @_;
+ $vars->{$_} = $SUBS{$_} foreach keys %SUBS;
+ $class->SUPER::process($template, $vars, $output, %options);
+}
+
+=head2 loc
+
+ [% loc('Some text to localize', 'Optional comment for translator') %]
+
+Passes the text to the localisation engine for translations.
+
+=cut
+
+sub loc : Fn {
+ return _(@_);
+}
+
+=head2 nget
+
+ [% nget( 'singular', 'plural', $number ) %]
+
+Use first or second string depending on the number.
+
+=cut
+
+sub nget : Fn {
+ return mySociety::Locale::nget(@_);
+}
+
+=head2 file_exists
+
+ [% file_exists("web/cobrands/$cobrand/image.png") %]
+
+Checks to see if a file exists, relative to the codebase root.
+
+=cut
+
+sub file_exists : Fn {
+ -e FixMyStreet->path_to(@_);
+}
+
+=head2 html_filter
+
+Same as Template Toolkit's html_filter, but escapes ' too, as we don't (and
+shouldn't have to) know whether we'll be used inbetween single or double
+quotes.
+
+=cut
+
+sub html_filter : Filter('html') {
+ my $text = shift;
+ for ($text) {
+ s/&/&amp;/g;
+ s/</&lt;/g;
+ s/>/&gt;/g;
+ s/"/&quot;/g;
+ s/'/&#39;/g;
+ }
+ return $text;
+}
+
+=head2 html_paragraph
+
+Same as Template Toolkit's html_paragraph, but converts single newlines
+into <br>s too.
+
+=cut
+
+sub html_paragraph : Filter('html_para') {
+ my $text = shift;
+ my @paras = split(/(?:\r?\n){2,}/, $text);
+ s/\r?\n/<br>\n/ for @paras;
+ $text = "<p>\n" . join("\n</p>\n\n<p>\n", @paras) . "</p>\n";
+ return $text;
+}
+
+1;