You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/decisions/0002-content-flexibility.rst
+12-1Lines changed: 12 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,16 @@
1
1
2. Approach to Content Flexibility
2
2
==================================
3
3
4
+
Status
5
+
------
6
+
7
+
Proposed. The "Sequence" and "Navigation" concepts described below have not been realized.
8
+
9
+
4
10
Context
5
11
-------
6
12
7
-
Open edX courses follow a strict Course > Section > Subsection > Unit > Module hierarchy. There are a number of use cases that do not fit this pattern:
13
+
Open edX courses follow a strict Course > Section > Subsection > Unit > XBlock hierarchy. There are a number of use cases that do not fit this pattern:
8
14
9
15
* A problem bank shared via LTI, with individual problems for use in other LMS systems.
10
16
* Short courses that do not require the "Section" middle layer of hierarchy.
@@ -47,6 +53,11 @@ To realize the benefits of this system would require significant changes to Stud
47
53
Changelog
48
54
---------
49
55
56
+
2026-04-02:
57
+
58
+
* Renamed "Module" to "XBlock" to be consistent with updated platform terminology.
59
+
* Added "Status"
60
+
50
61
2023-02-06:
51
62
52
63
* Renamed "Item" to "Component" to be consistent with user-facing Studio terminology.
Copy file name to clipboardExpand all lines: docs/decisions/0005-identifier-conventions.rst
+14-1Lines changed: 14 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,11 @@
1
1
5. Identifier Conventions
2
2
=========================
3
3
4
+
Status
5
+
------
6
+
7
+
Likely superseded by `OEP-68 <https://github.com/openedx/openedx-proposals/pull/773>`_.
8
+
4
9
Context
5
10
-------
6
11
@@ -28,7 +33,7 @@ Key
28
33
Implementation Notes
29
34
--------------------
30
35
31
-
Helpers to generate these field types are in the ``openedx_learning.lib.fields`` module.
36
+
Helpers to generate these field types are in the ``openedx_django_lib.fields`` module.
32
37
33
38
Rejected Alternatives
34
39
---------------------
@@ -37,3 +42,11 @@ A number of names were considered for ``key``, and were rejected for different r
37
42
38
43
* ``identifier`` is used in some standards like QTI, but it's too easily confused with ``id`` or the general concept of the three types of identity-related fields we have.
39
44
* ``slug`` was considered, but ultimately rejected because that implied these fields would be human-readable, and that's not guaranteed. Most XBlock content that comes from MongoDB will be using GUIDs, for instance.
Copy file name to clipboardExpand all lines: docs/decisions/0006-app-label-prefix.rst
+12Lines changed: 12 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,11 @@
1
1
6. App Label Prefix
2
2
===================
3
3
4
+
Status
5
+
------
6
+
7
+
Obsolete. See decision 0020. Apps like ``openedx_content`` no longer use the ``oel_`` prefix, and this repo is no longer called "learning core".
8
+
4
9
Context
5
10
-------
6
11
@@ -11,3 +16,10 @@ Decision
11
16
--------
12
17
13
18
All apps in this repo will create a default AppConfig that sets the ``label`` to have a prefix of ``oel_`` before the app name. So if the app name is ``publishing``, the ``label`` will be ``oel_publishing``. This means that all generated database tables will similarly be prefixed with ``oel_``.
Copy file name to clipboardExpand all lines: docs/decisions/0007-tagging-app.rst
+18-3Lines changed: 18 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,11 @@
1
1
7. Tagging App structure
2
2
========================
3
3
4
+
Status
5
+
------
6
+
7
+
Partially accepted, partially obsolete (see note under "ObjectTag").
8
+
4
9
Context
5
10
-------
6
11
@@ -17,18 +22,20 @@ Classes which require dependencies on other Open edX projects should be defined
17
22
Taxonomy
18
23
~~~~~~~~
19
24
20
-
The ``openedx_tagging`` module defines ``openedx_tagging.core.models.Taxonomy``, whose data and functionality are self-contained to the ``openedx_tagging`` app. However in Studio, we need to be able to limit access to some Taxonomy by organization, using the same "course creator" access which limits course creation for an organization to a defined set of users.
25
+
The ``openedx_tagging`` module defines ``openedx_tagging.models.Taxonomy``, whose data and functionality are self-contained to the ``openedx_tagging`` app. However in Studio, we need to be able to limit access to some Taxonomy by organization, using the same "course creator" access which limits course creation for an organization to a defined set of users.
21
26
22
-
So in edx-platform, we will create the ``openedx.features.content_tagging`` app, to contain the models and logic for linking Organization owners to Taxonomies. Here, we can subclass ``Taxonomy`` as needed, preferably using proxy models. The APIs are responsible for ensuring that any ``Taxonomy`` instances are cast to the appropriate subclass.
27
+
So in edx-platform, we will create the ``openedx.core.djangoapps.content_tagging`` app, to contain the models and logic for linking Organization owners to Taxonomies. Here, we can subclass ``Taxonomy`` as needed, preferably using proxy models. The APIs are responsible for ensuring that any ``Taxonomy`` instances are cast to the appropriate subclass.
23
28
24
29
ObjectTag
25
30
~~~~~~~~~
26
31
27
-
Similarly, the ``openedx_tagging`` module defined ``openedx_tagging.core.models.ObjectTag``, also self-contained to the
32
+
Similarly, the ``openedx_tagging`` module defines ``openedx_tagging.models.ObjectTag``, also self-contained to the
28
33
``openedx_tagging`` app.
29
34
30
35
But to tag content in the LMS/Studio, we need to enforce ``object_id`` as a CourseKey or UsageKey type. So to do this, we subclass ``ObjectTag``, and use this class when creating content object tags. Once the ``object_id`` is set, it is not editable, and so this key validation need not happen again.
31
36
37
+
Note 2026-04-02: In 2024, `we simplified this <https://github.com/openedx/openedx-platform/pull/34146>`_, and ObjectTags are no longer subclassable. Instead, Django ``rules`` permissions hooks allow openedx-platform to extend the ``can_change_object_tag`` permission rule as needed.
38
+
32
39
Rejected Alternatives
33
40
---------------------
34
41
@@ -38,3 +45,11 @@ Embed in edx-platform
38
45
Embedding the logic in edx-platform would provide the content tagging logic specifically required for the MVP.
39
46
40
47
However, we plan to extend tagging to other object types (e.g. People) and contexts (e.g. Marketing), and so a generic, standalone library is preferable in the log run.
Copy file name to clipboardExpand all lines: docs/decisions/0009-tagging-administrators.rst
+8-1Lines changed: 8 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ In the Studio context, a modified version of "course creator" access will be use
22
22
23
23
Permission #1 requires no external access, so can be enforced by the ``openedx_tagging`` app.
24
24
25
-
But because permissions #2 + #3 require access to the edx-platform CMS model `CourseCreator`_, this access can only be enforced in Studio, and so will live under ``cms.djangoapps.content_tagging`` along with the ``ContentTag`` class. Tagging MVP must work for libraries v1, v2 and courses created in Studio, and so tying these permissions to Studio is reasonable for the MVP.
25
+
But because permissions #2 + #3 require access to the edx-platform CMS model `CourseCreator`_, this access can only be enforced in Studio, and so will live under ``openedx.core.djangoapps.content_tagging`` along with the ``ContentTag`` class. Tagging MVP must work for libraries v1, v2 and courses created in Studio, and so tying these permissions to Studio is reasonable for the MVP.
26
26
27
27
Per `OEP-9`_, ``openedx_tagging`` will allow applications to use the standard Django API to query permissions, for example: ``user.has_perm('openedx_tagging.edit_taxonomy', taxonomy)``, and the appropriate permissions will be applied in that application's context.
28
28
@@ -40,3 +40,10 @@ This is a standard way to grant access in Django apps, but it is not used in Ope
Copy file name to clipboardExpand all lines: docs/decisions/0010-taxonomy-enable-context.rst
+14-1Lines changed: 14 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,11 @@
1
1
10. Taxonomy enabled for context
2
2
================================
3
3
4
+
Status
5
+
------
6
+
7
+
Rejected. The "all available taxonomies" advanced setting described was never implemented, and the ``OrgTaxonomy`` subclass of taxonomies was instead replaced with a ``TaxonomyOrg`` model that links organizations to regular ``Taxonomy`` instances.
8
+
4
9
Context
5
10
-------
6
11
@@ -59,7 +64,7 @@ If ``enabled = True``, then the :ref:`Organization` and :ref:`Course` contexts d
59
64
Organization
60
65
~~~~~~~~~~~~
61
66
62
-
OrgTaxonomy has a many-to-many relationship with the Organization model, accessed via the ``org_owners`` field. OrgTaxonomy lives under `cms.djangoapps.tagging` and so has access to the Organization model and logic in Studio.
67
+
OrgTaxonomy has a many-to-many relationship with the Organization model, accessed via the ``org_owners`` field. OrgTaxonomy lives under ``openedx.core.djangoapps.content_tagging`` and so has access to the Organization model and logic in Studio.
63
68
64
69
An OrgTaxonomy is enabled for all organizations if ``org_owners == []``.
65
70
If there are any ``org_owners`` set, then the OrgTaxonomy is only enabled for those orgas, i.e. only courses in these orgs will see the taxonomy field in Studio.
@@ -91,3 +96,11 @@ This was deemed too granular for the MVP, and the data structures and UI can be
Copy file name to clipboardExpand all lines: docs/decisions/0011-tag-changes.rst
+10-2Lines changed: 10 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,11 +14,11 @@ Decision
14
14
Preserve content tag name:value pairs even if the associated taxonomy or tag is removed.
15
15
Reflect name:value changes from the linked taxonomy:tag immediately to the user.
16
16
17
-
Content tags (through their base ObjectTag class) store a foreign key to their Taxonomy and Tag (if relevant), but they also store a copy of the Taxonomy.name and Tag.value, which can be used if there is no Taxonomy or Tag available.
17
+
Content tags (through their base ObjectTag class) store a foreign key to their Taxonomy and Tag (if relevant), but they also store a copy of the Taxonomy.export_id and Tag.value, which can be used if there is no Taxonomy or Tag available.
18
18
19
19
We consult the authoritative Taxonomy.name and Tag.value whenever displaying a content tag, so any changes are immediately reflected to the user.
20
20
21
-
If a Taxonomy or Tag is deleted, the linked content tags will remain, and cached copies of the name:value pair will be displayed.
21
+
If a Taxonomy or Tag is deleted, the linked content tags will remain, and cached copies of the (name/export_id):value pair will be displayed.
22
22
23
23
This cached "value" field enables content tags (through their base ObjectTag class) to store free-text tag values, so that the free-text Taxonomy itself need not be modified when new free-text tags are added.
24
24
@@ -33,3 +33,11 @@ Require foreign keys
33
33
Require a foreign key from a content tag to Taxonomy for the name, and Tag for the value.
34
34
35
35
Only using foreign keys puts the labor-intensive content tag data at risk during taxonomy changes, and requires free-text tags to be made part of a taxonomy.
36
+
37
+
Changelog
38
+
---------
39
+
40
+
2026-04-02:
41
+
42
+
* Updated: ObjectTag instances now store a reference to ``taxonomy.export_id``, not ``taxonomy.name``
Copy file name to clipboardExpand all lines: docs/decisions/0016-python-public-api-conventions.rst
+12Lines changed: 12 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,11 @@
1
1
16. Python Public API Conventions
2
2
=================================
3
3
4
+
Status
5
+
------
6
+
7
+
Superseded by decision 0020.
8
+
4
9
Context
5
10
--------
6
11
@@ -88,3 +93,10 @@ Use ``_api`` modules in apps instead of ``api``.
88
93
I'm not adding this because it feels unintuitive that apps would import a private module from other apps, e.g. the ``components`` app importing from ``openedx_learning.apps.publishing._api``. My hope is that documentation and import linter rules in edx-platform will be enough to make it clear that APIs should only be imported from ``openedx_learning.api``.
89
94
90
95
We should revisit this at a later time if this turns out to be a source of confusion.
Accepted, except that "Selectors" have not been finalized nor implemented. Container implementation has been separated from ``publishing`` and is part of a separate "applet".
8
+
4
9
Context
5
10
-------
6
11
@@ -92,4 +97,12 @@ This section defines the rules for pruning container versions, explaining when a
92
97
- In a top-down approach, start the deletion process with the parent container and work your way down to its children. E.g., when pruning Section V2 > Subsection V1 > Unit V3, the deletion process starts in the greater container working its way down to the smaller.
93
98
- Pruning a container version will not affect the container's history or the children of other container versions, so containers will not be deleted if they are shared by other containers.
0 commit comments