The Branching Scenario XBlock provides interactive, decision-based learning experiences for Open edX courses. It allows course authors to create choose-your-own-adventure style scenarios where learners navigate through content by making choices that lead to different outcomes.
- Interactive Decision Trees: Create multi-path scenarios with branching narratives
- Rich Media Support: Include images, videos, and formatted text in scenarios
- Choice Feedback: Provide immediate feedback and hints for each decision point
- Undo Functionality: Allow learners to backtrack through their choices (optional)
- Scoring Integration: Award points for completed scenarios (optional)
- Completion Tracking: Monitor learner progress through the scenario
- Studio Editor: Visual editor for creating and managing branching scenarios
- Internationalization: Support for multiple languages
Install the XBlock within your Open EdX instance:
git clone https://github.com/open-craft/branching-xblock.git
cd branching-xblock
pip install -e .Then add it to your advanced component list in Studio:
ADVANCED_COMPONENT_TYPES = [
# ... other components
'branching_xblock',
]- In Studio, navigate to the unit where you want to add the branching scenario
- Click "Add New Component" → "Advanced" → "Branching Scenario"
- Click "Edit" to open the scenario editor
The scenario editor allows you to:
- Add Nodes: Create content blocks with text, images, or videos
- Create Choices: Add decision points that link to other nodes
- Configure Settings: * Enable/disable undo functionality * Enable/disable scoring * Set maximum score value * Enable/disable hints
- Preview: Test your scenario before publishing
This XBlock comes with a Docker test environment ready to build, based on the xblock-sdk workbench. To build and run it:
make dev.runThe XBlock SDK Workbench, including this XBlock, will be available on the list of XBlocks at http://localhost:8000
Admins can define a global HTML snippet that is used as the default content for the first node in the Studio editor when that node has no content yet.
Configure this in Django SiteConfiguration
site_valuesunder the keybranching_xblock:{ "branching_xblock": { "FIRST_NODE_HTML": "<p>Welcome to the scenario.</p>" } }This value is sanitized server-side (via
bleachwhen available). Allowed tags:p,br,strong,b,em,u,h3,h4,h5,h6,hr,ul,ol,li,a. Allowed attributes: links permithref,title,target,rel.Behavior note: this snippet is not automatically prepended/appended at runtime in the learner view; it is only used to pre-fill empty first-node content in Studio.
Internationalization (i18n) is when a program is made aware of multiple languages. Localization (l10n) is adapting a program to local language and cultural habits.
Use the locale directory to provide internationalized strings for your XBlock project. For more information on how to enable translations, visit the Enabling Translations on a New Repo.
This cookiecutter template uses django-statici18n
to provide translations to static javascript using gettext.
The included Makefile contains targets for extracting, compiling and validating translatable strings. The general steps to provide multilingual messages for a Python program (or an XBlock) are:
- Mark translatable strings.
- Run i18n tools to create raw message catalogs.
- Create language specific translations for each message in the catalogs.
- Use
gettextto translate strings.
Mark translatable strings in python:
from django.utils.translation import ugettext as _
# Translators: This comment will appear in the `.po` file.
message = _("This will be marked.")See edx-developer-guide for more information.
You can also use gettext to mark strings in javascript:
// Translators: This comment will appear in the `.po` file.
var message = gettext("Custom message.");See edx-developer-guide for more information.
This cookiecutter template offers multiple make targets which are shortcuts to use edx-i18n-tools.
After marking strings as translatable we have to create the raw message catalogs.
These catalogs are created in .po files. For more information see
GNU PO file documentation.
These catalogs can be created by running:
make extract_translationsThe previous command will create the necessary .po files under
branching-xblock/branching_xblock/conf/locale/en/LC_MESSAGES/text.po.
The text.po file is created from the django-partial.po file created by
django-admin makemessages (makemessages documentation),
this is why you will not see a django-partial.po file.
After creating the raw message catalogs, all translations should be filled out by the translator.
One or more translators must edit the entries created in the message catalog, i.e. the .po file(s).
The format of each entry is as follows:
# translator-comments A. extracted-comments #: reference… #, flag… #| msgid previous-untranslated-string msgid 'untranslated message' msgstr 'mensaje traducido (translated message)'
For more information see GNU PO file documentation.
To use translations from transifex use the follow Make target to pull translations:
$ make pull_translations
See config instructions for information on how to set up your transifex credentials.
See Enabling Translations on a New Repo for more details about integrating django with transifex.
Once translations are in place, use the following Make target to compile the translation catalogs .po into
.mo message files:
make compile_translationsThe previous command will compile .po files using
django-admin compilemessages (compilemessages documentation).
After compiling the .po file(s), django-statici18n is used to create language specific catalogs. See
django-statici18n documentation for more information.
Note: The
dev.runmake target will automatically compile any translations.Note: To check if the source translation files (
.po) are up-to-date run:
make detect_changed_source_translationsDjango will automatically use gettext and the compiled translations to translate strings.
If there are any errors compiling .po files run the following command to validate your .po files:
make validateSee django's i18n troubleshooting documentation for more information.