diff --git a/openedx/core/lib/xblock_serializer/block_serializer.py b/openedx/core/lib/xblock_serializer/block_serializer.py index 9e3d218e477a..22baac9dae69 100644 --- a/openedx/core/lib/xblock_serializer/block_serializer.py +++ b/openedx/core/lib/xblock_serializer/block_serializer.py @@ -171,6 +171,8 @@ def _serialize_html_block(self, block) -> etree.Element: olx_node.attrib["editor"] = block.editor if block.use_latex_compiler: olx_node.attrib["use_latex_compiler"] = "true" + if "use_mfe_theming" in block.fields and block.use_mfe_theming: + olx_node.attrib["use_mfe_theming"] = "true" for field_name in block.fields: if ( field_name.startswith(("upstream", "downstream")) or field_name == "top_level_downstream_parent_key" diff --git a/openedx/core/lib/xblock_serializer/test_api.py b/openedx/core/lib/xblock_serializer/test_api.py index d8703661693d..6a45a15e09fc 100644 --- a/openedx/core/lib/xblock_serializer/test_api.py +++ b/openedx/core/lib/xblock_serializer/test_api.py @@ -189,6 +189,60 @@ def test_html_with_fields(self): """ ) + def test_html_with_use_mfe_theming(self): + """ Test that the extracted HTML block's use_mfe_theming setting is serialized. """ + course = CourseFactory.create(display_name='test course', run="Testing_course") + html_block = BlockFactory.create( + parent_location=course.location, + category="html", + display_name="Themed HTML Block", + use_mfe_theming=True, + data="🍔", + ) + serialized = api.serialize_xblock_to_olx(html_block) + self.assertXmlEqual( + serialized.olx_str, + f""" + + """ + ) + + def test_html_without_use_mfe_theming_is_not_serialized(self): + """ Blocks that leave the setting unset must not gain the attribute. """ + course = CourseFactory.create(display_name='test course', run="Testing_course") + html_block = BlockFactory.create( + parent_location=course.location, + category="html", + data="🍔", + ) + serialized = api.serialize_xblock_to_olx(html_block) + assert "use_mfe_theming" not in serialized.olx_str + + def test_html_with_use_mfe_theming_false_is_not_serialized(self): + """ A block carrying the default value must not gain the attribute either. + + Syncing a library into a course copies every declared field into the + block's field data, so the setting arrives present and False rather than + absent. Writing it out would put use_mfe_theming="false" on every synced + HTML block. + """ + course = CourseFactory.create(display_name='test course', run="Testing_course") + html_block = BlockFactory.create( + parent_location=course.location, + category="html", + data="🍔", + use_mfe_theming=False, + ) + serialized = api.serialize_xblock_to_olx(html_block) + assert "use_mfe_theming" not in serialized.olx_str + def test_export_sequential(self): """ Export a sequential from the toy course, including all of its children. diff --git a/pyproject.toml b/pyproject.toml index cc96b2daefc4..14dd7317aad0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -293,6 +293,12 @@ constraint-dependencies = [ "djangorestframework<3.18", "openedx-forum<0.6.0", ] + +# TODO: drop this once xblocks-contrib ships a release carrying the Text +# (HTML) block's use_mfe_theming field. Tracked by openedx/xblocks-core#308. +[tool.uv.sources] +xblocks-contrib = { git = "https://github.com/open-craft/xblocks-core.git", rev = "rpenido/text-xblock-include-theme" } + [tool.edx_lint] uv_constraints = [ # Date: 2025-10-07 diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 5d9f5f17135a..480a384f688d 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -1318,7 +1318,7 @@ xblock==6.3.4 xblock-drag-and-drop-v2==5.1.2 xblock-google-drive==0.8.2 xblock-poll==1.16.1 -xblocks-contrib==1.0.7 +xblocks-contrib @ git+https://github.com/open-craft/xblocks-core.git@b9b5d72a17d4ea562f0b29f28529d038ca0ef664 xmlsec==1.3.14 # via python3-saml xss-utils==1.1.0 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index e484be8bed19..d20ca8d5dcc2 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1598,7 +1598,7 @@ xblock==6.3.4 xblock-drag-and-drop-v2==5.1.2 xblock-google-drive==0.8.2 xblock-poll==1.16.1 -xblocks-contrib==1.0.7 +xblocks-contrib @ git+https://github.com/open-craft/xblocks-core.git@b9b5d72a17d4ea562f0b29f28529d038ca0ef664 xmlsec==1.3.14 # via python3-saml xss-utils==1.1.0 diff --git a/uv.lock b/uv.lock index 56ee5e338ade..1ffdae5db53d 100644 --- a/uv.lock +++ b/uv.lock @@ -5312,7 +5312,7 @@ bundled = [ { name = "xblock-drag-and-drop-v2" }, { name = "xblock-google-drive" }, { name = "xblock-poll" }, - { name = "xblocks-contrib" }, + { name = "xblocks-contrib", git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme" }, ] ci = [ { name = "tox" }, @@ -5386,7 +5386,7 @@ development = [ { name = "xblock-drag-and-drop-v2" }, { name = "xblock-google-drive" }, { name = "xblock-poll" }, - { name = "xblocks-contrib" }, + { name = "xblocks-contrib", git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme" }, ] django42 = [ { name = "beautifulsoup4" }, @@ -5434,7 +5434,7 @@ django42 = [ { name = "xblock-drag-and-drop-v2" }, { name = "xblock-google-drive" }, { name = "xblock-poll" }, - { name = "xblocks-contrib" }, + { name = "xblocks-contrib", git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme" }, ] django52 = [ { name = "beautifulsoup4" }, @@ -5482,7 +5482,7 @@ django52 = [ { name = "xblock-drag-and-drop-v2" }, { name = "xblock-google-drive" }, { name = "xblock-poll" }, - { name = "xblocks-contrib" }, + { name = "xblocks-contrib", git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme" }, ] docs = [ { name = "code-annotations" }, @@ -5508,7 +5508,7 @@ docs = [ { name = "xblock-drag-and-drop-v2" }, { name = "xblock-google-drive" }, { name = "xblock-poll" }, - { name = "xblocks-contrib" }, + { name = "xblocks-contrib", git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme" }, ] testing = [ { name = "beautifulsoup4" }, @@ -5555,7 +5555,7 @@ testing = [ { name = "xblock-drag-and-drop-v2" }, { name = "xblock-google-drive" }, { name = "xblock-poll" }, - { name = "xblocks-contrib" }, + { name = "xblocks-contrib", git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme" }, ] [[package]] @@ -8567,8 +8567,8 @@ wheels = [ [[package]] name = "xblocks-contrib" -version = "1.0.7" -source = { registry = "https://pypi.org/simple" } +version = "0.0" +source = { git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme#b9b5d72a17d4ea562f0b29f28529d038ca0ef664" } dependencies = [ { name = "beautifulsoup4" }, { name = "chem" }, @@ -8600,10 +8600,6 @@ dependencies = [ { name = "wrapt" }, { name = "xblock" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/0f/6dfd257da62f54023f89571f2145641b6def174bd354680bd1c029cb47ce/xblocks_contrib-1.0.7.tar.gz", hash = "sha256:23022249dfdc2960f59005064d337236806a909be055aca45c2c37123d8aea01", size = 22138641, upload-time = "2026-10-12T06:09:12.919Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/35/33db566382d6f369267ccc82bae744c354fbbaa5ed6539c04982a003f375/xblocks_contrib-1.0.7-py3-none-any.whl", hash = "sha256:8c52480066b3df10b4219922a0a491715a975d105575b138f90cfab1ed5a5fd9", size = 3768557, upload-time = "2026-10-12T06:09:11.061Z" }, -] [[package]] name = "xmlsec"