Diff for /loncom/interface/lonhelper.pm between versions 1.6 and 1.10

version 1.6, 2003/04/11 17:21:18 version 1.10, 2003/04/11 19:07:48
Line 30 Line 30
 # (.helper handler  # (.helper handler
 #  #
   
 # FIXME: Change register calls to register with the helper.  
 # Then have the helper reg and unreg the tags.  
 # This removes my concerns about breaking other code.  
   
 =pod  =pod
   
 =head1 lonhelper - HTML Helper framework for LON-CAPA  =head1 lonhelper - HTML Helper framework for LON-CAPA
Line 62  of the helper itself, such as "Parameter Line 58  of the helper itself, such as "Parameter
 =head2 State tags  =head2 State tags
   
 State tags are required to have an attribute "name", which is the symbolic  State tags are required to have an attribute "name", which is the symbolic
 name of the state and will not be directly seen by the user. The wizard is  name of the state and will not be directly seen by the user. The helper is
 required to have one state named "START", which is the state the wizard  required to have one state named "START", which is the state the helper
 will start with. By convention, this state should clearly describe what  will start with. By convention, this state should clearly describe what
 the helper will do for the user, and may also include the first information  the helper will do for the user, and may also include the first information
 entry the user needs to do for the helper.  entry the user needs to do for the helper.
Line 95  use Apache::Constants qw(:common); Line 91  use Apache::Constants qw(:common);
 use Apache::File;  use Apache::File;
 use Apache::lonxml;  use Apache::lonxml;
   
   # Register all the tags with the helper, so the helper can 
   # push and pop them
   
   my @helperTags;
   
   sub register {
       my ($namespace, @tags) = @_;
   
       for my $tag (@tags) {
           push @helperTags, [$namespace, $tag];
       }
   }
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper',       Apache::lonxml::register('Apache::lonhelper', 
                               ('helper', 'state'));                               ('helper'));
         register('Apache::lonhelper', ('state'));
 }  }
   
 # Since all wizards are only three levels deep (wizard tag, state tag,   # Since all helpers are only three levels deep (helper tag, state tag, 
 # substate type), it's easier and more readble to explicitly track   # substate type), it's easier and more readble to explicitly track 
 # those three things directly, rather then futz with the tag stack   # those three things directly, rather then futz with the tag stack 
 # every time.  # every time.
Line 145  sub handler { Line 155  sub handler {
     &Apache::lonxml::xmlparse($r, 'helper', $file);      &Apache::lonxml::xmlparse($r, 'helper', $file);
   
     $r->print($helper->display());      $r->print($helper->display());
     return OK;     return OK;
 }  }
   
 sub start_helper {  sub start_helper {
Line 154  sub start_helper { Line 164  sub start_helper {
     if ($target ne 'helper') {      if ($target ne 'helper') {
         return '';          return '';
     }      }
   
       for my $tagList (@helperTags) {
           Apache::lonxml::register($tagList->[0], $tagList->[1]);
       }
           
     $helper = Apache::lonhelper::helper->new($token->[2]{'title'});      $helper = Apache::lonhelper::helper->new($token->[2]{'title'});
     return '';      return '';
Line 165  sub end_helper { Line 179  sub end_helper {
     if ($target ne 'helper') {      if ($target ne 'helper') {
         return '';          return '';
     }      }
       
       for my $tagList (@helperTags) {
           Apache::lonxml::deregister($tagList->[0], $tagList->[1]);
       }
   
     return '';      return '';
 }  }
   
Line 265  sub new { Line 283  sub new {
     $self->{STATES} = {};      $self->{STATES} = {};
     $self->{DONE} = 0;      $self->{DONE} = 0;
   
       # Used by various helpers for various things; see lonparm.helper
       # for an example.
       $self->{DATA} = {};
   
     bless($self, $class);      bless($self, $class);
     return $self;      return $self;
 }  }
Line 546  the helper variables, like this: Line 568  the helper variables, like this:
 =cut  =cut
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper::element',      &Apache::lonhelper::register('Apache::lonhelper::element',
                               ('nextstate'));                                   ('nextstate'));
 }  }
   
 # Because we use the param hash, this is often a sufficent  # Because we use the param hash, this is often a sufficent
Line 637  transition directly to the state in the Line 659  transition directly to the state in the
    </message>     </message>
   
 This will display the HTML message and transition to the <nextstate> if  This will display the HTML message and transition to the <nextstate> if
 given. The HTML will be directly inserted into the wizard, so if you don't  given. The HTML will be directly inserted into the helper, so if you don't
 want text to run together, you'll need to manually wrap the <message_text>  want text to run together, you'll need to manually wrap the <message_text>
 in <p> tags, or whatever is appropriate for your HTML.  in <p> tags, or whatever is appropriate for your HTML.
   
