Metadata-Version: 1.1
Name: xblock-utils
Version: 3.4.0
Summary: Various utilities for XBlocks
Home-page: https://github.com/openedx/xblock-utils
Author: edX
Author-email: oscm@edx.org
License: UNKNOWN
Description: xblock-utils: Various utilities for XBlocks
        ###########################################
        
        |pypi-badge| |ci-badge| |codecov-badge| |doc-badge| |pyversions-badge|
        |license-badge| |status-badge|
        
        Purpose
        *******
        
        These are a collection of utility functions, base test classes and
        documentation that are useful for any XBlocks.
        
        Getting Started
        ***************
        
        Developing
        ==========
        
        One Time Setup
        --------------
        .. code-block::
        
          # 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-utils
        
        
        Every time you develop something in this repo
        ---------------------------------------------
        .. code-block::
        
          # 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.
        
        Deploying
        =========
        
        This component is automatically deployed to PyPI whenever new GitHub releases are made.
        
        To deploy this library.
        
        #. Update the version in ``xblockutils/__init__.py`` based on semantic versioning.
        
        #. Create a new GitHub release with a tag matching the version.
        
        #. Automation should build and deploy the version to PyPI
        
        Getting Help
        ************
        
        Documentation
        =============
        
        Start by going through `the documentation`_.  If you need more help see below.
        
        .. _the documentation: https://docs.openedx.org/projects/xblock-utils
        
        More Help
        =========
        
        If you're having trouble, we have discussion forums at
        https://discuss.openedx.org where you can connect with others in the
        community.
        
        Our real-time conversations are on Slack. You can request a `Slack
        invitation`_, then join our `community 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/issues
        
        For more information about these options, see the `Project Getting Help`_ page.
        
        .. _Slack invitation: https://openedx.org/slack
        .. _community Slack workspace: https://openedx.slack.com/
        .. _Project Getting Help: https://openedx.org/getting-help
        
        License
        *******
        
        The code in this repository is licensed under the AGPLv3 unless
        otherwise noted.
        
        Please see `the LICENSE <LICENSE>`_ for details.
        
        Contributing
        ************
        
        Contributions are very welcome.
        Please read `How To Contribute <https://openedx.org/r/how-to-contribute>`_ for 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 Conduct
        ****************************
        
        All community members are expected to follow the `Open edX Code of Conduct`_.
        
        .. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/
        
        People
        ******
        
        The assigned maintainers for this component and other project details may be
        found in `Backstage`_. Backstage pulls this data from the ``catalog-info.yaml``
        file in this repo.
        
        .. _Backstage: https://backstage.openedx.org/catalog/default/component/xblock-utils
        
        Reporting Security Issues
        *************************
        
        Please do not report security issues in public. Please email security@openedx.org.
        
        .. |pypi-badge| image:: https://img.shields.io/pypi/v/xblock-utils.svg
            :target: https://pypi.python.org/pypi/xblock-utils/
            :alt: PyPI
        
        .. |ci-badge| image:: https://github.com/openedx/xblock-utils/workflows/Python%20CI/badge.svg?branch=main
            :target: https://github.com/openedx/xblock-utils/actions
            :alt: CI
        
        .. |codecov-badge| image:: https://codecov.io/github/openedx/xblock-utils/coverage.svg?branch=main
            :target: https://codecov.io/github/openedx/xblock-utils?branch=main
            :alt: Codecov
        
        .. |doc-badge| image:: https://readthedocs.org/projects/xblock-utils/badge/?version=latest
            :target: https://docs.openedx.org/projects/xblock-utils/
            :alt: Documentation
        
        .. |pyversions-badge| image:: https://img.shields.io/pypi/pyversions/xblock-utils.svg
            :target: https://pypi.python.org/pypi/xblock-utils/
            :alt: Supported Python versions
        
        .. |license-badge| image:: https://img.shields.io/github/license/openedx/xblock-utils.svg
            :target: https://github.com/openedx/xblock-utils/blob/main/LICENSE
            :alt: License
        
        .. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen
        
        More Documentation
        ******************
        
        StudioEditableXBlockMixin
        =========================
        
        .. code:: python
        
            from xblockutils.studio_editable import StudioEditableXBlockMixin
        
        This mixin will automatically generate a working ``studio_view`` form
        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
        called ``editable_fields``, set to a tuple of the names of the fields
        you want your user to be able to edit.
        
        .. code:: python
        
            @XBlock.needs("i18n")
            class ExampleBlock(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 optional
        ``display_name``, ``help``, ``default``, and ``values`` settings 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 override
        ``validate_field_data(self, validation, data)`` and/or
        ``clean_studio_edits(self, data)`` - see the source code for details.
        
        Supported field types:
        
        * Boolean:
          ``field_name = Boolean(display_name="Field Name")``
        * Float:
          ``field_name = Float(display_name="Field Name")`` 
        * Integer:
          ``field_name = Integer(display_name="Field Name")`` 
        * String:
          ``field_name = String(display_name="Field Name")`` 
        * 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)``
        
          - The ``List`` declaration must include the property ``list_style='set'`` to
            indicate that the ``List`` field is being used with set semantics.
          - The ``List`` declaration must also define a ``list_values_provider`` method
            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 types
        
          - ``list_field = List(display_name="Ordered List", default=[])``
          - ``dict_field = Dict(display_name="Normal Dict", default={})``
        
        Supported field options (all field types):
        
        * ``values`` can define a list of possible options, changing the UI element
          to a select box. Values can be set to any of the formats `defined in the
          XBlock source code <https://github.com/openedx/XBlock/blob/master/xblock/fields.py>`__:
          
          - 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 does
            *not* get passed the XBlock instance or runtime, so it cannot be a
            normal member function)
        * ``values_provider`` can 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 to ``True``. Set ``False`` to 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: |Screenshot 1|
        
        StudioContainerXBlockMixin
        ==========================
        
        .. code:: python
        
            from xblockutils.studio_editable import StudioContainerXBlockMixin
        
        This mixin helps to create XBlocks that allow content authors to add,
        remove, or reorder child blocks. By removing any existing
        ``author_view`` and 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 override ``author_edit_view`` 
        and set ``can_add=True`` when calling ``render_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: |Screenshot 2|
        
        SeleniumXBlockTest
        ==================
        
        .. code:: python
        
            from xblockutils.base_test import SeleniumXBlockTest
        
        This 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:
        
        .. code:: python
        
            class TestStudentView(SeleniumXBlockTest):
                """
                Test the Student View of MyCoolXBlock
                """
                def setUp(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")
        
                def test_shows_field_2(self):
                    """
                    The xblock should display the text value of field2.
                    """
                    self.assertIn("hello", self.element.text)
        
        StudioEditableBaseTest
        ======================
        
        .. code:: python
        
            from xblockutils.studio_editable_test import StudioEditableBaseTest
        
        This is a subclass of ``SeleniumXBlockTest`` that adds a few helper
        methods useful for testing the ``studio_view`` of any XBlock using
        ``StudioEditableXBlockMixin``.
        
        child\_isinstance
        =================
        
        .. code:: python
        
            from xblockutils.helpers import child_isinstance
        
        If your XBlock needs to find children/descendants of a particular
        class/mixin, you should use
        
        .. code:: python
        
            child_isinstance(self, child_usage_id, SomeXBlockClassOrMixin)
        
        rather than calling
        
        .. code:: python
        
            ``isinstance(self.runtime.get_block(child_usage_id), SomeXBlockClassOrMixin)``.
        
        On runtimes such as those in edx-platform, ``child_isinstance`` is
        orders of magnitude faster.
        
        .. |Screenshot 1| image:: https://cloud.githubusercontent.com/assets/945577/6341782/7d237966-bb83-11e4-9344-faa647056999.png
        .. |Screenshot 2| image:: https://cloud.githubusercontent.com/assets/945577/6341803/d0195ec4-bb83-11e4-82f6-8052c9f70690.png
        
        XBlockWithSettingsMixin
        =======================
        
        This 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 details
        
        ThemableXBlockMixin
        ===================
        
        This 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
        
Platform: UNKNOWN
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.2
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: Implementation :: CPython
