create new tag
, view all tags

Development discussion for SablotronPlugin

The first release of the SablotronPlugin works but returns either Internal Server error or other cryptic messages if there are errors in either of the file inputs. Since these are caught at the Preview Changes screen just click on the Back button and fix it.

I am working on returning the error messages to the edit preview screen rather than to the log file and running into a problem. I can register an error handler in XML::Sablotron to capture and manipulate the error messages. I have this working in a standalone program but when I put the code into my TWiki plugin I get an error as if it were not receiving any input. I thought that the method just doesn't work in packages but I have created a standalone package and a program that calls it that returns the correct result.

So, I appear to be running into the limit of my understanding of Perl or TWiki. Everything is fine up to the line $sab->process($sit, 'arg:/template', 'arg:/input', 'arg:/output'); I have verified that the variables $xml and $xslText that feed arg:/template and arg:/input contain the proper information. But all I get is error 63, unknown encoding '' from my error handler. Can someone provide me with further insight? Problem found!

package TWiki::Plugins::SablotronPlugin;

use vars qw(
 $web $topic $user $installWeb $VERSION $debug
use XML::Sablotron;
my ($self, $processor, $code, $level, @fields, $error);

$VERSION = '1.001';

sub initPlugin {
 ( $topic, $web, $user, $installWeb ) = @_;

 # check for Plugins.pm versions
 if( $TWiki::Plugins::VERSION < 1 ) {
  &TWiki::Func::writeWarning( "Version mismatch between SablotronPlugin and Plugins.pm" );
  return 0;

 # Get plugin preferences, the variable defined by:          * Set EXAMPLE = ...
 $exampleCfgVar = &TWiki::Prefs::getPreferencesValue( "SABLOTRONPLUGIN_EXAMPLE" ) || "default";

 # Get plugin debug flag
 $debug = &TWiki::Func::getPreferencesFlag( "SABLOTRONPLUGIN_DEBUG" ) || 0;

 # Plugin correctly initialized
 &TWiki::Func::writeDebug( "- TWiki::Plugins::SablotronPlugin::initPlugin( $web.$topic ) is OK" ) if $debug;
 return 1;

sub commonTagsHandler {
### my ( $text, $topic, $web ) = @_;   # do not uncomment, use $_[0], $_[1]... instead

 &TWiki::Func::writeDebug( "- SablotronPlugin::commonTagsHandler( $_[2].$_[1] )" ) if $debug;

 # This is the place to define customized tags and variables
 # Called by sub handleCommonTags, after %INCLUDE:"..."%

 # do custom extension rule, like for example:
 # $_[0] =~ s/%XYZ%/&handleXyz()/geo;
 # $_[0] =~ s/%XYZ{(.*?)}%/&handleXyz($1)/geo;
 $_[0] =~ s/%XSLTRANSFORM{xsl="(.*?)",xml=(.*?)}%/&applySablotron($1, $2)/gseo;

sub applySablotron {
 my $xsl = $_[0];
 my $xml = $_[1];

 my $sab = new XML::Sablotron;
 my $sit = new XML::Sablotron::Situation;
 $sab->RegHandler(0, { MHMakeCode => \&myMHMakeCode,
  MHLog => \&myMHLog,
  MHError => \&myMHError });

 $xml =~ s/^\s+//; # trim leading white space
 $xml =~ s/\s+$//; # trim trailing white space

 #get the web name and the topic name
 my ($xslWeb, $xslTopic) = getWebTopic( $xsl );
 #check if the topic exists
 if (&TWiki::Func::topicExists($xslWeb, $xslTopic)) {
  #the topic does exist so read from the file
  my ($xslMeta, $xslText) = &TWiki::Func::readTopic($xslWeb, $xslTopic);
  $xslText =~ s/^\s+//; # trim leading white space
  $xslText =~ s/\s+$//; # trim trailing white space
Here $xslText goes out of scope
 } else {
  return "XSL source: ".$xsl." does not exist.";

 $sab->addArg($sit, 'input', $xml);
Here I attempt to use $xslText again, since I am not "use strict" I don't get warned that this is an undefined variable
 $sab->addArg($sit, 'template', $xslText);
 $error = 0;
 $sab->process($sit, 'arg:/template', 'arg:/input', 'arg:/output');
 return "SablotronError:\nlevel:$level\n".(join("\n",@fields,"")) if $error;
 return $sab->getResultArg('arg:/output');

sub myMHMakeCode {
 my ($self, $processor, $severity, $facility, $code) = @_;
 return $code if $severity; # I can deal with internal numbers

sub myMHLog {
 ($self, $processor, $code, $level, @fields) = @_;
 $error = 1 if $level > 1;

sub myMHError {
 ($self, $processor, $code, $level, @fields) = @_;
 $error = 1;

# get the web and topic name from fully qualified topic name
sub getWebTopic {
 return &TWiki::Store::getWebTopic( @_ );

-- CharlieReitsma - 15 Mar 2002

I just wanted to say that it is really nice to see the work we did with the XmlXslPlugin carried forward!

-- MartinCleaver - 15 Mar 2002

Is it possible to include the XML code from a file or a URL instead?

-- ArneJorgensen - 17 Feb 2003

checked .zip into CVS

-- WillNorris - 19 Jul 2005

I had to make the following change to make this work on the current version of TWiki

diff SablotronPlugin.pm.orig SablotronPlugin.pm
<  my ($xslWeb, $xslTopic) = getWebTopic( $xsl );
>  my ($xslWeb, $xslTopic) = ( "", $xsl );
<  return &TWiki::Store::getWebTopic( @_ );
>  return &TWiki::Store::normalizeWebTopicName( @_ );
-- LodeLeroy - 12 Aug 2005

Yes, I used a function other than those listed in TWiki::Func. I have removed the use of the TWiki::Store function in version 1.002.

-- CharlieReitsma - 17 Aug 2005

It would be nice if the source xml could come from an attachment to the topic instead of the topic itself.

-- NicholasSushkin - 01 Apr 2006

Edit | Attach | Watch | Print version | History: r10 < r9 < r8 < r7 < r6 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r10 - 2006-04-02 - PeterThoeny
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.