[system] / trunk / webwork-modperl / lib / WeBWorK / ContentGenerator.pm Repository:
ViewVC logotype

Diff of /trunk/webwork-modperl/lib/WeBWorK/ContentGenerator.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1860 Revision 1861
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator.pm,v 1.78 2004/03/04 21:03:04 sh002i Exp $ 4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator.pm,v 1.79 2004/03/06 18:50:00 gage Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 6# This program is free software; you can redistribute it and/or modify it under
7# the terms of either: (a) the GNU General Public License as published by the 7# the terms of either: (a) the GNU General Public License as published by the
8# Free Software Foundation; either version 2, or (at your option) any later 8# Free Software Foundation; either version 2, or (at your option) any later
9# version, or (b) the "Artistic License" which comes with this package. 9# version, or (b) the "Artistic License" which comes with this package.
18 18
19=head1 NAME 19=head1 NAME
20 20
21WeBWorK::ContentGenerator - base class for modules that generate page content. 21WeBWorK::ContentGenerator - base class for modules that generate page content.
22 22
23=head1 SYNOPSIS
24
25 # start with a WeBWorK::Request object: $r
26
27 use WeBWorK::ContentGenerator::SomeSubclass;
28
29 my $cg = WeBWorK::ContentGenerator::SomeSubclass->new($r);
30 my $result = $cg->go();
31
32=head1 DESCRIPTION
33
34FIXME: write this
35
23=cut 36=cut
24 37
25use strict; 38use strict;
26use warnings; 39use warnings;
27use Apache::Constants qw(:common); 40use Apache::Constants qw(:common);
34################################################################################ 47################################################################################
35# This is a very unruly file, so I'm going to use very large comments to divide 48# This is a very unruly file, so I'm going to use very large comments to divide
36# it into logical sections. 49# it into logical sections.
37################################################################################ 50################################################################################
38 51
39## new(Apache::Request, WeBWorK::CourseEnvironment, WeBWorK::DB) - create a new 52=head1 CONSTRUCTOR
40## instance of a content generator. Usually only called by the dispatcher, although
41## one might be able to use it for things like "sub-requests". Uh... uh... I have
42## to think about that one. The dispatcher uses this idiom:
43##
44## WeBWorK::ContentGenerator::WHATEVER->new($r, $ce, $db)->go(@whatever);
45##
46## and throws away the result ;)
47##
48#sub new {
49# my ($invocant, $r, $ce, $db) = @_;
50# my $class = ref($invocant) || $invocant;
51# my $self = {
52# r => $r,
53# ce => $ce,
54# db => $db,
55# authz => WeBWorK::Authz->new($r, $ce, $db),
56# noContent => undef,
57# };
58# bless $self, $class;
59# return $self;
60#}
61 53
62# new(WeBWorK::Request) - create a new instance of a content generator. Usually 54=over
63# only called by the dispatcher, although one might be able to use it for things 55
64# like "sub-requests". Uh... uh... I have to think about that one. The dispatcher 56=item new($r)
65# uses this idiom: 57
66# 58Create a new instance of a content generator. Supply a WeBWorK::Request object
67# WeBWorK::ContentGenerator::WHATEVER->new($r)->go(); 59$r.
68# 60
69# and throws away the result ;) 61=cut
70# 62
71sub new { 63sub new {
72 my ($invocant, $r) = @_; 64 my ($invocant, $r) = @_;
73 my $class = ref($invocant) || $invocant; 65 my $class = ref($invocant) || $invocant;
74 my $self = { 66 my $self = {
75 r => $r, # this is now a WeBWorK::Request 67 r => $r, # this is now a WeBWorK::Request
80 }; 72 };
81 bless $self, $class; 73 bless $self, $class;
82 return $self; 74 return $self;
83} 75}
84 76
77=back
78
79=cut
80
85################################################################################ 81################################################################################
86# Invocation and template processing 82# Invocation and template processing
87################################################################################ 83################################################################################
88 84
89# go(@otherArguments) - render a page, using methods from the particular 85=head1 INVOCATION
90# subclass of ContentGenerator. @otherArguments is passed to each method, so 86
91# that the dispatcher can pass CG-specific data. The order of calls looks like 87=over
92# this: 88
93# 89=item go()
94# * &pre_header_initialize - give subclasses a chance to do initialization 90
95# necessary for generating the HTTP header. 91Render a page, using methods from the particular subclass of ContentGenerator.
96# * &header - this class provides a standard HTTP header with Content-Type 92go() will call the following methods when invoked:
97# text/html. Subclasses are welcome to overload this for things like 93
98# an image-creation content generator or a PDF generator. 94=over
99# In addition, if &header returns a value, that will be the value 95
100# returned by the entire PerlHandler. 96=item pre_header_initialize()
97
98Give the subclass a chance to do initialization necessary before generating the
99HTTP header.
100
101=item header()
102
103This method provides a standard HTTP header with Content-Type text/html.
104Subclasses are welcome to override this for things like an image-creation
105content generator or a PDF generator. In addition, if header() returns a value,
106that will be the value returned by go().
107
108=item initialize()
109
101# * &initialize - let subclasses do post-header initialization. 110Let the subclass do post-header initialization.
102# * any "template escapes" defined in the system template and supported by 111
103# the subclass.
104# (if &content exists on a content generator, it is called
105# and no template processing occurs.)
106#
107# If &pre_header_initialize or &header sets $self->{noContent} to a true value, 112If pre_header_initialize() or header() sets $self->{noContent} to a true value,
108# &initialize will not be run and the content or template processing code 113initialize() will not be run and the content or template processing code
109# will not be executed. This is probably only desirable if a redirect has been 114will not be executed. This is probably only desirable if a redirect has been
110# issued. 115issued.
116
117=item template()
118
119The layout template is processed. See template() below.
120
121If the subclass implements a method named content(), it is called
122instead and no template processing occurs.
123
124=back
125
126=cut
127
111sub go { 128sub go {
112 my $self = shift; 129 my $self = shift;
113 130
114 my $r = $self->{r}; 131 my $r = $self->{r};
115 my $ce = $self->{ce}; 132 my $ce = $self->{ce};
146 } 163 }
147 164
148 return $returnValue; 165 return $returnValue;
149} 166}
150 167
168=item sendFile()
169
170=cut
171
151sub sendFile { 172sub sendFile {
152 my ($self) = @_; 173 my ($self) = @_;
153 174
154 my $file = $self->{sendFile}->{source}; 175 my $file = $self->{sendFile}->{source};
155 176
163 } 184 }
164 close $fh; 185 close $fh;
165 186
166 return OK; 187 return OK;
167} 188}
189
190=back
191
192=cut
193
194=head1 TEMPLATE PROCESSING
195
196=over
197
198=item template($templateFile)
199
200=cut
168 201
169# template(STRING, @otherArguments) - parse a template, looking for escapes of 202# template(STRING, @otherArguments) - parse a template, looking for escapes of
170# the form <!--#NAME ARG1="FOO" ARG2="BAR"--> and calling a member function NAME 203# the form <!--#NAME ARG1="FOO" ARG2="BAR"--> and calling a member function NAME
171# (if available) for each NAME. The escapes are called like: 204# (if available) for each NAME. The escapes are called like:
172# 205#
227 print substr($line, (defined pos $line) ? pos $line : 0), "\n"; 260 print substr($line, (defined pos $line) ? pos $line : 0), "\n";
228 } 261 }
229 } 262 }
230} 263}
231 264
265=item cook_args($string)
266
267=cut
268
232# cook_args(STRING) - parses a string of the form ARG1="FOO" ARG2="BAR". Returns 269# cook_args(STRING) - parses a string of the form ARG1="FOO" ARG2="BAR". Returns
233# a list which pairs into key/values and fits nicely in {}s. 270# a list which pairs into key/values and fits nicely in {}s.
234# 271#
235sub cook_args($) { # ... also used by bin/wwdb, so watch out 272sub cook_args($) { # ... also used by bin/wwdb, so watch out
236 my ($raw_args) = @_; 273 my ($raw_args) = @_;
245 push @args, $key => $value; 282 push @args, $key => $value;
246 } 283 }
247 284
248 return @args; 285 return @args;
249} 286}
287
288=item if($args)
289
290=cut
250 291
251# This is different. It probably shouldn't print anything (except in debugging cases) 292# This is different. It probably shouldn't print anything (except in debugging cases)
252# and it should return a boolean, not a string. &if is called in a nonstandard way 293# and it should return a boolean, not a string. &if is called in a nonstandard way
253# by &template, with $args as an arrayref instead of a hashref. this is a hack! yay! 294# by &template, with $args as an arrayref instead of a hashref. this is a hack! yay!
254 295
277 } 318 }
278 319
279 return 0; 320 return 0;
280} 321}
281 322
323=back
324
325=cut
326
282################################################################################ 327################################################################################
283# Macros used by content generators to render common idioms 328# Macros used by content generators to render common idioms
284################################################################################ 329################################################################################
285 330
286# pathMacro(HASHREF, LIST) - helper macro for <!--#path--> escape: the hash 331# FIXME: some of these should be moved to WeBWorK::HTML:: modules!
287# reference contains the "style", "image", and "text" arguments to the escape. 332
333=head1 HTML MACROS
334
335Macros used by content generators to render common idioms
336
337=over
338
339=item pathMacro($args, @path)
340
341Helper macro for <!--#path--> escape: $args is a hash reference containing the
342"style", "image", "text", and "textonly" arguments to the escape. @path consists
288# The LIST consists of ordered key-value pairs of the form: 343of ordered key-value pairs of the form:
289# 344
290# "Page Name" => URL 345 "Page Name" => URL
291# 346
292# If the page should not have a link associated with it, the URL should be left 347If the page should not have a link associated with it, the URL should be left
293# empty. Authentication data is added to the URL so you don't have to. A fully- 348empty. Authentication data is added to the URL so you don't have to. A fully-
294# formed path line is returned, suitable for returning by a function 349formed path line is returned, suitable for returning by a function implementing
295# implementing the #path escape. 350the #path escape.
296# 351
352=cut
353
297sub pathMacro { 354sub pathMacro {
298 my $self = shift; 355 my $self = shift;
299 my %args = %{ shift() }; 356 my %args = %{ shift() };
300 my @path = @_; 357 my @path = @_;
358 $args{style} = "text" if $args{textonly};
301 my $sep; 359 my $sep;
302 if ($args{style} eq "image") { 360 if ($args{style} eq "image") {
303 $sep = CGI::img({-src=>$args{image}, -alt=>$args{text}}); 361 $sep = CGI::img({-src=>$args{image}, -alt=>$args{text}});
304 } else { 362 } else {
305 $sep = $args{text}; 363 $sep = $args{text};
307 my $auth = $self->url_authen_args; 365 my $auth = $self->url_authen_args;
308 my @result; 366 my @result;
309 while (@path) { 367 while (@path) {
310 my $name = shift @path; 368 my $name = shift @path;
311 my $url = shift @path; 369 my $url = shift @path;
312 push @result, $url 370 if ($url and not $args{textonly}) {
313 ? CGI::a({-href=>"$url?$auth"}, $name) 371 push @result, CGI::a({-href=>"$url?$auth"}, $name);
314 : $name; 372 } else {
373 push @result, $name;
374 }
315 } 375 }
316 return join($sep, @result) . "\n"; 376 return join($sep, @result) . "\n";
317} 377}
378
379=item siblingsMacro(@siblings)
380
381=cut
318 382
319sub siblingsMacro { 383sub siblingsMacro {
320 my $self = shift; 384 my $self = shift;
321 my @siblings = @_; 385 my @siblings = @_;
322 my $sep = CGI::br(); 386 my $sep = CGI::br();
329 ? CGI::a({-href=>"$url?$auth"}, $name) 393 ? CGI::a({-href=>"$url?$auth"}, $name)
330 : $name; 394 : $name;
331 } 395 }
332 return join($sep, @result), "\n"; 396 return join($sep, @result), "\n";
333} 397}
398
399=item navMacro($args, $tail)
400
401=cut
334 402
335sub navMacro { 403sub navMacro {
336 my $self = shift; 404 my $self = shift;
337 my %args = %{ shift() }; 405 my %args = %{ shift() };
338 my $tail = shift; 406 my $tail = shift;
359 } 427 }
360 } 428 }
361 return join($args{separator}, @result) . "\n"; 429 return join($args{separator}, @result) . "\n";
362} 430}
363 431
364# hidden_fields(LIST) - return hidden <INPUT> tags for each field mentioned in 432=item hidden_fields(@fields)
433
434Return hidden <INPUT> tags for each field mentioned in @fields (or all fields if
365# LIST (or all fields if list is empty), taking data from the current request. 435list is empty), taking data from the current request.
366# 436
437=cut
438
367sub hidden_fields($;@) { 439sub hidden_fields($;@) {
368 my $self = shift; 440 my $self = shift;
369 my $r = $self->{r}; 441 my $r = $self->{r};
370 my @fields = @_; 442 my @fields = @_;
371 @fields or @fields = $r->param; 443 @fields or @fields = $r->param;
377 $html .= CGI::input({-type=>"hidden",-name=>"$param",-value=>"$value"}); 449 $html .= CGI::input({-type=>"hidden",-name=>"$param",-value=>"$value"});
378 } 450 }
379 return $html; 451 return $html;
380} 452}
381 453
382# hidden_authen_fields() - use hidden_fields to return hidden <INPUT> tags for 454=item hidden_authen_fields()
383# request fields used in authentication. 455
384# 456Use hidden_fields to return hidden <INPUT> tags for request fields used in
457authentication.
458
459=cut
460
385sub hidden_authen_fields($) { 461sub hidden_authen_fields($) {
386 my $self = shift; 462 my $self = shift;
387 return $self->hidden_fields("user","effectiveUser","key"); 463 return $self->hidden_fields("user","effectiveUser","key");
388} 464}
389 465
390# url_args(LIST) - return a URL query string (without the leading `?') 466=item url_args(@fields)
391# containing values for each field mentioned in LIST, or all fields if list is 467
392# empty. Data is taken from the current request. 468Return a URL query string (without the leading `?') containing values for each
393# 469field mentioned in @fields, or all fields if list is empty. Data is taken from
470the current request.
471
472=cut
473
394sub url_args($;@) { 474sub url_args($;@) {
395 my $self = shift; 475 my $self = shift;
396 my $r = $self->{r}; 476 my $r = $self->{r};
397 my @fields = @_; 477 my @fields = @_;
398 @fields or @fields = $r->param; # If no fields are passed in, do them all. 478 @fields or @fields = $r->param; # If no fields are passed in, do them all.
407 } 487 }
408 488
409 return join("&", @pairs); 489 return join("&", @pairs);
410} 490}
411 491
412# url_authen_args() - use url_args to return a URL query string for request 492=item url_authen_args()
413# fields used in authentication. 493
414# 494Use url_args to return a URL query string for request fields used in
495authentication.
496
497=cut
498
415sub url_authen_args($) { 499sub url_authen_args($) {
416 my $self = shift; 500 my $self = shift;
417 my $r = $self->{r}; 501 my $r = $self->{r};
418 return $self->url_args("user","effectiveUser","key"); 502 return $self->url_args("user","effectiveUser","key");
419} 503}
420 504
421# returns non-breaking space for empty strings 505=item nbsp($string)
506
507If string is the empty string, the HTML entity C< &nbsp; > is returned.
508Otherwise the string is returned.
509
510=cut
511
422sub nbsp { 512sub nbsp {
423 my $self = shift; 513 my $self = shift;
424 my $str = shift; 514 my $str = shift;
425 ($str =~/\S/) ? $str : '&nbsp;' ; # returns non-breaking space for empty strings 515 ($str =~/\S/) ? $str : '&nbsp;' ; # returns non-breaking space for empty strings
426 # tricky cases: $str =0; 516 # tricky cases: $str =0;
427 # $str is a complex number 517 # $str is a complex number
428} 518}
429# print_form_data(BEGIN, MIDDLE, END, OMIT) - return a string containing request 519
430# fields not matched by OMIT, placing BEGIN before each field name, MIDDLE 520=item print_form_data($begin, $middle, $end, $omit)
431# between each field and its value, and END after each value. Values are taken 521
432# from the current request. OMIT is a quoted reguar expression. 522Return a string containing request fields not matched by $omit, placing $begin
433# 523before each field name, $middle between each field and its value, and $end after
524each value. Values are taken from the current request. $omit is a quoted reguar
525expression.
526
527=cut
528
434sub print_form_data { 529sub print_form_data {
435 my ($self, $begin, $middle, $end, $qr_omit) = @_; 530 my ($self, $begin, $middle, $end, $qr_omit) = @_;
436 my $return_string = ""; 531 my $return_string = "";
437 my $r=$self->{r}; 532 my $r=$self->{r};
438 my @form_data = $r->param; 533 my @form_data = $r->param;
448 } 543 }
449 } 544 }
450 return $return_string; 545 return $return_string;
451} 546}
452 547
548=item errorOutput($error, $details)
549
550=cut
551
453sub errorOutput($$$) { 552sub errorOutput($$$) {
454 my ($self, $error, $details) = @_; 553 my ($self, $error, $details) = @_;
455 return 554 return
456 CGI::h3("Software Error"), 555 CGI::h3("Software Error"),
457 CGI::p(<<EOF), 556 CGI::p(<<EOF),
462EOF 561EOF
463 CGI::h3("Error messages"), CGI::p(CGI::tt($error)), 562 CGI::h3("Error messages"), CGI::p(CGI::tt($error)),
464 CGI::h3("Error context"), CGI::p(CGI::tt($details)); 563 CGI::h3("Error context"), CGI::p(CGI::tt($details));
465} 564}
466 565
566=item warningOutput($warnings)
567
568=cut
569
467sub warningOutput($$) { 570sub warningOutput($$) {
468 my ($self, $warnings) = @_; 571 my ($self, $warnings) = @_;
469 572
470 my @warnings = split m/\n+/, $warnings; 573 my @warnings = split m/\n+/, $warnings;
471 574
480 CGI::h3("Warning messages"), 583 CGI::h3("Warning messages"),
481 CGI::ul(CGI::li(\@warnings)), 584 CGI::ul(CGI::li(\@warnings)),
482 ; 585 ;
483} 586}
484 587
588=back
589
590=cut
591
485################################################################################ 592################################################################################
486# Generic versions of template escapes 593# Generic versions of template escapes
487################################################################################ 594################################################################################
488 595
489# Reminder: here are the template functions currently defined: 596=head1 THE HEADER METHOD
490# FIXME: this list is out of date!!!!!!!! 597
491# 598=over
492# head 599
493# path 600=item header()
494# style = text|image 601
495# image = URL of image 602The C<header> method is defined in WeBWorK::ContentGenerator to generate a
496# text = text separator 603default C<Content-type> of text/html and send the HTTP header.
497# loginstatus 604
498# links 605=back
499# siblings 606
500# nav 607=cut
501# style = text|image
502# imageprefix = prefix to image URL
503# imagesuffix = suffix to image URL
504# separator = HTML to place in between links
505# title
506# body
507 608
508sub header { 609sub header {
509 my $self = shift; 610 my $self = shift;
510 my $r = $self->{r}; 611 my $r = $self->{r};
511 612
521 622
522 $r->send_http_header(); 623 $r->send_http_header();
523 return OK; 624 return OK;
524} 625}
525 626
526sub loginstatus { 627=head1 TEMPLATE ESCAPE METHODS
527 my $self = shift; 628
528 my $r = $self->{r}; 629Template escape methods are invoked when a
529 my $ce = $self->{ce}; 630C< <!--#escape argument="value" ... -> > construct is encountered in the
530 631template. The methods can be defined here in ContentGenerator, or in a
531 my $user = $r->param("user"); 632particular subclass. Arguments are passed to the method as a reference to a
532 my $eUser = $r->param("effectiveUser"); 633hash.
533 my $key = $r->param("key"); 634
534 635The following template escapes are currently defined:
535 return "" unless $key; 636
536 637=over
537 my $exitURL = $r->uri() . "?user=$user&key=$key"; 638
538 639=item head
539 my $root = $ce->{webworkURLs}->{root}; 640
540 my $courseID = $ce->{courseName}; 641Any tags that should appear in the HEAD of the document. Not defined by default.
541 my $logout = "$root/$courseID/logout/?" . $self->url_authen_args(); 642
542 643=item info
543 print CGI::small("User:", "$user"); 644
544 645Auxiliary information related to the C<body>. Not defined by default.
545 if ($user ne $eUser) { 646
546 print CGI::br(), CGI::font({-color=>'red'}, 647=item links
547 CGI::small("Acting as:", "$eUser") 648
548 ), 649Links that should appear on every page. Defined in WeBWorK::ContentGenerator by
549 CGI::br(), CGI::a({-href=>$exitURL}, 650default.
550 CGI::small("Stop Acting") 651
551 ); 652=cut
552 }
553
554 print CGI::br(), CGI::a({-href=>$logout}, CGI::small("Log Out"));
555
556 return "";
557}
558 653
559# FIXME: drunk code. rewrite. 654# FIXME: drunk code. rewrite.
560# also, this should be structured s.t. subclasses can add items to the links 655# also, this should be structured s.t. subclasses can add items to the links
561# area, i.e. "stacking" 656# area, i.e. "stacking"
562sub links { 657sub links {
598 ($permLevel > 0 693 ($permLevel > 0
599 ? $self->instructor_links(@components) : "" 694 ? $self->instructor_links(@components) : ""
600 ), 695 ),
601 ); 696 );
602} 697}
698
603sub instructor_links { 699sub instructor_links {
604 my $self = shift; 700 my $self = shift;
605 my @components = @_; 701 my @components = @_;
606 my $args = pop(@components); # get hash of option arguments 702 my $args = pop(@components); # get hash of option arguments
607 my $courseName = $self->{ce}->{courseName}; 703 my $courseName = $self->{ce}->{courseName};
664 : '', 760 : '',
665 '&nbsp;&nbsp;&nbsp;',CGI::a({-href=>$fileXfer}, "File&nbsp;Transfer"), CGI::br(), 761 '&nbsp;&nbsp;&nbsp;',CGI::a({-href=>$fileXfer}, "File&nbsp;Transfer"), CGI::br(),
666 ); 762 );
667} 763}
668 764
669# &if_can will return 1 if the current object->can("do $_[1]") 765=item loginstatus
670sub if_can ($$) { 766
671 my ($self, $arg) = (@_); 767A notification message announcing the current real user and effective user, a
768link to stop acting as the effective user, and a logout link. Defined in
769WeBWorK::ContentGenerator by default.
770
771=cut
772
773sub loginstatus {
774 my $self = shift;
775 my $r = $self->{r};
776 my $ce = $self->{ce};
672 777
673 if ($self->can("$arg")) { 778 my $user = $r->param("user");
779 my $eUser = $r->param("effectiveUser");
780 my $key = $r->param("key");
781
782 return "" unless $key;
783
784 my $exitURL = $r->uri() . "?user=$user&key=$key";
785
786 my $root = $ce->{webworkURLs}->{root};
787 my $courseID = $ce->{courseName};
788 my $logout = "$root/$courseID/logout/?" . $self->url_authen_args();
789
790 print CGI::small("User:", "$user");
791
792 if ($user ne $eUser) {
793 print CGI::br(), CGI::font({-color=>'red'},
794 CGI::small("Acting as:", "$eUser")
795 ),
796 CGI::br(), CGI::a({-href=>$exitURL},
797 CGI::small("Stop Acting")
798 );
799 }
800
801 print CGI::br(), CGI::a({-href=>$logout}, CGI::small("Log Out"));
802
674 return 1; 803 return "";
675 } else {
676 return 0;
677 }
678} 804}
679 805
680# Every content generator is logged in unless it says otherwise. 806=item nav
681sub if_loggedin($$) {
682 my ($self, $arg) = (@_);
683
684 return $arg;
685}
686 807
687# Handling of errors in submissions 808Links to the previous, next, and parent objects. Not defined by default.
688 809
689sub if_submiterror($$) { 810 style => text|image
811 imageprefix => prefix to prepend to base image URL
812 imagesuffix => suffix to append to base image URL
813 separator => HTML to place in between links
814
815=item options
816
817A place for an options form, like the problem display options. Not defined by
818default.
819
820=item path
821
822"Breadcrubs" from the current page to the root of the virtual hierarchy. Defined
823in WeBWorK::ContentGenerator to pull information from the WeBWorK::URLPath.
824
825 style => type of separator: text|image
826 image => URL of separator image
827 text => text of texual separator (also used for image alt text)
828 textonly => suppress links
829
830=cut
831
832sub path {
690 my ($self, $arg) = @_; 833 my ($self, $args) = @_;
691 if (exists $self->{submitError}) { 834 my $r = $self->{r};
692 return $arg; 835
693 } else { 836 my @path;
694 return !$arg; 837
695 } 838 my $urlpath = $r->urlpath;
839 do {
840 unshift @path, $urlpath->name, $r->location . $urlpath->path;
841 } while ($urlpath = $urlpath->parent);
842
843 $path[$#path] = ""; # we don't want the last path element to be a link
844
845 return $self->pathMacro($args, @path);
696} 846}
847
848=item siblings
849
850Links to siblings of the current object. Not defined by default.
851
852=item submiterror
853
854Any error messages resulting from the last form submission. Defined in
855WeBWorK::ContentGenerator by default.
856
857=cut
697 858
698sub submiterror { 859sub submiterror {
699 my ($self) = @_; 860 my ($self) = @_;
700 if (exists $self->{submitError}) { 861 if (exists $self->{submitError}) {
701 return $self->{submitError}; 862 return $self->{submitError};
702 } else { 863 } else {
703 return ""; 864 return "";
704 } 865 }
705} 866}
706 867
707# General warning handling 868=item title
708 869
709sub if_warnings($$) { 870The title of the current page. Defined in WeBWorK::ContentGenerator to pull
871information from the WeBWorK::URLPath.
872
873=cut
874
875sub title {
710 my ($self, $arg) = @_; 876 my ($self, $args) = @_;
711 return $self->{r}->notes("warnings") ? $arg : !$arg; 877 my $r = $self->{r};
878
879 return $r->urlpath->name;
712} 880}
881
882=item warnings
883
884Any warnings. Not defined by default.
885
886=cut
713 887
714sub warnings { 888sub warnings {
715 my ($self) = @_; 889 my ($self) = @_;
716 my $r = $self->{r}; 890 my $r = $self->{r};
717 if ($r->notes("warnings")) { 891 if ($r->notes("warnings")) {
719 } else { 893 } else {
720 return ""; 894 return "";
721 } 895 }
722} 896}
723 897
898=back
899
900=head CONDITIONAL PREDICATES
901
902Conditional predicate methods are invoked when the
903C< <!--#if predicate="value"--> > construct is encountered in the template. If a
904method named C<if_predicate> is defined in here or in a particular subclass, it
905is invoked.
906
907The following predicates are currently defined:
908
909=over
910
911=item if_can
912
913will return 1 if the current object->can("do $_[1]")
914
915=cut
916
917sub if_can ($$) {
918 my ($self, $arg) = (@_);
919
920 if ($self->can("$arg")) {
921 return 1;
922 } else {
923 return 0;
924 }
925}
926
927=item if_loggedin
928
929Every content generator is logged in unless it overrides this method to say
930otherwise.
931
932=cut
933
934sub if_loggedin($$) {
935 my ($self, $arg) = (@_);
936
937 return $arg;
938}
939
940=item if_submiterror
941
942=cut
943
944sub if_submiterror($$) {
945 my ($self, $arg) = @_;
946 if (exists $self->{submitError}) {
947 return $arg;
948 } else {
949 return !$arg;
950 }
951}
952
953=item if_warnings
954
955sub if_warnings($$) {
956 my ($self, $arg) = @_;
957 return $self->{r}->notes("warnings") ? $arg : !$arg;
958}
959
960=back
961
962=cut
963
7241; 9641;
725 965
726__END__ 966__END__
727 967
728=head1 AUTHOR 968=head1 AUTHOR

Legend:
Removed from v.1860  
changed lines
  Added in v.1861

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9