Package: xblock-utils
PurposeThese are a collection of utility functions, base test classes and
documentation that are useful for any XBlocks.⚠️ Deprecation Notice ⚠️Effective Date:September 26, 2023Repository Migration:Thisxblock-utilsrepository has beendeprecatedas of September 26, 2023, and the code and documentation have been migrated to theXblockrepository.This decision was made to streamline and consolidate our codebase.The migration process was completed through this Pull Request:PR #669Archival: We are going to archive thexblock-utilsrepository. This means that it will become read-only, and no further updates or changes will be accepted.We appreciate your understanding and cooperation during this transition. If you have any questions or concerns, please don’t hesitate to reach out to us through theXBlockrepository’s issue tracker.Thank you for your continued support and contributions to the Open edX community.Getting StartedDevelopingOne Time Setup# Clone the repository
git clone git@github.com:openedx/xblock-utils.git
cd xblock-utils

# Set up a virtualenv with the same name as the repo and activate it
# Here's how you might do that if you have virtualenvwrapper setup.
mkvirtualenv -p python3.8 xblock-utilsEvery time you develop something in this repo# Activate the virtualenv
# Here's how you might do that if you're using virtualenvwrapper.
workon xblock-utils

# Grab the latest code
git checkout master
git pull

# Install/update the dev requirements
make requirements

# Run the tests and quality checks (to verify the status before you make any changes)
make test

# Make a new branch for your changes
git checkout -b <your_github_username>/<short_description>

# Using your favorite editor, edit the code to make your change.
vim ...

# Temporary until https://github.com/openedx/xblock-utils/issues/199 is resolved
mkdir var
touch var/workbench.log

# Run your new tests
pytest ./path/to/new/tests

# Run all the tests and quality checks
make test

# Commit all your changes
git commit ...
git push

