[LON-CAPA-cvs] cvs: loncom /interface lonhelper.pm

bowersj2 lon-capa-cvs@mail.lon-capa.org
Fri, 11 Apr 2003 18:16:04 -0000


bowersj2		Fri Apr 11 14:16:04 2003 EDT

  Modified files:              
    /loncom/interface	lonhelper.pm 
  Log:
  Add the "condition" and "exec" tags for executing code and conditionally
  dropping selected parts of the helper XML. This gives me most of the tools
  I need to replicate current wizards.
  
  
Index: loncom/interface/lonhelper.pm
diff -u loncom/interface/lonhelper.pm:1.7 loncom/interface/lonhelper.pm:1.8
--- loncom/interface/lonhelper.pm:1.7	Fri Apr 11 13:45:37 2003
+++ loncom/interface/lonhelper.pm	Fri Apr 11 14:16:04 2003
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # .helper XML handler to implement the LON-CAPA helper
 #
-# $Id: lonhelper.pm,v 1.7 2003/04/11 17:45:37 bowersj2 Exp $
+# $Id: lonhelper.pm,v 1.8 2003/04/11 18:16:04 bowersj2 Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -30,10 +30,6 @@
 # (.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
 
 =head1 lonhelper - HTML Helper framework for LON-CAPA
@@ -794,8 +790,6 @@
 "push" onto the choice list, rather then wiping it out. (You can even 
 remove choices programmatically, but that would probably be bad form.)
 
-FIXME: Document and implement <exec> and <condition> in the element package.
-
 =cut
 
 no strict;
@@ -1718,6 +1712,97 @@
 
     return 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;