################################################################################ # WeBWorK mod_perl (c) 1995-2002 WeBWorK Team, Univeristy of Rochester # $Id$ ################################################################################ package WeBWorK::ContentGenerator; =head1 NAME WeBWorK::ContentGenerator - base class for modules that generate page content. =cut use strict; use warnings; use Apache::Constants qw(:common); use CGI qw(); use URI::Escape; #use CGI::Carp qw(fatalsToBrowser); ################################################################################ # This is a very unruly file, so I'm going to use very large comments to divide # it into logical sections. ################################################################################ # new(Apache::Request, WeBWorK::CourseEnvironment) - create a new instance of a # content generator. Usually only called by the dispatcher, although one might # be able to use it for things like "sub-requests". Uh... uh... I have to think # about that one. The dispatcher uses this idiom: # # # WeBWorK::ContentGenerator::WHATEVER->new($r, $ce)->go(@whatever); # # and throws away the result ;) # sub new($$$) { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = {}; ($self->{r}, $self->{courseEnvironment}) = @_; bless $self, $class; return $self; } ################################################################################ # Invocation and template processing ################################################################################ # go(@otherArguments) - render a page, using methods from the particular # subclass of ContentGenerator. @otherArguments is passed to each method, so # that the dispatcher can pass CG-specific data. The order of calls looks like # this: # # * &pre_header_initialize - give subclasses a chance to do initialization # necessary for generating the HTTP header. # * &header - this class provides a standard HTTP header with Content-Type # text/html. Subclasses are welcome to overload this for things like # an image-creation content generator or a PDF generator. # * &initialize - let subclasses do post-header initialization. # * any "template escapes" defined in the system template and supported by # the subclass. Generic implementations of &title and &body are provided. # sub go { my $self = shift; my $r = $self->{r}; my $courseEnvironment = $self->{courseEnvironment}; $self->pre_header_initialize(@_) if $self->can("pre_header_initialize"); $self->header(@_); return OK if $r->header_only; $self->initialize(@_) if $self->can("initialize"); $self->template($courseEnvironment->{templates}->{system}, @_); return OK; } # template(STRING, @otherArguments) - parse a template, looking for escapes of # the form and calling a member function NAME # (if available) for each NAME. The escapes are called like: # # $self->NAME(@otherArguments, \%escapeArguments) # # where @otherArguments originates in the dispatcher and %escapeArguments is # parsed out of the escape itself (i.e. ARG1 => FOO, ARG2 => BAR) # sub template { my ($self, $templateFile) = (shift, shift); my $r = $self->{r}; my $courseEnvironment = $self->{courseEnvironment}; open(TEMPLATE, $templateFile) or die "Couldn't open template $templateFile"; my @template =