|Title||Context-scoped XBlock Fields|
|Author||Braden MacDonald <firstname.lastname@example.org>|
|Arbiter||Calen Pennington <email@example.com>|
There is currently no standard way for XBlocks to define data fields such that content, settings, or user input can be shared among multiple XBlocks within a particular “context” such as a course. Such “course-scoped” or “context-scoped” fields are a common requirement; for example, an author may wish to specify the default “number of attempts allowed” once for all problems in a course, or a video player XBlock may want to “remember” the user’s preferred video playback speed for videos within a particular course.
This OEP proposes a new mechanism for defining XBlock fields that are explicitly scoped to a particular context. The generic term “context” refers to a course, content library, blog post, or any other place where XBlocks can be used (see “Rationale”).
The XBlock API uses the abstract notion of “scopes” to associate each field
with particular environment(s) and user(s). A field’s
Scope is generally a
composite property, defined as the combination of a
UserScope, and a
For reference, the
UserScope can have three values (no changes to these are
NONE: data not related any particular user, that does not change while users interact with the XBlock
ALL: data not related to any particular user, but which may be modified during user interactions
ONE: data related to an individual user
BlockScope can have the following values:
USAGE: “The data is related to a particular use of a block in a course.”
DEFINITION: “The data is related to the definition of the block” (one
block definition can be used multiple times in a course or even among multiple
TYPE: “The data is related to all instances of this type of XBlock.”
ALL: “The data is common to all blocks.”
XBlock runtimes would generally not be expected to implement every possible
UserScope. Instead, certain “named scopes”
are defined, which are the only scopes that most runtimes support:
The existing named scopes, and an example use case for each, are as follows:
As one would expect,
Scope.preferences fields in the
Open edX platform are implemented globally, and not scoped to the course that
uses them. There is currently no standard, extensible way to use XBlock fields
to store data that is scoped to a particular “context,” such as a course,
although this is a common need.
In the absence of a formal method for achieving context-scoped fields through the XBlock API, many other solutions have been put in place, such as: adding custom Django models to XBlocks, storing fields on the root “course” XBlock, defining inherited fields using InheritanceMixin, using edx-submissions as a generic data store, and more.
It is hoped that the new canonical mechanism described by this OEP can provide consistency, improve interoperability, allow new types of behavior to be implemented by XBlocks, and give both authors and learners additional control over learner interactions with XBlocks.
To support context-scoped fields,
BlockScope will allow a new value:
CONTEXT. This new
BlockScope will denote data that is related to all
instances of this type of XBlock within a particular context.
A “context” is defined by the runtime but is usually a “course” or the nearest equivalent. In the Open edX platform, the context may be a course or a content library. Different runs of the same course would be considered different contexts and would not share data, though UserScope.NONE fields would be copied when creating a new course run. On other platforms, a “context” could be defined as a blog post or a textbook.
As is the situtation today, XBlock runtimes would generally not be expected to
implement every possible combination of
Instead, XBlock runtimes are encouraged to implement these new named scopes,
which would be defined in the XBlock python package:
An XBlock which uses
Scope.context_settings fields will need a way for
content authors to edit the data in those fields. (e.g. when creating a course,
the course author may wish to change course-wide settings for the discussion
XBlock used throughout that course.)
A new XBlock view,
context_settings_view shall be used for this purpose.
Just like the existing studio_view defined by edX Studio, this new view will
allow an XBlock to return an arbitrary HTML Fragment which contains a form or
other UI for editing its
It is expected (but not required) that runtimes like edX Studio which want to
support editing of context-scoped fields will define a list of XBlocks that are
enabled within a particular context/course, and will display a list of XBlocks
that define the
context_settings_view. Clicking on the name of that XBlock
would display the HTML fragment and allow the author to edit the context-scoped
When serializing a course with
Scope.context_settings fields to Open
Learning XML (OLX), any context-scoped fields could be described within a new
<xblock-settings> XML element that is a child of the
This would typically be found in
course/course.xml. Each XBlock class that
Scope.context_settings field data could be represented as a child
<xblock-settings>, with the name of the element matching the
XBlock’s entry point name.
An example follows:
<course display_name="Example Course" language="en" advanced_modules='["drag-and-drop-v2", "lti_consumer", "xblock-dalite"]'> <chapter url_name="6915ee3dd6ab403d8c05c0ea3180a0ee"/> <wiki slug="A.B.C"/> <xblock-settings> <discussion allow_anonymous_discussion_posts="true" discussion_blackout_dates='[["2015-09-15", "2015-09-21"], ["2015-10-01", "2015-10-08"]]' /> <lti_consumer lti_passports='["myapp:key1:secret1", "otherapp:key2:secret2"]' /> <xblock-dalite dalite_lti_passports='["dalite-ng-demo:https://dalite-ng-demo.example:key:secret"]' /> </xblock-settings> </course>
The reasoning behind the above provisional spec is as follows: * Conceptually, in the OLX format, all course content and all XBlock fields are
serialized as XML nodes, within a root
<course>node (docs). The entire course’s XML may be in a single course.xml file or spread out into multiple files and subdirectories, where the subdirectory name is the XBlock entry point name (XML node name) and the file name is the block ID (
<course>element is not feasible as it would be messy and conflicts with the current approach where almost every attribute is an XBlock field belonging to the course XBlock.
<xblock-settings>is suggested as a wrapper to keep these new XML nodes organized and indicate their purpose clearly.
Many of the ideas in this proposal are driven by the desire for new types of functionality to be implemented via XBlocks, and thus to be pluggable and easily installed, enabled, or disabled for each Open edX installation or each course.
The idea of naming the new scope “context” comes from other technologies such as LTI, where the term “context” is used analogously. For example, when embedding an LTI tool into the Open edX LMS, the LMS will pass the current course ID as the LTI “context” parameter.
Previous discussions of note include:
Other related proposals of note include:
This OEP introduces new field scopes but does not remove or modify any existing functionality. XBlock authors that add new fields to their XBlock may opt-in to using this feature.
XBlock runtimes may choose to implement context-scoped fields or not. Attempting
to access a context-scoped field in a runtime that does not support such fields
should simply return the default value of the field. Attempting to modify such a
context-scoped field in a runtime that doesn’t support such fields should raise
Some existing XBlocks currently use workarounds for the lack of context-scoped fields, such as storing data in the fields of the root ‘course’ XBlock. Converting such existing techniques to use context-scoped fields instead would be best achieved with an XBlock data migration API, which currently does not exist and is outside the scope of this OEP (however, see here for an example implementation).
Scope.context_preferencesfields for XBlocks used in that course?
values_provideras implemented in xblock-utils.
BlockScopescopes and use the first value found, such as “check for a
Scope.settingsvalue, then a
TBD. Sample code to implement this feature in the XBlock package and the XBlock SDK/Workbench will be produced once the draft has had some initial scrutiny and feedback.
This proposal originally included two new
CONTEXT_ALL_TYPES; the latter was a proposed new scope that would be
used for field data that is accessible to XBlocks of any type, within a
It also defined two named scopes that used
The current proposal deliberately does not support inheritance (i.e. a “context” in the LMS would always be a course, not a “section” or any smaller unit, and field values don’t propagate from parent blocks to children), so it is not a replacement for InheritanceMixin.
Initial discussions of this OEP agreed that context-scoped fields should not participate in inheritance. Improving inheritance of fields or making inheritable fields pluggable are worthy goals, but for a separate proposal.
UserScope, and a
name are combined to
make a Scope for a field. Under this alternative option, a new
RelevanceScope dimension would be added, which could have one of two values:
ALL (default) or
ALL value would represent the current
XBlock API’s definitions, and the
CONTEXT value would mean that the field’s
relevance is limited to one particular context (e.g. that field’s value relates
to one particular course.)
The downside of this is that it creates a large matrix/tensor of scopes:
4 BlockScopes × 3 UserScopes × 2 RelevanceScopes = 24 distinct scope types.
Not only is this more difficult to understand, but there is no value in defining
a “context-specific” version of any
BlockScope.DEFINITION fields. As a result of that and other conflicting or
not useful Scope combinations, it is likely that fewer than half of the 24
possible Scope values would be used.
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.