From 9dd0aba53aca97dd5b72133eb5c6ca5b8b7003a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Tue, 29 Sep 2026 16:22:47 -0300 Subject: [PATCH 1/5] fix: serialize the HTML block's include_theme setting --- .../lib/xblock_serializer/block_serializer.py | 3 ++ .../core/lib/xblock_serializer/test_api.py | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/openedx/core/lib/xblock_serializer/block_serializer.py b/openedx/core/lib/xblock_serializer/block_serializer.py index 9e3d218e477a..5c6f5c13bb13 100644 --- a/openedx/core/lib/xblock_serializer/block_serializer.py +++ b/openedx/core/lib/xblock_serializer/block_serializer.py @@ -171,6 +171,9 @@ 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" + # The deprecated built-in html block does not declare this field. + if "include_theme" in block.fields and block.include_theme: + olx_node.attrib["include_theme"] = "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..47cc7b9a885d 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_include_theme(self): + """ Test that the extracted HTML block's include_theme 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", + include_theme=True, + data="🍔", + ) + serialized = api.serialize_xblock_to_olx(html_block) + self.assertXmlEqual( + serialized.olx_str, + f""" + + """ + ) + + def test_html_without_include_theme_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 "include_theme" not in serialized.olx_str + + def test_html_with_include_theme_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 include_theme="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="🍔", + include_theme=False, + ) + serialized = api.serialize_xblock_to_olx(html_block) + assert "include_theme" not in serialized.olx_str + def test_export_sequential(self): """ Export a sequential from the toy course, including all of its children. From 5793e247fc82021b819b3ec5621be593c8567b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Fri, 2 Oct 2026 03:00:57 -0300 Subject: [PATCH 2/5] build: pin xblocks-contrib to the branch carrying include_theme --- pyproject.toml | 6 ++++++ requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- uv.lock | 20 ++++++++------------ 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cc96b2daefc4..5dd5eba4ffa1 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 include_theme 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..9547ac475c4b 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@cf783e1499559ff1bdb8855e93c10ab01b8363fe 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..78e5f9197d16 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@cf783e1499559ff1bdb8855e93c10ab01b8363fe xmlsec==1.3.14 # via python3-saml xss-utils==1.1.0 diff --git a/uv.lock b/uv.lock index 56ee5e338ade..57889f76aa11 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#cf783e1499559ff1bdb8855e93c10ab01b8363fe" } 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" From ef8614448f648d5bf646ca98050654200f49de1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Mon, 5 Oct 2026 16:02:07 -0300 Subject: [PATCH 3/5] docs: removing unnecessary comment --- openedx/core/lib/xblock_serializer/block_serializer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openedx/core/lib/xblock_serializer/block_serializer.py b/openedx/core/lib/xblock_serializer/block_serializer.py index 5c6f5c13bb13..4cd6d5744ae3 100644 --- a/openedx/core/lib/xblock_serializer/block_serializer.py +++ b/openedx/core/lib/xblock_serializer/block_serializer.py @@ -171,7 +171,6 @@ 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" - # The deprecated built-in html block does not declare this field. if "include_theme" in block.fields and block.include_theme: olx_node.attrib["include_theme"] = "true" for field_name in block.fields: From ca010322611eff308c5b058aafdca5b3cf09c546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Mon, 19 Oct 2026 14:25:30 -0300 Subject: [PATCH 4/5] refactor: rename include_theme to use_mfe_theming --- .../lib/xblock_serializer/block_serializer.py | 4 ++-- .../core/lib/xblock_serializer/test_api.py | 20 +++++++++---------- pyproject.toml | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openedx/core/lib/xblock_serializer/block_serializer.py b/openedx/core/lib/xblock_serializer/block_serializer.py index 4cd6d5744ae3..22baac9dae69 100644 --- a/openedx/core/lib/xblock_serializer/block_serializer.py +++ b/openedx/core/lib/xblock_serializer/block_serializer.py @@ -171,8 +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 "include_theme" in block.fields and block.include_theme: - olx_node.attrib["include_theme"] = "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 47cc7b9a885d..6a45a15e09fc 100644 --- a/openedx/core/lib/xblock_serializer/test_api.py +++ b/openedx/core/lib/xblock_serializer/test_api.py @@ -189,14 +189,14 @@ def test_html_with_fields(self): """ ) - def test_html_with_include_theme(self): - """ Test that the extracted HTML block's include_theme setting is serialized. """ + 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", - include_theme=True, + use_mfe_theming=True, data="🍔", ) serialized = api.serialize_xblock_to_olx(html_block) @@ -207,14 +207,14 @@ def test_html_with_include_theme(self): copied_from_block="{str(html_block.location)}" url_name="Themed_HTML_Block" display_name="Themed HTML Block" - include_theme="true" + use_mfe_theming="true" > """ ) - def test_html_without_include_theme_is_not_serialized(self): + 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( @@ -223,14 +223,14 @@ def test_html_without_include_theme_is_not_serialized(self): data="🍔", ) serialized = api.serialize_xblock_to_olx(html_block) - assert "include_theme" not in serialized.olx_str + assert "use_mfe_theming" not in serialized.olx_str - def test_html_with_include_theme_false_is_not_serialized(self): + 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 include_theme="false" on every synced + 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") @@ -238,10 +238,10 @@ def test_html_with_include_theme_false_is_not_serialized(self): parent_location=course.location, category="html", data="🍔", - include_theme=False, + use_mfe_theming=False, ) serialized = api.serialize_xblock_to_olx(html_block) - assert "include_theme" not in serialized.olx_str + assert "use_mfe_theming" not in serialized.olx_str def test_export_sequential(self): """ diff --git a/pyproject.toml b/pyproject.toml index 5dd5eba4ffa1..14dd7317aad0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -295,7 +295,7 @@ constraint-dependencies = [ ] # TODO: drop this once xblocks-contrib ships a release carrying the Text -# (HTML) block's include_theme field. Tracked by openedx/xblocks-core#308. +# (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" } From 3d5327c5899810b72adef267928e2ec42118d236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Thu, 29 Oct 2026 21:20:03 -0300 Subject: [PATCH 5/5] build: repin xblocks-contrib to the renamed theming label --- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- uv.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 9547ac475c4b..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 @ git+https://github.com/open-craft/xblocks-core.git@cf783e1499559ff1bdb8855e93c10ab01b8363fe +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 78e5f9197d16..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 @ git+https://github.com/open-craft/xblocks-core.git@cf783e1499559ff1bdb8855e93c10ab01b8363fe +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 57889f76aa11..1ffdae5db53d 100644 --- a/uv.lock +++ b/uv.lock @@ -8568,7 +8568,7 @@ wheels = [ [[package]] name = "xblocks-contrib" version = "0.0" -source = { git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme#cf783e1499559ff1bdb8855e93c10ab01b8363fe" } +source = { git = "https://github.com/open-craft/xblocks-core.git?rev=rpenido%2Ftext-xblock-include-theme#b9b5d72a17d4ea562f0b29f28529d038ca0ef664" } dependencies = [ { name = "beautifulsoup4" }, { name = "chem" },