Line 657  no strict; Line 679  no strict;
 use strict;  use strict;
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper::message',      &Apache::lonhelper::register('Apache::lonhelper::message',
                               ('message', 'message_text'));                                ('message'));
 }  }
   
 sub new {  sub new {
Line 668  sub new { Line 690  sub new {
   
 # CONSTRUCTION: Construct the message element from the XML  # CONSTRUCTION: Construct the message element from the XML
 sub start_message {  sub start_message {
     return '';  
 }  
   
 sub end_message {  
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
     if ($target ne 'helper') {      if ($target ne 'helper') {
         return '';          return '';
     }      }
     Apache::lonhelper::message->new();  
       $paramHash->{MESSAGE_TEXT} = &Apache::lonxml::get_all_text('/message',
                                                                  $parser);
   
       if (defined($token->[2]{'nextstate'})) {
           $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};
       }
     return '';      return '';
 }  }
   
 sub start_message_text {  sub end_message {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
     if ($target ne 'helper') {      if ($target ne 'helper') {
         return '';          return '';
     }      }
       Apache::lonhelper::message->new();
     $paramHash->{MESSAGE_TEXT} = &Apache::lonxml::get_all_text('/message_text',      return '';
                                                                $parser);  
 }  }
       
 sub end_message_text { return 1; }  
   
 sub render {  sub render {
     my $self = shift;      my $self = shift;
Line 772  You can mix and match methods of creatin Line 793  You can mix and match methods of creatin
 "push" onto the choice list, rather then wiping it out. (You can even   "push" onto the choice list, rather then wiping it out. (You can even 
 remove choices programmatically, but that would probably be bad form.)  remove choices programmatically, but that would probably be bad form.)
   
 FIXME: Document and implement <exec> and <condition> in the element package.  
   
 =cut  =cut
   
 no strict;  no strict;
Line 781  no strict; Line 800  no strict;
 use strict;  use strict;
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper::choices',      &Apache::lonhelper::register('Apache::lonhelper::choices',
                               ('choice', 'choices'));                                ('choice', 'choices'));
 }  }
   
Line 960  use strict; Line 979  use strict;
 use Time::localtime;  use Time::localtime;
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper::date',      &Apache::lonhelper::register('Apache::lonhelper::date',
                               ('date'));                                ('date'));
 }  }
   
Line 1182  no strict; Line 1201  no strict;
 use strict;  use strict;
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper::resource',      &Apache::lonhelper::register('Apache::lonhelper::resource',
                               ('resource', 'filterfunc',                                 ('resource', 'filterfunc', 
                                'choicefunc', 'valuefunc'));                                 'choicefunc', 'valuefunc'));
 }  }
Line 1363  use strict; Line 1382  use strict;
   
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper::student',      &Apache::lonhelper::register('Apache::lonhelper::student',
                               ('student'));                                ('student'));
 }  }
   
Line 1527  no strict; Line 1546  no strict;
 use strict;  use strict;
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::lonhelper::files',      &Apache::lonhelper::register('Apache::lonhelper::files',
                               ('files', 'filechoice', 'filefilter'));                                   ('files', 'filechoice', 'filefilter'));
 }  }
   
 sub new {  sub new {
Line 1699  sub postprocess { Line 1718  sub postprocess {
   
 1;  1;
   
   package Apache::lonhelper::general;
   
   =pod
   
   =head2 General-purpose tag: <exec>
   
   The contents of the exec tag are executed as Perl code, not inside a 
   safe space, so the full range of $ENV and such is available. The code
   will be executed as a subroutine wrapped with the following code:
   
   "sub { my $helper = shift; my $state = shift;" and
   
   "}"
   
   The return value is ignored.
   
   $helper is the helper object. Feel free to add methods to the helper
   object to support whatever manipulation you may need to do (for instance,
   overriding the form location if the state is the final state; see 
   lonparm.helper for an example).
   
   $state is the $paramHash that has currently been generated and may
   be manipulated by the code in exec. Note that the $state is not yet
   an actual state B<object>, it is just a hash, so do not expect to
   be able to call methods on it.
   
   =cut
   
   BEGIN {
       &Apache::lonhelper::register('Apache::lonhelper::general',
                                    'exec', 'condition', 'clause');
   }
   
   sub start_exec {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
       if ($target ne 'helper') {
           return '';
       }
       
       my $code = &Apache::lonxml::get_all_text('/exec', $parser);
       
       $code = eval ('sub { my $helper = shift; my $state = shift; ' .
           $code . "}");
       &$code($helper, $paramHash);
   }
   
   sub end_exec { return ''; }
   
   =pod
   
   =head2 General-purpose tag: <condition>
   
   The <condition> tag allows you to mask out parts of the helper code
   depending on some programatically determined condition. The condition
   tag contains a tag <clause> which contains perl code that when wrapped
   with "sub { my $helper = shift; my $state = shift; " and "}", returns
   a true value if the XML in the condition should be evaluated as a normal
   part of the helper, or false if it should be completely discarded.
   
   The <clause> tag must be the first sub-tag of the <condition> tag or
   it will not work as expected.
   
   =cut
   
   # The condition tag just functions as a marker, it doesn't have
   # to "do" anything. Technically it doesn't even have to be registered
   # with the lonxml code, but I leave this here to be explicit about it.
   sub start_condition { return ''; }
   sub end_condition { return ''; }
   
   sub start_clause {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
       if ($target ne 'helper') {
           return '';
       }
       
       my $clause = Apache::lonxml::get_all_text('/clause', $parser);
       $clause = eval('sub { my $helper = shift; my $state = shift; '
           . $clause . '}');
       if (!&$clause($helper, $paramHash)) {
           # Discard all text until the /condition.
           &Apache::lonxml::get_all_text('/condition', $parser);
       }
   }
   
   sub end_clause { return ''; }
   
   1;
   
 __END__  __END__
   

Removed from v.1.6  
changed lines
  Added in v.1.10


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>