summaryrefslogtreecommitdiff
path: root/LedgerSMB/Template.pm
blob: 1b59f66476c787e714c2f59e429df8ed6a2acca9 (plain)
  1. =head1 NAME
  2. LedgerSMB::Template - Template support module for LedgerSMB
  3. =head1 SYNOPSIS
  4. This module renders templates.
  5. =head1 METHODS
  6. =over
  7. =item new(user => \%myconfig, template => $string, format => $string, [locale => $locale] [language => $string], [include_path => $path], [no_auto_output => $bool], [method => $string], [no_escape => $bool], [debug => $bool] );
  8. This command instantiates a new template:
  9. =over
  10. =item template
  11. The name of the template file to be processed.
  12. =item format
  13. The format to be used. Currently HTML, PS, PDF, TXT and CSV are supported.
  14. =item locale (optional)
  15. The locale object to use for regular gettext lookups. Having this option adds
  16. the text function to the usable list for the templates. Has no effect on the
  17. gettext function.
  18. =item language (optional)
  19. The language for template selection.
  20. =item include_path (optional)
  21. Overrides the template directory. Used with user interface templates.
  22. =item no_auto_output (optional)
  23. Disables the automatic output of rendered templates.
  24. =item no_escape (optional)
  25. Disables escaping on the template variables.
  26. =item debug (optional)
  27. Enables template debugging.
  28. With the TT-based renderers, HTML, PS, PDF, TXT, and CSV, the portion of the
  29. template to get debugging messages is to be surrounded by
  30. <?lsmb DEBUG format 'foo' ?> statements. Example:
  31. <tr><td colspan="<?lsmb columns.size ?>"></td></tr>
  32. <tr class="listheading">
  33. <?lsmb FOREACH column IN columns ?>
  34. <?lsmb DEBUG format '$file line $line : [% $text %]' ?>
  35. <th class="listtop"><?lsmb heading.$column ?></th>
  36. <?lsmb DEBUG format '' ?>
  37. <?lsmb END ?>
  38. </tr>
  39. =item method/media (optional)
  40. The output method to use, defaults to HTTP. Media is a synonym for method
  41. =back
  42. =item render($hashref)
  43. This command renders the template and writes the result to standard output.
  44. Currently email and server-side printing are not supported.
  45. =item output
  46. This function outputs the rendered file in an appropriate manner.
  47. =item my $bool = _valid_language()
  48. This command checks for valid langages. Returns 1 if the language is valid,
  49. 0 if it is not.
  50. =back
  51. =head1 Copyright 2007, The LedgerSMB Core Team
  52. This file is licensed under the GNU General Public License version 2, or at your
  53. option any later version. A copy of the license should have been included with
  54. your software.
  55. =cut
  56. package LedgerSMB::Template;
  57. use Error qw(:try);
  58. use LedgerSMB::Sysconfig;
  59. use LedgerSMB::Mailer;
  60. sub new {
  61. my $class = shift;
  62. my $self = {};
  63. my %args = @_;
  64. $self->{myconfig} = $args{user};
  65. $self->{template} = $args{template};
  66. $self->{format} = $args{format};
  67. $self->{format} = 'PS' if lc $self->{format} eq 'postscript';
  68. $self->{language} = $args{language};
  69. $self->{no_escape} = $args{no_escape};
  70. $self->{debug} = $args{debug};
  71. if ($args{outputfile}) {
  72. $self->{outputfile} =
  73. "${LedgerSMB::Sysconfig::tempdir}/$args{outputfile}";
  74. } else {
  75. $self->{outputfile} =
  76. "${LedgerSMB::Sysconfig::tempdir}/$args{template}-output-$$";
  77. }
  78. $self->{include_path} = $args{path};
  79. $self->{locale} = $args{locale};
  80. $self->{noauto} = $args{noauto};
  81. $self->{method} = $args{method};
  82. $self->{method} ||= $args{media};
  83. bless $self, $class;
  84. if (!$self->{include_path}){
  85. $self->{include_path} = $self->{'myconfig'}->{'templates'};
  86. if (defined $self->{language}){
  87. if (!$self->_valid_language){
  88. throw Error::Simple 'Invalid language';
  89. return undef;
  90. }
  91. $self->{include_path} = "$self->{'include_path'}"
  92. ."/$self->{language}"
  93. .";$self->{'include_path'}"
  94. }
  95. }
  96. return $self;
  97. }
  98. sub _valid_language {
  99. my $self = shift;
  100. if ($self->{language} =~ m#(/|\\|:|\.\.|^\.)#){
  101. return 0;
  102. }
  103. return 1;
  104. }
  105. sub render {
  106. my $self = shift;
  107. my $vars = shift;
  108. my $format = "LedgerSMB::Template::$self->{format}";
  109. eval "require $format";
  110. if ($@) {
  111. throw Error::Simple $@;
  112. }
  113. my $cleanvars;
  114. if ($self->{no_escape}) {
  115. $cleanvars = $vars;
  116. } else {
  117. $cleanvars = $format->can('preprocess')->($vars);
  118. }
  119. if (UNIVERSAL::isa($self->{locale}, 'LedgerSMB::Locale')){
  120. $cleanvars->{text} = sub { return $self->{locale}->text(@_)};
  121. }
  122. $format->can('process')->($self, $cleanvars);
  123. #return $format->can('postprocess')->($self);
  124. my $post = $format->can('postprocess')->($self);
  125. if (!$self->{'noauto'}) {
  126. $self->output;
  127. }
  128. return $post;
  129. }
  130. sub output {
  131. my $self = shift;
  132. my %args = @_;
  133. my $method = $self->{method} || $args{method} || $args{media};
  134. if ('email' eq lc $method) {
  135. $self->_email_output;
  136. } elsif ('print' eq lc $method) {
  137. $self->_lpr_output;
  138. } else {
  139. $self->_http_output;
  140. }
  141. }
  142. sub _http_output {
  143. my $self = shift;
  144. my $FH;
  145. if ($self->{mimetype} =~ /^text/) {
  146. print "Content-Type: $self->{mimetype}; charset=utf-8\n\n";
  147. } else {
  148. print "Content-Type: $self->{mimetype}\n\n";
  149. }
  150. open($FH, '<:bytes', $self->{rendered}) or
  151. throw Error::Simple 'Unable to open rendered file';
  152. my $data;
  153. {
  154. local $/;
  155. $data = <$FH>;
  156. }
  157. close($FH);
  158. binmode STDOUT, ':bytes';
  159. print $data;
  160. binmode STDOUT, ':utf8';
  161. unlink($self->{rendered}) or
  162. throw Error::Simple 'Unable to delete output file';
  163. exit;
  164. }
  165. sub _email_output {
  166. my $self = shift;
  167. my $mail = new LedgerSMB::Mailer;
  168. #TODO stub
  169. }
  170. sub _lpr_output {
  171. my $self = shift;
  172. #TODO stub
  173. }
  174. 1;