X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FPresenter.pm;h=44332bd91a666971e0ce3057039d62c6af61d7cd;hb=3782a90c336bc6c506f572e607c8526cb5e79ea3;hp=ec36c3b528b63bba94abcad7f12470bf4595362e;hpb=30c8e51b034338753f180118b67c96dc6b5e842f;p=kivitendo-erp.git diff --git a/SL/Presenter.pm b/SL/Presenter.pm index ec36c3b52..44332bd91 100644 --- a/SL/Presenter.pm +++ b/SL/Presenter.pm @@ -7,17 +7,14 @@ use parent qw(Rose::Object); use Carp; use Template; -use SL::Presenter::CustomerVendor; -use SL::Presenter::DeliveryOrder; -use SL::Presenter::EscapedText; -use SL::Presenter::Invoice; -use SL::Presenter::Order; -use SL::Presenter::Project; -use SL::Presenter::Record; +use SL::Presenter::EscapedText qw(is_escaped); + +use Rose::Object::MakeMethods::Generic ( + scalar => [ qw(need_reinit_widgets) ], +); sub get { - $::request->{presenter} ||= SL::Presenter->new; - return $::request->{presenter}; + return $::request->presenter; } sub render { @@ -25,17 +22,60 @@ sub render { my $template = shift; my ($options, %locals) = (@_ && ref($_[0])) ? @_ : ({ }, @_); - $options->{type} = lc($options->{type} || 'html'); + # Set defaults for all available options. + my %defaults = ( + type => 'html', + process => 1, + ); + $options->{$_} //= $defaults{$_} for keys %defaults; + $options->{type} = lc $options->{type}; + + # Check supplied options for validity. + foreach (keys %{ $options }) { + croak "Unsupported option: $_" unless $defaults{$_}; + } + + # Only certain types are supported. + croak "Unsupported type: " . $options->{type} unless $options->{type} =~ m/^(?:html|js|json|text)$/; + + # The "template" argument must be a string or a reference to one. + $template = ${ $template } if ((ref($template) || '') eq 'REF') && (ref(${ $template }) eq 'SL::Presenter::EscapedText'); + croak "Unsupported 'template' reference type: " . ref($template) if ref($template) && (ref($template) !~ m/^(?:SCALAR|SL::Presenter::EscapedText)$/); + # Look for the file given by $template if $template is not a reference. my $source; - if ($options->{inline}) { - $source = \$template; + if (!ref $template) { + my $webpages_path = $::request->layout->webpages_path; - } else { - $source = "templates/webpages/${template}." . $options->{type}; + my $ext = $options->{type} eq 'text' ? 'txt' : $options->{type}; + $source = "${webpages_path}/${template}.${ext}"; croak "Template file ${source} not found" unless -f $source; + + } elsif (ref($template) eq 'SCALAR') { + # Normal scalar reference: hand over to Template + $source = $template; + + } else { + # Instance of SL::Presenter::EscapedText. Get reference to its content. + $source = \$template->{text}; } + # If no processing is requested then return the content. + if (!$options->{process}) { + # If $template is a reference then don't try to read a file. + my $ref = ref $template; + return $template if $ref eq 'SL::Presenter::EscapedText'; + return is_escaped(${ $template }) if $ref eq 'SCALAR'; + + # Otherwise return the file's content. + my $file = IO::File->new($source, "r") || croak("Template file ${source} could not be read"); + my $content = do { local $/ = ''; <$file> }; + $file->close; + + return is_escaped($content); + } + + # Processing was requested. Set up all variables. my %params = ( %locals, AUTH => $::auth, FLASH => $::form->{FLASH}, @@ -52,39 +92,32 @@ sub render { my $parser = $self->get_template; $parser->process($source, \%params, \$output) || croak $parser->error; - return SL::Presenter::EscapedText->new(text => $output, is_escaped => 1); + return is_escaped($output); } sub get_template { my ($self) = @_; + my $webpages_path = $::request->layout->webpages_path; + + # Make locales.pl parse generic/exception.html, too: + # $::form->parse_html_template("generic/exception") $self->{template} ||= Template->new({ INTERPOLATE => 0, EVAL_PERL => 0, ABSOLUTE => 1, CACHE_SIZE => 0, PLUGIN_BASE => 'SL::Template::Plugin', - INCLUDE_PATH => '.:templates/webpages', + INCLUDE_PATH => ".:$webpages_path", COMPILE_EXT => '.tcc', COMPILE_DIR => $::lx_office_conf{paths}->{userspath} . '/templates-cache', - ERROR => 'templates/webpages/generic/exception.html', + ERROR => "${webpages_path}/generic/exception.html", + ENCODING => 'utf8', }) || croak; return $self->{template}; } -sub escape { - my ($self, $text) = @_; - - return SL::Presenter::EscapedText->new(text => $text); -} - -sub escaped_text { - my ($self, $text) = @_; - - return SL::Presenter::EscapedText->new(text => $text, is_escaped => 1); -} - 1; __END__ @@ -107,14 +140,15 @@ SL::Presenter - presentation layer class # Higher-level rendering of certain objects: use SL::DB::Customer; - my $linked_customer_name = $presenter->customer($customer, display => 'table-cell'); + my $linked_customer_name = $customer->presenter->customer(display => 'table-cell'); # Render a list of links to sales/purchase records: use SL::DB::Order; + use SL::Presenter::Record qw(grouped_record_list); my $quotation = SL::DB::Manager::Order->get_first(where => { quotation => 1 }); my $records = $quotation->linked_records(direction => 'to'); - my $html = $presenter->grouped_record_list($records); + my $html = grouped_record_list($records); =head1 CLASS FUNCTIONS @@ -147,32 +181,62 @@ controller. Therefore the presenter's L function does not use all of the parameters for controlling the output that the controller's function does. -What is rendered and how C<$template> is interpreted is determined by -the options I and I. +What is rendered and how C<$template> is interpreted is determined +both by C<$template>'s reference type and by the supplied options. -If C<< $options->{inline} >> is trueish then C<$template> is a string -containing the template code to interprete. +If C<$template> is a normal scalar (not a reference) then it is meant +to be a template file name relative to the C +directory. The file name to use is determined by the C option. -If C<< $options->{inline} >> is falsish then C<$template> is -interpreted as the name of a template file. It is prefixed with -"templates/webpages/" and postfixed with a file extension based on -C<< $options->{type} >>. C<< $options->{type} >> can be either C -or C and defaults to C. An exception will be thrown if that -file does not exist. +If C<$template> is a reference to a scalar then the referenced +scalar's content is used as the content to process. The C option +is not considered in this case. -The template itself has access to the following variables: +C<$template> can also be an instance of L +or a reference to such an instance. Both of these cases are handled +the same way as if C<$template> were a reference to a scalar: its +content is processed, and C is not considered. + +Other reference types, unknown options and unknown arguments to the +C option cause the function to L. + +The following options are available: + +=over 2 + +=item C + +The template type. Can be C (the default), C for JavaScript, +C for JSON and C for plain text content. Affects only the +extension that's added to the file name given with a non-reference +C<$template> argument. + +=item C + +If trueish (which is also the default) it causes the template/content +to be processed by the Template toolkit. Otherwise the +template/content is returned as-is. + +=back + +If template processing is requested then the template has access to +the following variables: =over 2 =item * C -- C<$::auth> +=item * C -- the flash instance (C<$::form-E{FLASH}>) + =item * C
-- C<$::form> +=item * C -- C<$::instance_conf> + =item * C -- C<$::locale> =item * C -- all parameters from C with the same name they appear in the file (first level is the -section, second the actual variable, e.g. C, +section, second the actual variable, e.g. C, C etc) =item * C -- C<$::lxdebug> @@ -181,6 +245,9 @@ C etc) =item * C -- the controller instance +=item * C -- the presenter instance the template is +rendered with + =item * All items from C<%locals> =back @@ -197,29 +264,15 @@ Example: Render a HTML template with a certain title and a few locals Example: Render a string and return its content for further processing by the calling function. - my $content = $presenter->render( - '[% USE JavaScript %][% JavaScript.replace_with("#someid", "js/something") %]', - { type => 'js', inline => 1 } - ); - -=item C - -Returns an HTML-escaped version of C<$text>. Instead of a string an -instance of the thin proxy-object L is -returned. - -It is safe to call C on an instance of -L. This is a no-op (the same instance will -be returned). + my $content = $presenter->render(\'[% USE JavaScript %][% JavaScript.replace_with("#someid", "js/something") %]'); -=item C +Example: Return the content of a JSON template file without processing +it at all: -Returns an instance of L. C<$text> is -assumed to be a string that has already been HTML-escaped. - -It is safe to call C on an instance of -L. This is a no-op (the same instance will -be returned). + my $template_content = $presenter->render( + 'customer/contact', + { type => 'json', process => 0 } + ); =item C