UPDATE: This post is outdated! See later replies about how to use xblock.v1.overrides
instead of the hack suggsted in this first post of mine.
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.