Override default edx-platform XBlock mappings without forking

When you create an XBlock, you define an entry point in your setup.py, where you specify the tags you want to associate with it:

    entry_points={
        'xblock.v1': [
            "supercool = my_plugin_pkg.xblocks:SuperCoolBlock"
        ]
    }

But say you want to override the built-in html tag so that HTML content is handled by your own custom XBlock, instead of edx-platform’s HTMLBlock entry. Maybe you’ve got a plugin where you subclass HTMLBlock to add one or two key new behaviors.

You could try to do:

    entry_points={
        'xblock.v1': [
            "html = my_plugin_pkg.xblocks:CustomHtmlBlock"
        ]
    }

But that will cause the XBlock to raise an AmbiguousPluginError when rendering, because it doesn’t know which mapping to use:

That’s actually a pretty reasonable behavior, since anything can install an XBlock, and it’s better to surface the ambiguity immediately, rather than have it just pick one of the classes at random.

But you can force the edx-platform entry to be removed at startup in your private.py settings file (or anything else that executes in process at server startup) with a snippet like this:

# Remove edx-platform's mapping for the "html" XBlock tag if we've installed
# a plugin with our own mapping for that tag.
import pkg_resources
html_mappings = list(pkg_resources.iter_entry_points('xblock.v1', 'html'))
if len(html_mappings) > 1:
    dist = pkg_resources.get_distribution('Open-edX')
    del dist.get_entry_map('xblock.v1')['html']

This doesn’t permanently remove edx-platform’s entry point for the html tag from its installed package. It’s still there, and pkg_resources will read it on startup every time. We’re just removing the in-process dictionary entry for it as part of LMS/Studio startup, so that it’s no longer there by the time the XBlock tag lookup is checking for it.

I’ve tested that it works locally, though I haven’t used it in production. I definitely recommend caution when trying this approach, since the configuration changes will not be obvious for people who might have to debug issues later. Folks who are running their own forks are almost certainly better off modifying their local copies of edx-platform’s setup.py to just directly map to their custom XBlock. But if you really need to override a built-in XBlock and forking is not feasible for you, this alternative might work.

4 Likes

Thanks, this is useful