From b9bd3d29212db876bad4d35ee2a651eaa12d7e42 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/3] 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 5b6f1ad26c581751fd1d869f8cae86ac0e78066f 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/3] 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 52d2cb789126..4b29702cfd28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -293,6 +293,12 @@ constraint-dependencies = [ "edx-enterprise==8.17.0", "djangorestframework<3.18", ] + +# 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 cba7720bb47c..1646e5ccbc86 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -1301,7 +1301,7 @@ xblock==6.3.3 xblock-drag-and-drop-v2==5.1.1 xblock-google-drive==0.8.2 xblock-poll==1.16.1 -xblocks-contrib==1.0.6 +xblocks-contrib @ git+https://github.com/open-craft/xblocks-core.git@25702c61b6a9f3cf1afbc6e49a60790ca90f34c1 xmlsec==1.3.14 # via python3-saml xss-utils==1.0.0 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 1cedc06a830a..80448b5a1afb 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1563,7 +1563,7 @@ xblock==6.3.3 xblock-drag-and-drop-v2==5.1.1 xblock-google-drive==0.8.2 xblock-poll==1.16.1 -xblocks-contrib==1.0.6 +xblocks-contrib @ git+https://github.com/open-craft/xblocks-core.git@25702c61b6a9f3cf1afbc6e49a60790ca90f34c1 xmlsec==1.3.14 # via python3-saml xss-utils==1.0.0 diff --git a/uv.lock b/uv.lock index 4b0ef1aefdfe..a7449b5e3909 100644 --- a/uv.lock +++ b/uv.lock @@ -5068,7 +5068,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" }, @@ -5142,7 +5142,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" }, @@ -5190,7 +5190,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" }, @@ -5238,7 +5238,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" }, @@ -5264,7 +5264,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" }, @@ -5311,7 +5311,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]] @@ -8063,8 +8063,8 @@ wheels = [ [[package]] name = "xblocks-contrib" -version = "1.0.6" -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#25702c61b6a9f3cf1afbc6e49a60790ca90f34c1" } dependencies = [ { name = "beautifulsoup4" }, { name = "chem" }, @@ -8096,10 +8096,6 @@ dependencies = [ { name = "wrapt" }, { name = "xblock" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/0e/41c6147c86486cae3ceaa5a9338dfae29c3f3ecaf82c5bb4e7fb5843839a/xblocks_contrib-1.0.6.tar.gz", hash = "sha256:80c82fa20cf1f3de05e8eafb22588c10035b47e8026064edc4aa0208e565659f", size = 22112519, upload-time = "2026-09-01T14:39:17.068Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/79/76/0442f6b4c83e7585c1da30ff79227881451f2e7cf1a006985f8f39c453ee/xblocks_contrib-1.0.6-py3-none-any.whl", hash = "sha256:b74a407a94c5bffe8fed87e88c8971e06e5dd304fb8495761aee2bc07650328a", size = 3768728, upload-time = "2026-09-01T14:39:15.153Z" }, -] [[package]] name = "xmlsec" From d5fbdf2c84010e5862b95e81e767edbbf3ed824b 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/3] 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: