Skip to content

Commit

Permalink
feat: Serialize tag data in OLX for blocks (#34145)
Browse files Browse the repository at this point in the history
  • Loading branch information
yusuf-musleh authored Feb 14, 2024
1 parent 5a36fa9 commit 6e0bc66
Show file tree
Hide file tree
Showing 10 changed files with 475 additions and 5 deletions.
2 changes: 2 additions & 0 deletions cms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@

from lms.djangoapps.lms_xblock.mixin import LmsBlockMixin
from cms.lib.xblock.authoring_mixin import AuthoringMixin
from cms.lib.xblock.tagging.tagged_block_mixin import TaggedBlockMixin
from xmodule.modulestore.edit_info import EditInfoMixin
from openedx.core.djangoapps.theming.helpers_dirs import (
get_themes_unchecked,
Expand Down Expand Up @@ -975,6 +976,7 @@
XModuleMixin,
EditInfoMixin,
AuthoringMixin,
TaggedBlockMixin,
)
XBLOCK_EXTRA_MIXINS = ()

Expand Down
57 changes: 57 additions & 0 deletions cms/lib/xblock/tagging/tagged_block_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# lint-amnesty, pylint: disable=missing-module-docstring
from urllib.parse import quote


class TaggedBlockMixin:
"""
Mixin containing XML serializing and parsing functionality for tagged blocks
"""

def serialize_tag_data(self):
"""
Serialize block's tag data to include in the xml, escaping special characters
Example tags:
LightCast Skills Taxonomy: ["Typing", "Microsoft Office"]
Open Canada Skills Taxonomy: ["MS Office", "<some:;,skill/|=>"]
Example serialized tags:
lightcast-skills:Typing,Microsoft Office;open-canada-skills:MS Office,%3Csome%3A%3B%2Cskill%2F%7C%3D%3E
"""
# This import is done here since we import and use TaggedBlockMixin in the cms settings, but the
# content_tagging app wouldn't have loaded yet, so importing it outside causes an error
from openedx.core.djangoapps.content_tagging.api import get_object_tags
content_tags = get_object_tags(self.scope_ids.usage_id)

serialized_tags = []
taxonomies_and_tags = {}
for tag in content_tags:
taxonomy_export_id = tag.taxonomy.export_id

if not taxonomies_and_tags.get(taxonomy_export_id):
taxonomies_and_tags[taxonomy_export_id] = []

# Escape special characters in tag values, except spaces (%20) for better readability
escaped_tag = quote(tag.value).replace("%20", " ")
taxonomies_and_tags[taxonomy_export_id].append(escaped_tag)

for taxonomy in taxonomies_and_tags:
merged_tags = ','.join(taxonomies_and_tags.get(taxonomy))
serialized_tags.append(f"{taxonomy}:{merged_tags}")

return ";".join(serialized_tags)

def add_tags_to_node(self, node):
"""
Serialize and add tag data (if any) to node
"""
tag_data = self.serialize_tag_data()
if tag_data:
node.set('tags-v1', tag_data)

def add_xml_to_node(self, node):
"""
Include the serialized tag data in XML when adding to node
"""
super().add_xml_to_node(node)
self.add_tags_to_node(node)
6 changes: 6 additions & 0 deletions openedx/core/lib/xblock_serializer/block_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from lxml import etree

from cms.lib.xblock.tagging.tagged_block_mixin import TaggedBlockMixin

from .data import StaticFile
from . import utils

Expand Down Expand Up @@ -113,6 +115,10 @@ def _serialize_html_block(self, block) -> etree.Element:
if block.use_latex_compiler:
olx_node.attrib["use_latex_compiler"] = "true"

# Serialize and add tag data if any
if isinstance(block, TaggedBlockMixin):
block.add_tags_to_node(olx_node)

# Escape any CDATA special chars
escaped_block_data = block.data.replace("]]>", "]]&gt;")
olx_node.text = etree.CDATA("\n" + escaped_block_data + "\n")
Expand Down
Loading

0 comments on commit 6e0bc66

Please sign in to comment.