Skip to content

WeBWorK request execution path

drdrew42 edited this page Aug 16, 2019 · 5 revisions

This is the path traversed by a request to a WeBWorK server.

WeBWorK request execution path

conf/webwork.apache2-config
  • This file is included in the Apache server's http.conf file in order to handle requests related to WeBWorK.
  • For https://mysite.edu/webwork2 the webwork2 link ($webwork_url) signals that the request should be sent to lib/Apache/WeBWorK.pm (Apache::WeBWorK)
  • Other links handled by this file
    • webwork_files ($webwork_htdocs_url)
    • webwork_course_files ($webwork_courses_url)
    • mod_xmlrpc
    • mod_soap
lib/Apache/WeBWorK
  • This is the Apache handler for WeBWorK requests and sets up the infrastructure for error messages. After setting the warning and exception handlers it sends the request to the dispatcher at WeBWorK.pm
lib/WeBWorK.pm

WeBWorK.pm is the dispatcher for the WeBWorK system. Given an Apache request object, it performs authentication and determines which subclass of WeBWorK/ContentGenerator to call. It also takes the Apache request object (which contains all kinds of information about the original request) and adapts it to WeBWorK. Adding a few fields and reorganizing them. This request object is stored in $r and is passed to the content generating modules.

  • Create request object $r (via WeBWorK::Request)
  • Create URL path object from original path (which can't be completely trusted). (This is done by WeBWorK::URLPath). Stored in $r->urlpath
  • Create course environment object (via WeBWorK::CourseEnvironment) and store in $r->ce
  • Create a database object (via WeBWorK::DB) and store in $r->db
  • Create localization object (via WeBWorK::Localize) create and store language infrastructure in $r->language_handle
  • Set the effective user or target user -- the person for whom the problem is being created. (The actual user might be a professor "acting" as the effective user).
  • Send request $r to modules go function. The module is initially determined by WeBWorK::URLPath. Most often it is WeBWorK/ContentGenerator.pm.
  • Comments
    • The debug comments in WeBWorK.pm help walk through the dispatch process.
    • What are the uploads?
lib/WeBWorK/ContentGenerator.pm
  • The subroutines common to the ContentGenerator modules are defined in ContentGenerator.pm which is their parent class. Some of these are overridden in the subclasses.

ContentGenerator generates a page, using methods from the particular subclass of ContentGenerator that is instantiated. Generation is broken up into several steps, to give subclasses ample control over the process.

  1. go() will attempt to call the method pre_header_initialize(). This method is often implemented in subclasses which must do processing before the HTTP header is emitted.

  2. go() will attempt to call the method header(). This method emits the HTTP header. It is defined in this class (see below), but may be overridden in subclasses which need to send different header information. For some reason, the return value of header() will be used as the result of this function, if it is defined. FIXME: figure out what the deal is with the return value of header(). If we sent a header, it's too late to set the status by returning. If we didn't, header() didn't perform its function!

  3. At this point, go() will terminate if the request is a HEAD request or if the field $self->{noContent} contains a true value. FIXME: I don't think we'll need noContent after reply_with_redirect() is adopted by all modules.

  4. go() then attempts to call the method initialize(). This method will be implemented in subclasses which must do processing after the HTTP header is sent but before any content is sent.

  5. The method content() is called to send the page content to client.

    • The content() method first determines the "theme" for the page (e.g. math4) as specified by the conf files and determines the name (type) of the template (a few pages have special templates, most just use a version of the system template used by the Problem page.

The template object provided by WeBWorK::Template contains the outline of the html page to be returned with embedded call backs to the ContentGenerator module to fill in specific details.

See an example at webwork2/htdocs/themes/math4/system.template and read details in WeBWorK::Template. Here is a very brief overview.

Template commands are indicated by <!--#commandOrCallback-->. <!--#if can="output_JS"--> is true if the subroutine output_JS exists on the page. It has nothing to do with permissions.

Examples of callbacks () include:

* output_CSS
* output_JS
* links (navigation links)
* output_problem_body (signals that the template should organize individual parts of the page)
	* output_comments
	* output_hidden_info
	* output_editor_link
	* output_score_summary
	* info
* body (the content page organizes material and since it altogether to the template page)
* footer.

The Problem page has callbacks for each part of the page in order to provide flexibility to rearrange the output for a theme. Other more generic pages may only have body as a call back and the organization of material is done within that ContentGenerator page.

lib/WeBWorK/ContentGenerator/Problem.pm
  • The most common (and complex) ContentGenerator module is WeBWorK::ContentGenerator::Problem We discuss the purposes of some of the subroutines.

  • "can" methods Subroutines to determine if a user "can" perform an action. Each subroutine is called with the following arguments: ($self, $User, $EffectiveUser, $Set, $Problem)

  • attemptResults() creates the table at the top of the page evaluating the student's answer

  • content() uses the parent subroutine in ContentGenerator but in addition cleans up some of the data left over from rendering the problem

  • pre_header_initialize()

    • checks authentication and authorization
    • fetch data from $db and the problem file text from the course/templates directory
    • collect (and check permissions) for the options selected by the user
    • fill in "sticky answers" -- if this is the resubmission of a problem populate the answer blanks with the previous entries.
    • translate (render the problem) by creating a WeBWorK::PG object (found in webwork2/lib/WeBWorK/PG.pm
    • record results, errors and warnings

Now we are ready to start printing using callbacks

  • body -- not used
  • output_problem_body -- prints text returned by PG
  • output_message
  • output_checkboxes
  • output_submit_buttons
  • output_score_summary
  • etc.
  • can_body_parts -- could be checked by the template that the template can select parts of the body and arrange them rather than calling body for the entire content. I don't think this is used anywhere, but it should be used in the templates.
Other ContentGeneration modules
  • Look in URLPath.pms for information