XModule Conversion to XBlock

This page documents hackathon work on converting XModules to XBlocks. Here's the first steps we'll take:

  • Convert the "vertical" XModule.
    • This is a core module that all courses use.
    • It's also theoretically easy to convert.
    • And we'll know immediately if we've broken it.

Cale advises us to start with these items:

  • Take the XModule and XModuleDescriptor-derived classes for "vertical" and munge the methods into a single class.
  • Derive the new class from XBlock.
  • Split the get_html() method into a student_view() and a studio_view() method.
  • Tend to XML serialization and any Javascript/Coffeescript that might need to be converted.

We created a branch for the initial work:  jeskew/xmodule_to_xblock_vertical.

  • First error, __init__ in XBlock and XModule classes differ.

We switched the VerticalModule to inherit from XBlock instead of XModule and munged the methods from VerticalDescriptor into VerticalModule.

Roadblocks:

  • The test_vertical.py unittests failed - it's likely due to the tests no longer being set up correctly. XBlocks need to be created instead of XModules.
  • When starting up the LMS, the static asset collection of assets fails due to not finding a get_javascript() method.
    • The code is still calling VerticalModule like an XModule instead of an XBlock.

A WrapperModule and WrapperDescriptor class also existed that derived from VerticalModule/VerticalDescriptor. The WrapperDescriptor class was also removed.

We were able to make the static asset collection work by removing the VerticalDescriptor class completely. BUT that wasn't enough - we had to remove the "vertical" and "wrapper" lines from the common/lib/xmodule/setup.py file as well and rerun "pip install -r requirements/edx/local.txt". This action removed the entry points from the common/lib/xmodule/XModule.egg-info/entry_points.txt file - and removed the exceptions occurring upon XBlock creation.

All these actions brought us to a non-exception error on a vertical: "ERROR: This module is unknown–students will not see it at all"

A HiddenModule was being constructed for the XBlock due to no entry point being found for the vertical. Nimisha added the entry points back into setup.py, pointing at the VerticalModule/WrapperModule and only in the "xblock.v1" section. We then ran "pip install -r requirements/edx/local.txt" to fix the XModule entry_points.txt file. This brought us to a "UndefinedContext" exception being raised by the XModuleDescriptor._xmodule property.

We then hacked in a PureSystem() as a runtime for vertical children only. But we found that in some calls to cache_for_descriptor_descendents() called only to a depth of 2, providing get_module_for_descriptor() with a proper cache and setting up bind_for_student() properly underneath. Basically, the problem is that we're sometime constructing a PureSystem() with a None module runtime.

Questions:

  • When an XBlock/XModule is constructed, can we always assume that it'll have an associated module runtime? An associated descriptor runtime?
    • Answer: Seems to be "No" for a module runtime. For an XModule, the runtime seems to be course- and student- specific. A descriptor runtime is course- and student-agnostic.

A PR was created against the branch for this work - it's here:

https://github.com/edx/edx-platform/pull/6035

A separate branch was created for converting the HTMLDescriptor class - it's here:

https://github.com/itsbenweeks/edx-platform/tree/itsbenweeks/html_xmodule_to_xblock