Subject: | patch to add a render() method |
Hi,
as i wanted to use the module also to render various XSL templates for
other uses than putting them out directly to the user i've implemented a
render() method.
It works like what Catalyst::View::TT does.
Besides the code itself i also added the corresponding tests to check
for the new functionality. The other tests pass to of course.
Would be nice to see something like that merged upstream.
Kind regards,
Simon
Subject: | Catalyst-View-XSLT_render-support.diff |
Index: t/lib/TestApp/root/testRender.xsl
===================================================================
--- t/lib/TestApp/root/testRender.xsl (revision 0)
+++ t/lib/TestApp/root/testRender.xsl (revision 0)
@@ -0,0 +1,11 @@
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:output method="text" />
+
+ <xsl:template match="/">
+ <xsl:value-of select="dummy-root" />
+ </xsl:template>
+
+</xsl:stylesheet>
Index: t/lib/TestApp.pm
===================================================================
--- t/lib/TestApp.pm (revision 8506)
+++ t/lib/TestApp.pm (working copy)
@@ -71,6 +71,16 @@ sub testNoXSLT : Local {
$c->stash->{message} = $message;
}
+sub testRender : Local {
+ my ($self, $c) = @_;
+
+ my $message = $c->request->param('message') || $c->config->{default_message};
+
+ my $out = $c->view('XSLT')->render($c, $c->req->param('template'), {xml => "<dummy-root>$message</dummy-root>"});
+
+ $c->stash->{xml} = "<dummy-root>$out</dummy-root>";
+}
+
sub end : Private {
my ($self, $c) = @_;
Index: t/08testRender.t
===================================================================
--- t/08testRender.t (revision 0)
+++ t/08testRender.t (revision 0)
@@ -0,0 +1,21 @@
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+use lib "$FindBin::Bin/lib";
+
+use_ok('Catalyst::Test', 'TestApp');
+
+my $view = 'XML::LibXSLT';
+
+my $response;
+ok(($response = request("/testRender?view=$view&template=testRender.xsl"))->is_success, 'request ok');
+is($response->content, TestApp->config->{default_message}, 'message ok');
+
+my $message = scalar localtime;
+my $xml = "<dummy-root>$message</dummy-root>";
+ok(($response = request("/testRender?view=$view&message=$message&template=testRender.xsl"))->is_success, 'request with message ok');
+is($response->content, $message, 'message ok');
+
Index: lib/Catalyst/View/XSLT.pm
===================================================================
--- lib/Catalyst/View/XSLT.pm (revision 8506)
+++ lib/Catalyst/View/XSLT.pm (working copy)
@@ -208,11 +208,113 @@ sub new {
}
#
+=item render
+Renders the template specified via C<< $template >>.
+The template variables are set to C<%$args> if $args is a hashref, or
+C<< $c->stash >> otherwise.
+
+=cut
+
+sub render {
+ my ( $self, $c, $template, $args ) = @_;
+
+ my $output;
+
+ unless ( -e $template) {
+ my ($tmplFullPath, $error) = $self->_searchInIncPath($c, $template);
+
+ if (defined $error) {
+ $c->error("Template [$template] does not exists in include path");
+ return 0;
+ } else {
+ $template = $tmplFullPath;
+ }
+ }
+
+ my $vars = {
+ (ref $args eq 'HASH' ? %$args : %{ $c->stash() }),
+ };
+
+ unless (exists $vars->{ xml } && defined $vars->{ xml }) {
+ $c->log->error( 'No xml provided' );
+ return undef;
+ }
+
+ my $xml = $vars->{xml};
+
+ # if xml is not string (therefore is a file (what about file descriptors ?!))
+ # and is not existsting in the file system
+ if ($xml !~ m/\</ && ! -e $xml) {
+ my ($xmlFullPath, $error) = $self->_searchInIncPath($c, $xml);
+
+ if (defined $error) {
+ $c->error("Template [$template] does not exists in include path");
+ return undef;
+ } else {
+ $vars->{xml} = $xmlFullPath;
+ }
+ }
+
+ $c->log->debug( qq{Rendering template "$template"} ) if $c->debug;
+
+ if ($isMS) {
+ my $error = 'XSLT View for MS Windows is not yet implemented.';
+ $c->log->error($error);
+ $c->error($error);
+
+ return undef;
+ }
+ # elsif ($^O eq 'linux') {
+ else {
+
+ # add runtime register_function(s) from stash
+ if (exists $vars->{additional_register_function} &&
+ ref($vars->{additional_register_function}) eq 'ARRAY' ) {
+ my @additional_subrefs = @{ $vars->{additional_register_function} };
+ delete $vars->{additional_register_function};
+
+ unless (ref($self->{CONFIG}->{LibXSLT}->{register_function}) eq 'ARRAY') {
+ $self->{CONFIG}->{LibXSLT}->{register_function} = [];
+ }
+
+ unshift(
+ @{ $self->{CONFIG}->{LibXSLT}->{register_function} },
+ @additional_subrefs
+ );
+ }
+
+ my $processor = undef;
+ eval {
+ $processor = $self->_getProcessor()->new($c, $self->{CONFIG}->{LibXSLT});
+ };
+
+ if ($@ && (! defined $processor)) {
+ $c->error("Could not instanciate XSLT processor: $@");
+ return undef;
+ } elsif (scalar @{$c->error}) {
+ return undef;
+ }
+
+ $c->log->debug("Processing...") if $c->debug;
+ my ($output, $error) = $processor->process($template, $vars);
+
+ if ($error) {
+ chomp $error;
+ $error = qq{Couldn't render template "$template". Error: "$error"};
+ $c->error($error);
+ return undef;
+ }
+ else {
+ return $output;
+ }
+ }
+}
+
=item process
Renders the template specified in C<< $c->stash->{template} >> or C<<
-$c->action >>.
+$c->action >>. Calls C<< render >> to perform actual rendering.
Template params are set up from the contents of C<< $c->stash >>.
Output is stored in C<< $c->response->body >>.
@@ -224,8 +326,7 @@ sub process {
my $template = undef;
if (exists $c->stash->{template} && defined $c->stash->{template}) {
- $template = $c->stash->{template};
- delete $c->stash->{template};
+ $template = delete $c->stash->{template};
} else {
my $actionName = $c->action;
my $ext = $self->{CONFIG}->{'TEMPLATE_EXTENSION'};
@@ -240,95 +341,10 @@ sub process {
return 0;
}
- unless (exists $c->stash->{ xml } && defined $c->stash->{ xml }) {
- $c->log->error( 'No xml provided' );
- return 0;
- }
+ my $output = $self->render($c, $template);
- unless ( -e $template) {
- my ($tmplFullPath, $error) = $self->_searchInIncPath($c, $template);
-
- if (defined $error) {
- $c->error("Template [$template] does not exists in include path");
- return 0;
- } else {
- $template = $tmplFullPath;
- }
- }
+ $c->response->body($output);
-
- my $xml = $c->stash->{xml};
-
- # if xml is not string (therefore is a file (what about file descriptors ?!))
- # and is not existsting in the file system
- if ($xml !~ m/\</ && ! -e $xml) {
-
- my ($xmlFullPath, $error) = $self->_searchInIncPath($c, $xml);
-
- if (defined $error) {
- $c->error("Template [$template] does not exists in include path");
- return 0;
- } else {
- $c->stash->{xml} = $xmlFullPath;
- }
- }
-
- $c->log->debug( qq{Rendering template "$template"} ) if $c->debug;
-
- if ($isMS) {
-
- my $error = 'XSLT View for MS Windows is not yet implemented.';
- $c->log->error($error);
- $c->error($error);
- return 0;
-
- }
- # elsif ($^O eq 'linux') {
- else {
-
- # add runtime register_function(s) from stash
- if (exists $c->stash->{additional_register_function} &&
- ref($c->stash->{additional_register_function}) eq 'ARRAY' ) {
- my @additional_subrefs = @{ $c->stash->{additional_register_function} };
- delete $c->stash->{additional_register_function};
-
- unless (ref($self->{CONFIG}->{LibXSLT}->{register_function}) eq 'ARRAY') {
- $self->{CONFIG}->{LibXSLT}->{register_function} = [];
- }
-
- unshift(
- @{ $self->{CONFIG}->{LibXSLT}->{register_function} },
- @additional_subrefs
- );
- }
-
- my $processor = undef;
- eval {
- $processor = $self->_getProcessor()->new($c, $self->{CONFIG}->{LibXSLT});
- };
-
- if ($@ && (! defined $processor)) {
- $c->error("Could not instanciate XSLT processor: $@");
- return 0;
- } elsif (scalar @{$c->error}) {
- return 0;
- }
-
- $c->log->debug("Processing...") if $c->debug;
- my ($output, $error) = $processor->process($c, $template);
-
- if ($error) {
- chomp $error;
- $error = qq{Couldn't render template "$template". Error: "$error"};
- $c->error($error);
- return 0;
- }
- else {
- $c->response->body($output);
- }
-
- }
-
return 1;
}
Index: lib/Catalyst/View/XSLT/XML/LibXSLT.pm
===================================================================
--- lib/Catalyst/View/XSLT/XML/LibXSLT.pm (revision 8506)
+++ lib/Catalyst/View/XSLT/XML/LibXSLT.pm (working copy)
@@ -76,7 +76,7 @@ sub new
sub process {
- my ($self, $c, $template) = @_;
+ my ($self, $template, $args) = @_;
my ($result, $error) = ('', undef);
@@ -87,8 +87,7 @@ sub process {
my ($xmlDocument, $xsltStylesheet);
- my $xml = $c->stash->{xml};
- delete $c->stash->{xml};
+ my $xml = delete $args->{xml};
if ($xml =~ /\</) {
$xmlDocument = $xmlParser->parse_string($xml);
@@ -104,7 +103,7 @@ sub process {
my $xsltTransformer = $xsltProcessor->parse_stylesheet($xsltStylesheet);
- my %params = XML::LibXSLT::xpath_to_string( %{$c->stash} );
+ my %params = XML::LibXSLT::xpath_to_string( %{$args} );
my $results = $xsltTransformer->transform($xmlDocument, %params);