diff --git a/source/educators/how-tos/course_development/backup_restore_library.rst b/source/educators/how-tos/course_development/backup_restore_library.rst index d68c108b2..d76da1609 100644 --- a/source/educators/how-tos/course_development/backup_restore_library.rst +++ b/source/educators/how-tos/course_development/backup_restore_library.rst @@ -10,7 +10,8 @@ Backup and Restore a Library :depth: 1 You can :ref:`backup` and :ref:`restore` a -content library in Studio. +content library in Studio. Both operations use the :ref:`Library Archive +Format`, a portable ZIP format that you can also inspect or edit by hand. .. _Backup a Library: @@ -104,6 +105,8 @@ To create a library from an archive, follow these steps. :ref:`Add users to Libraries` + :ref:`Library Archive Format` + **Maintenance chart** +--------------+-------------------------------+----------------+---------------------------------------------------------------+ diff --git a/source/educators/navigation/content_creation_management.rst b/source/educators/navigation/content_creation_management.rst index 6f0c847f3..6466a662a 100644 --- a/source/educators/navigation/content_creation_management.rst +++ b/source/educators/navigation/content_creation_management.rst @@ -52,6 +52,7 @@ Work with Content Libraries ../how-tos/course_development/create_edit_blocks.rst ../how-tos/course_development/publish_library_content.rst ../how-tos/course_development/backup_restore_library.rst + ../references/library_archive_format.rst ../how-tos/course_development/add_delete_tags_in_library_content.rst ../how-tos/course_development/build_a_collection_in_a_library.rst ../how-tos/course_development/search_for_content_in_a_library.rst diff --git a/source/educators/references/library_archive_format.rst b/source/educators/references/library_archive_format.rst new file mode 100644 index 000000000..33ed431dc --- /dev/null +++ b/source/educators/references/library_archive_format.rst @@ -0,0 +1,355 @@ +.. _Library Archive Format: + +The Library Archive Format +########################## + +.. tags:: educator, reference + +The Library Archive Format is the ZIP-based format used to +:ref:`Backup and Restore a Library` on the Open edX Platform. + +With a library archive, authors can: + +* Move a library between different Open edX instances. +* Keep a portable backup copy of a library. +* Inspect, or even hand-edit, the contents of a library outside of Studio. + +Because the archive keeps each component's content as OLX (open learning XML) — +the same format Studio uses internally — authors already familiar with +:ref:`OLX ` will recognize the XML stored inside. + +.. contents:: + :local: + :depth: 2 + +Overview +******** + +A backup ZIP is a self-contained snapshot of one learning package. It captures +every component, collection, container (section / subsection / unit), and +static asset. For each component and container, only the current draft and +published versions are exported — the full version history is not preserved. + +The archive uses `TOML `_ for all metadata files and keeps the +actual component XBlock content as XML (the same OLX format Studio has always +used). This makes backups both machine-readable and human-inspectable. + + +.. admonition:: A note on Learning Packages + + Every user-facing *Library* is backed in the database by a *Learning Package*, + a general repository of learning content. During the restore process, + the system creates a standalone Learning Package for inspection; once the + operator confirms the content, the Learning Package is promoted into a + proper Library. Because of this relationship, you will see the term + ``learning_package`` used inside the archive's metadata files. In the + future, this same archive format may be used to restore other kinds of + Learning-Package-backed content. + +.. admonition:: Schema versioning + + The current archive ``format_version`` is **1**. Future incompatible changes + to the schema will increment this number so that tooling can detect them + before attempting a restore. + +Archive Structure +***************** + +:: + + .zip + ├── package.toml # library metadata + archive metadata + ├── collections/ + │ └── .toml # one file per collection + └── entities/ + ├── .toml # sections, subsections, units + └── xblock.v1/ + └── / # e.g. html, problem, video + ├── .toml # entity metadata + version list + └── / + └── component_versions/ + └── v/ + ├── block.xml # XBlock content (XML) + └── static/ # media assets referenced by block.xml + +File Format Reference +********************* + +package.toml +============ + +Located at the root of the archive. Contains two sections: + +``[meta]`` — archive metadata (for inspection only): + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Field + - Required + - Description + * - ``format_version`` + - yes + - Integer schema version; currently ``1`` + * - ``created_by`` + - no + - Username of the operator who ran the export + * - ``created_by_email`` + - no + - Email address of the exporting user + * - ``created_at`` + - yes + - UTC timestamp when the archive was created + * - ``origin_server`` + - no + - Free-form string identifying the origin CMS instance (typically a + hostname or URL; stored as-is with no format validation) + +``[learning_package]`` — library data. Note that ``key`` may be overridden when +the library is restored under a new reference, and ``updated`` is written to the +archive for reference but is not applied during a restore: + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Field + - Required + - Description + * - ``title`` + - yes + - Human-readable name of the library + * - ``key`` + - yes + - Package reference string, e.g. ``lib:MyOrg:MyLib`` + * - ``description`` + - yes + - Free-text description (may be blank) + * - ``created`` + - yes + - UTC timestamp when the library was originally created + * - ``updated`` + - yes + - UTC timestamp of the library's last modification (written to the + archive for reference; **not** applied during restore) + +Example:: + + [meta] + format_version = 1 + created_by = "lp_user" + created_by_email = "lp_user@example.com" + created_at = 2025-10-05T18:23:45.180535Z + origin_server = "cms.test" + + [learning_package] + title = "Library test" + key = "lib:WGU:LIB_C001" + description = "" + created = 2025-08-19T04:25:10.988166Z + updated = 2025-08-19T04:25:10.988166Z + +Component entity TOML (``entities/xblock.v1//.toml``) +================================================================= + +Each XBlock component gets one TOML file. + +``[entity]``: + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Field + - Required + - Description + * - ``can_stand_alone`` + - yes + - Whether this component can be used independently (almost always ``true``) + * - ``key`` + - yes + - Entity reference in the form ``xblock.v1::`` + * - ``created`` + - yes + - UTC creation timestamp + +``[entity.draft]`` / ``[entity.published]`` — each contains ``version_num`` +pointing at the current draft or published ``[[version]]`` entry respectively. +``[entity.draft]`` is absent when the entity has no draft. +``[entity.published]`` is **always present** — when the entity has no +published version it is written as an empty table with an explanatory comment +(see the container example below). + +``[[version]]`` — at most two entries: the current draft version first, then +the current published version if it differs from draft. The full version +history is not stored. + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Field + - Required + - Description + * - ``title`` + - yes + - Display name of the component at this version + * - ``version_num`` + - yes + - Monotonically increasing integer starting at 1 + +Example:: + + [entity] + can_stand_alone = true + key = "xblock.v1:html:e32d5479-9492-41f6-9222-550a7346bc37" + created = 2025-08-19T04:25:43.685529Z + + [entity.draft] + version_num = 5 + + [entity.published] + version_num = 4 + + # ### Versions + + [[version]] + title = "Text" + version_num = 5 + + [[version]] + title = "Text" + version_num = 4 + +.. admonition:: Mapping archive keys to platform keys + + Restoring a component with an archive reference key + ``xblock.v1::`` to a library with the key + ``lib::`` yields an XBlock with the usage key + ``lb::::``. + + +Container entity TOML (``entities/.toml``) +=============================================== + +Sections, subsections, and units share the same base structure with an +additional ``[entity.container.]`` marker (``section``, ``subsection``, +or ``unit``) and a ``[version.container]`` table that lists child keys. + +Example (section):: + + [entity] + can_stand_alone = true + key = "section1-8ca126" + created = 2025-09-04T22:51:40.919872Z + + [entity.draft] + version_num = 2 + + [entity.published] + # unpublished: no published_version_num + + [entity.container.section] + + # ### Versions + + [[version]] + title = "Section1" + version_num = 2 + + [version.container] + children = ["subsection1-48afa3"] + +.. admonition:: Mapping archive keys to platform keys + + Restoring a container of kind ```` and archive reference ```` to + a library with the key ``lib::`` yields a container with + the key ``lct::::``. + + +Collection TOML (``collections/.toml``) +============================================ + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Field + - Required + - Description + * - ``title`` + - yes + - Collection display name + * - ``key`` + - yes + - Unique key within the library + * - ``description`` + - yes + - Free-text description (may be blank) + * - ``created`` + - yes + - UTC creation timestamp + * - ``entities`` + - yes + - List of entity reference strings (e.g. ``xblock.v1:html:abc123``, ``unit-xyz789``) + +Example:: + + [collection] + title = "Collection test1" + key = "collection-test" + description = "" + created = 2025-08-19T04:25:27.754968Z + entities = [ + "xblock.v1:html:e32d5479-9492-41f6-9222-550a7346bc37", + "xblock.v1:problem:256739e8-c2df-4ced-bd10-8156f6cfa90b", + ] + +XBlock content (``component_versions/v/block.xml``) +====================================================== + +The library archive format uses +:ref:`OLX (open learning XML) ` to encode components, +similar to the course archive format, although there are a few notable differences: + +* Each library component version's OLX file is simply named ``block.xml``. Its key is + separately defined in the component's TOML metadata file. In the course OLX + archive, the name of each XML file is derived from its block's key: + ``.xml``. + +* Each library component stores its own static assets under + ``component_versions/v/static/``, and references them in its OLX + file as ``/static/``. In the course archive, the course's static + assets are all in one shared ``static/`` folder. + +* Library HTML content is currently serialized inline using a CDATA section + within the ``.xml`` file rather than being split into a separate ``.html`` + file. This differs from course archives, which support separate ``.xml`` and + ``.html`` files. This is a known limitation of the library XBlock + serialization layer. + +Example ``block.xml``:: + + + Hello Me

]]> + + +.. seealso:: + + :ref:`Backup and Restore a Library` (how-to) + + :ref:`What is Open Learning XML?` (concept) + + :ref:`OLX Documentation ` (reference) + + :ref:`OLX Directory Structure` (reference) + + +**Maintenance chart** + ++--------------+-------------------------------+----------------+--------------------------------+ +| Review Date | Working Group Reviewer | Release |Test situation | ++--------------+-------------------------------+----------------+--------------------------------+ +| | | | | ++--------------+-------------------------------+----------------+--------------------------------+