Settings and theme support#
Accessing XBlock specific settings#
XBlock utils provide a mixin to simplify accessing instance-wide
XBlock-specific configuration settings: XBlockWithSettingsMixin
.
This mixin aims to provide a common interface for pulling XBlock
settings from the LMS
SettingsService.
SettingsService
allows individual XBlocks to access environment and
django settings in an isolated manner:
XBlock settings are represented as dictionary stored in django settings and populated from environment *.json files (cms.env.json and lms.env.json)
Each XBlock is associated with a particular key in that dictionary: by default an XBlock’s class name is used, but XBlocks can override it using the
block_settings_key
attribute/property.
Please note that at the time of writing the implementation of
SettingsService
assumed “good citizenship” behavior on the part of
XBlocks, i.e. it does not check for key collisions and allows modifying
mutable settings. Both SettingsService
and
XBlockWithSettingsMixin
are not concerned with contents of settings
bucket and return them as is. Refer to the SettingsService
docstring
and implementation for more details.
Using XBlockWithSettingsMixin#
In order to use SettingsService
and XBlockWithSettingsMixin
, a
client XBlock must require it via standard
XBlock.wants('settings')
or XBlock.needs('settings')
decorators.
The mixins themselves are not decorated as this would not result in all
descendant XBlocks to also be decorated.
With XBlockWithSettingsMixin
and wants
decorator applied,
obtaining XBlock settings is as simple as
self.get_xblock_settings() # returns settings bucket or None
self.get_xblock_settings(default=something) # returns settings bucket or "something"
In case of missing or inaccessible XBlock settings (i.e. no settings
service in runtime, no XBLOCK_SETTINGS
in settings, or XBlock
settings key is not found) default
value is used.
Theming support#
XBlock theming support is built on top of XBlock-specific settings.
XBlock utils provide ThemableXBlockMixin
to streamline using XBlock
themes.
XBlock theme support is designed with two major design goals:
Allow for a different look and feel of an XBlock in different environments.
Use a pluggable approach to hosting themes, so that adding a new theme will not require forking an XBlock.
The first goal made using SettingsService
and
XBlockWithSettingsMixin
an obvious choice to store and obtain theme
configuration. The second goal dictated the configuration format - it is
a dictionary (or dictionary-like object) with the following keys:
package
- “top-level” selector specifying package which hosts theme fileslocations
- a list of locations within that package
Examples:
# will search for files red.css and small.css in my_xblock package
{
'package': 'my_xblock',
'locations': ['red.css', 'small.css']
}
# will search for files public/themes/red.css in my_other_xblock.assets package
default_theme_config = {
'package': 'my_other_xblock.assets',
'locations': ['public/themes/red.css']
}
Theme files must be included into package (see python docs for details). At the time of writing it is not possible to fetch theme files from multiple packages.
Note: XBlock themes are not LMS themes - they are just additional
CSS files included into an XBlock fragment when the corresponding XBlock
is rendered. However, it is possible to misuse this feature to change
look and feel of the entire LMS, as contents of CSS files are not
checked and might contain selectors that apply to elements outside of
the XBlock in question. Hence, it is advised to scope all CSS rules
belonging to a theme with a global CSS selector
.themed-xblock.<root xblock element class>
, e.g.
.themed-xblock.poll-block
. Note that the themed-xblock
class is
not automatically added by ThemableXBlockMixin
, so one needs to add
it manually.
Using ThemableXBlockMixin#
In order to use ThemableXBlockMixin
, a descendant XBlock must also
be a descendant of XBlockWithSettingsMixin
(XBlock.wants
decorator requirement applies) or provide a similar interface for
obtaining the XBlock settings bucket.
There are three configuration parameters that govern
ThemableXBlockMixin
behavior:
default_theme_config
- default theme configuration in case no theme configuration can be obtainedtheme_key
- a key in XBlock settings bucket that stores theme configurationblock_settings_key
- inherited fromXBlockWithSettingsMixin
if used in conjunction with it
It is safe to omit default_theme_config
or set it to None
in
case no default theme is available. In this case,
ThemableXBlockMixin
will skip including theme files if no theme is
specified via settings.
ThemableXBlockMixin
exposes two methods:
get_theme()
- this is used to get theme configuration. Default implementation usesget_xblock_settings
andtheme_key
, descendants are free to override it. Normally, it should not be called directly.include_theme_files(fragment)
- this method is an entry point toThemableXBlockMixin
functionality. It callsget_theme
to obtain theme configuration, fetches theme files and includes them into fragment.fragment
must be a web_fragments.fragment instance.
So, having met usage requirements and set up theme configuration parameters, including theme into XBlock fragment is a one liner:
self.include_theme_files(fragment)