# Open a PR and ask for review.DeployingThis component is automatically deployed to PyPI whenever new GitHub releases are made.To deploy this library.Update the version inxblockutils/__init__.pybased on semantic versioning.Create a new GitHub release with a tag matching the version.Automation should build and deploy the version to PyPIGetting HelpDocumentationStart by going throughthe documentation.  If you need more help see below.More HelpIf you’re having trouble, we have discussion forums athttps://discuss.openedx.orgwhere you can connect with others in the
community.Our real-time conversations are on Slack. You can request aSlack
invitation, then join ourcommunity Slack workspace.For anything non-trivial, the best path is to open an issue in this
repository with as many details about the issue you are facing as you
can provide.https://github.com/openedx/xblock-utils/issuesFor more information about these options, see theProject Getting Helppage.LicenseThe code in this repository is licensed under the AGPLv3 unless
otherwise noted.Please seethe LICENSEfor details.ContributingContributions are very welcome.
Please readHow To Contributefor details.This project is currently accepting all types of contributions, bug fixes,
security fixes, maintenance work, or new features.  However, please make sure
to have a discussion about your new feature idea with the maintainers prior to
beginning development to maximize the chances of your change being accepted.
You can start a conversation by creating a new issue on this repo summarizing
your idea.The Open edX Code of ConductAll community members are expected to follow theOpen edX Code of Conduct.PeopleThe assigned maintainers for this component and other project details may be
found inBackstage. Backstage pulls this data from thecatalog-info.yamlfile in this repo.Reporting Security IssuesPlease do not report security issues in public. Please emailsecurity@openedx.org.More DocumentationStudioEditableXBlockMixinfromxblockutils.studio_editableimportStudioEditableXBlockMixinThis mixin will automatically generate a workingstudio_viewform
that allows content authors to edit the fields of your XBlock. To use,
simply add the class to your base class list, and add a new class field
callededitable_fields, set to a tuple of the names of the fields
you want your user to be able to edit.@XBlock.needs("i18n")classExampleBlock(StudioEditableXBlockMixin,XBlock):...mode=String(display_name="Mode",help="Determines the behaviour of this component. Standard is recommended.",default='standard',scope=Scope.content,values=('standard','crazy'))editable_fields=('mode','display_name')That’s all you need to do. The mixin will read the optionaldisplay_name,help,default, andvaluessettings from
the fields you mention and build the editor form as well as an AJAX save
handler.If you want to validate the data, you can overridevalidate_field_data(self, validation, data)and/orclean_studio_edits(self, data)- see the source code for details.Supported field types:Boolean:field_name =Boolean(display_name="FieldName")Float:field_name =Float(display_name="FieldName")Integer:field_name =Integer(display_name="FieldName")String:field_name =String(display_name="FieldName")String (multiline):field_name = String(multiline_editor=True, resettable_editor=False)String (html):field_name =String(multiline_editor='html',resettable_editor=False)Any of the above will use a dropdown menu if they have a pre-defined
list of possible values.List of unordered unique values (i.e. sets) drawn from a small set of
possible values:field_name =List(list_style='set',list_values_provider=some_method)TheListdeclaration must include the propertylist_style='set'to
indicate that theListfield is being used with set semantics.TheListdeclaration must also define alist_values_providermethod
which will be called with the block as its only parameter and which must
return a list of possible values.Rudimentary support for Dict, ordered List, and any other JSONField-derived field typeslist_field =List(display_name="OrderedList",default=[])dict_field =Dict(display_name="NormalDict",default={})Supported field options (all field types):valuescan define a list of possible options, changing the UI element
to a select box. Values can be set to any of the formatsdefined in the
XBlock source code:A finite set of elements:[1, 2, 3]A finite set of elements where the display names differ from the values:[
    {"display_name": "Always", "value": "always"},
    {"display_name": "Past Due", "value": "past_due"},
]A range for floating point numbers with specific increments:{"min": 0 , "max": 10, "step": .1}A callable that returns one of the above. (Note: the callable doesnotget passed the XBlock instance or runtime, so it cannot be a
normal member function)values_providercan define a callable that accepts the XBlock
instance as an argument, and returns a list of possible values in one
of the formats listed above.resettable_editor- defaults toTrue. SetFalseto hide the
“Reset” button used to return a field to its default value by removing
the field’s value from the XBlock instance.Basic screenshot:StudioContainerXBlockMixinfromxblockutils.studio_editableimportStudioContainerXBlockMixinThis mixin helps to create XBlocks that allow content authors to add,
remove, or reorder child blocks. By removing any existingauthor_viewand adding this mixin, you’ll get editable,
re-orderable, and deletable child support in Studio. To enable authors to
add arbitrary blocks as children, simply overrideauthor_edit_viewand setcan_add=Truewhen callingrender_children- see the
source code. To restrict authors so they can add only specific types of
child blocks or a limited number of children requires custom HTML.An example is the mentoring XBlock:SeleniumXBlockTestfromxblockutils.base_testimportSeleniumXBlockTestThis is a base class that you can use for writing Selenium integration
tests that are hosted in the XBlock SDK (Workbench).Here is an example:classTestStudentView(SeleniumXBlockTest):"""
    Test the Student View of MyCoolXBlock
    """defsetUp(self):super(TestStudentView,self).setUp()self.set_scenario_xml('<mycoolblock display_name="Test Demo Block" field2="hello" />')self.element=self.go_to_view("student_view")deftest_shows_field_2(self):"""
        The xblock should display the text value of field2.
        """self.assertIn("hello",self.element.text)StudioEditableBaseTestfromxblockutils.studio_editable_testimportStudioEditableBaseTestThis is a subclass ofSeleniumXBlockTestthat adds a few helper
methods useful for testing thestudio_viewof any XBlock usingStudioEditableXBlockMixin.child_isinstancefromxblockutils.helpersimportchild_isinstanceIf your XBlock needs to find children/descendants of a particular
class/mixin, you should usechild_isinstance(self,child_usage_id,SomeXBlockClassOrMixin)rather than calling``isinstance(self.runtime.get_block(child_usage_id),SomeXBlockClassOrMixin)``.On runtimes such as those in edx-platform,child_isinstanceis
orders of magnitude faster.XBlockWithSettingsMixinThis mixin provides access to instance-wide XBlock-specific configuration settings.
See [wiki page](https://github.com/openedx/xblock-utils/wiki/Settings-and-theme-support#accessing-xblock-specific-settings) for detailsThemableXBlockMixinThis mixin provides XBlock theming capabilities built on top of XBlock-specific settings.
See [wiki page](https://github.com/openedx/xblock-utils/wiki/Settings-and-theme-support#theming-support) for details