1 # This module is part of debbugs, and is released
2 # under the terms of the GPL version 2, or any later
3 # version at your option.
4 # See the file README and COPYING for more information.
6 # Copyright 2007 by Don Armstrong <don@donarmstrong.com>.
15 Debbugs::Text -- General routines for text templates
19 use Debbugs::Text qw(:templates);
20 print fill_in_template(template => 'cgi/foo');
24 This module is a replacement for parts of common.pl; subroutines in
25 common.pl will be gradually phased out and replaced with equivalent
26 (or better) functionality here.
35 use vars qw($DEBUG $VERSION @EXPORT_OK %EXPORT_TAGS @EXPORT @ISA);
36 use Exporter qw(import);
40 $DEBUG = 0 unless defined $DEBUG;
43 %EXPORT_TAGS = (templates => [qw(fill_in_template)],
46 Exporter::export_ok_tags(qw(templates));
47 $EXPORT_TAGS{all} = [@EXPORT_OK];
50 use Text::Xslate qw(html_builder);
52 use Storable qw(dclone);
54 use Debbugs::Config qw(:config);
56 use Params::Validate qw(:types validate_with);
61 ### for %text_xslate_functions
63 use Debbugs::CGI qw(html_escape);
65 use Debbugs::Common qw(make_list);
69 our %filled_templates;
73 sub __output_select_options {
74 my ($options,$value) = @_;
75 my @options = @{$options};
78 my ($o_value) = shift @options;
86 my $name = shift @options;
88 if (defined $value and $o_value eq $value) {
89 $selected = ' selected';
91 $output .= q(<option value=").html_escape($o_value).qq("$selected>).
92 html_escape($name).qq(</option>\n);
97 sub __text_xslate_functions {
99 {gm_strftime => sub {POSIX::strftime($_[0],gmtime)},
100 package_links => html_builder(\&Debbugs::CGI::package_links),
101 bug_links => html_builder(\&Debbugs::CGI::bug_links),
102 looks_like_number => \&Scalar::Util::looks_like_number,
103 isstrongseverity => \&Debbugs::Status::isstrongseverity,
104 secs_to_english => \&Debbugs::Common::secs_to_english,
105 maybelink => \&Debbugs::CGI::maybelink,
106 # add in a few utility routines
107 duplicate_array => sub {
108 my @r = map {($_,$_)} make_list(@{$_[0]});
111 output_select_options => html_builder(\&__output_select_options),
112 make_list => \&make_list,
115 sub __text_xslate_functions_text {
120 $config{cgi_domain}.'/'.
121 Debbugs::CGI::bug_links(bug=>$_[0],
130 ### this function removes leading spaces from line-start code strings and spaces
131 ### before <:- and spaces after -:>
132 sub __html_template_prefilter {
134 $text =~ s/^\s+:/:/mg;
135 $text =~ s/((?:^:[^\n]*\n)?)\s*(<:-)/$1$2/mg;
136 $text =~ s/(-:>)\s+(^:|)/$1.(length($2)?"\n$2":'')/emg;
141 =head2 fill_in_template
143 print fill_in_template(template => 'template_name',
144 variables => \%variables,
148 Reads a template from disk (if it hasn't already been read in) andf
149 ills the template in.
153 sub fill_in_template{
154 my %param = validate_with(params => \@_,
155 spec => {template => SCALAR,
156 variables => {type => HASHREF,
159 language => {type => SCALAR,
162 output => {type => HANDLE,
165 hole_var => {type => HASHREF,
168 output_type => {type => SCALAR,
174 my $output_type = $param{output_type};
175 my $language = $param{language};
176 my $template = $param{template};
177 $template .= '.tx' unless $template =~ /\.tx$/;
179 if (not exists $tt_templates{$output_type}{$language} or
180 not defined $tt_templates{$output_type}{$language}
182 $tt_templates{$output_type}{$language} =
183 Text::Xslate->new(# cache in template_cache or temp directory
184 cache_dir => $config{template_cache} //
185 File::Temp::tempdir(CLEANUP => 1),
186 # default to the language, but fallback to en_US
187 path => [$config{template_dir}.'/'.$language.'/',
188 $config{template_dir}.'/en_US/',
191 ## use html or text specific functions
193 ($output_type eq 'html' ? __text_xslate_functions() :
194 __text_xslate_functions_text()),
196 module => ['Text::Xslate::Bridge::Star',
197 'Debbugs::Text::XslateBridge',
199 type => $output_type,
200 ## use the html-specific pre_process_handler
201 $output_type eq 'html'?
202 (pre_process_handler => \&__html_template_prefilter):(),
204 or die "Unable to create Text::Xslate";
206 $tt = $tt_templates{$output_type}{$language};
208 $tt->render($template,
210 %{$param{variables}//{}},
213 if (exists $param{output}) {
214 print {$param{output}} $ret;