-
Notifications
You must be signed in to change notification settings - Fork 25
Settings and theme support
XBlock utils provide mixin to simplify accessing instance-wide XBlock-specific configuration settings: XBlockWithSettingsMixin
. This mixin is aimed to provide a common interface for pulling XBlock settings from LMS SettingsService
.
SettingsService allows individual XBlocks 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 XBlock class name is used, but XBlocks can override it using
block_settings_key
attribute/property.
Please note that at the time of writing implementation of SettingsService assumed good citizenship XBlock behavior, i.e. it does not check for key collisions and allows modifying mutable settings. Both SettingsService and XBlockWithSettingsMixin are not concerned of contents of settings bucket and return them as is. Refer to SettingsService docstring and implementation for more details.
In order to use SettingsService and XBlockWithSettingsMixin, client XBlock must require it via standard XBlock.wants('settings')
or XBlock.needs('settings')
decorators. Mixin is not decorated as it does not result in all descendant XBlocks to be also 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.
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 different look and feel of an XBlock in different environments.
- Use pluggable approach to hosting themes, so that adding a new theme would 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 them configuration format - it is a dictionary (or dictionary-like object) with the following keys:
-
package
- "top-level" selector specifying which package hosts theme files -
locations
- 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). By 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 XBlock fragment when XBlock is rendered. However, it is possible to misuse this feature to change look and feel of entire LMS, as contents of css files are not checked and might contain too wide selectors. Hence, it is advised to scope all theme css rules with global css selector .themed-xblock.<root xblock element class
, i.e. .themed-xblock.poll-block
. Note that themed-xblock
class is not automatically added by ThemableXBlockMixin, so one need to add it manually.
In order to use ThemableXBlockMixin, descendant XBlock must also be a descendant of XBlockWithSettingsMixin (XBlock.wants
decorator requirement applies) or provide similar interface for obtaining 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 obtined * theme_key - a key in XBlock settings bucket that stores theme configuration
- block_settings_key - inherited from XBlockWithSettingsMixin if used in conjunction with it
It is safe to omit or set to None default_theme_config
in case no default theme is available. In such 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 uses
get_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 to ThemableXBlockMixin functionality - it calls
get_theme
to obtain theme configuration, fetches theme files and includes them into fragment.fragment
must be anXBlock.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)