diff options
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r-- | perllib/FixMyStreet/App/View/Email.pm | 29 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/View/Web.pm | 71 | ||||
-rw-r--r-- | perllib/FixMyStreet/Email.pm | 5 | ||||
-rw-r--r-- | perllib/FixMyStreet/Template.pm | 122 |
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/&/&/g; - s/</</g; - s/>/>/g; - s/"/"/g; - s/'/'/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/&/&/g; + s/</</g; + s/>/>/g; + s/"/"/g; + s/'/'/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; |