Discussion Modules and Categories
This document was created by Greg Price (Unlicensed) in February 2014. It was brought over from the old wiki: https://edx-wiki.atlassian.net/wiki/display/FOR/Discussion+modules
MongoDB objects
Discussion modules have "_id.category": "discussion"
. The metadata
field contains the following fields of interest: display_name
, discussion_category
, discussion_target
(orfor
), discussion_id
(or id)
, sort_key
.
Python objects
The discussion module objects returned from the modulestore have the relevant metadata fields set as attributes (with for
and id
being set as discussion_target
and discussion_id
respectively). The object also has a unique identifier available as scope_ids.usage_id
(aliased and currently used as location
), and it may have some attributes that are inherited from the module's ancestors' metadata, start
(containing the start date) being of particular interest. Despite the fact that certain metadata comes from the module's ancestry, the ancestry is not directly accessible. In fact, because the XBlock API does not require a block to specify contained blocks in any particular manner, it is not possible to even determine whether a particular block actually appears at any point in the course structure; the inherited metadata is applied only if the module is a descendant of a course module as indicated by the children field of various container modules.
Discussion category "components"
In several places, the discussion category is treated as composed of components, which are computed from the discussion_category
attribute by splitting it on '/' and trimming whitespace on the resulting strings.
Data constraints
Ideally, no two modules should share the same discussion_id
or the same set of discussion_category
components and discussion_target
. No part of the system enforces such a constraint. Consequences of violating the constraints are described below.
How the LMS uses discussion modules
Courseware context in Discussion tab
When a thread from a discussion module is displayed in the discussion tab, a footer is added to the initial post containing a link to the courseware page containing the discussion module. The footer is computed by building a map keyed on discussion_id
and then, for each thread, looking up the module corresponding to the thread's commentable_id
. The link URL is built using the "jump_to" view, passing the course id and the module's location as parameters. The link text consists of the last component of discussion_category
and discussion_target
joined by a '/'. Note that in the process of building the map, multiple modules with the same discussion_id
can conflict; whichever one is later in the list returned by the modulestore (which should be arbitrary but stable) will prevail, and the others will not be used in the link building process.
Discussion navigation menu
At the top of the left pane of the Discussion tab, there is a menu with which users can filter the thread list in that pane. Part of that menu is a hierarchical listing of categories from the discussion modules. The hierarchy is computed by creating a nested map with a level for each discussion_category
component. Each node in the nested map contains "subcategories", pointing to the nested children in the hierarchy, and "entries" which is a map from discussion_target
to module metadata (representing the leaves of the hierarchy), including start
and sort_key
(which is set to discussion_target
if sort_key
is not explicitly specified and the discussion_sort_alpha
setting is true for the course). Note that the tuple of discussion_category
components and discussion_target
can conflict; whichever one is later in the list returned by the modulestore (which should be arbitrary but stable) will prevail, and the others will not appear in the menu. Also, if the tuple of discussion_category
components and discussion_target
for one module is a prefix of that of another module, then the menu will contain an extra entry for the former and none for the latter. Each intermediate node also has a sort key, which is the corresponding discussion_category
component, and a start date, which is equal to the earliest start date of any of its leaves. The combined children ("subcategories" and "entries") are sorted by sort key and filtered by start date (without regard to staff or beta tester status of the user). When making the drop-down, the discussion_id
for a given module is included in the DOM for the leaf menu items (so the front-end code can build an appropriate query when it is selected).
New post topic menu
This is generated in the same way as the navigation menu, with slightly different DOM as a result.
In courseware
Discussion modules are, of course, rendered as part of the courseware. In this context, discussion_id
is used to filter the set of threads that are displayed in the module. Thus, if two modules have the same discussion_id
, then the same set of threads will appear in both places. The display_name
property is used to generate the page title and the tooltip for the unit in the navigation bar at the top of the section.
How Studio uses discussion modules
The Studio view of a discussion module includes the ability (currently broken) to show the module's threads and write new posts. This functionality is driven by the module's discussion_id
. Studio's discussion module edit dialog includes three fields labeled "Category", "Display Name", and "Subcategory", which set the module's discussion_category
, display_name
, and discussion_target
respectively.
Glossary
The names used in the UI and code for all of these "things" is quite confused at this point. Below is an attempt at clarifying some of what is there, but it may require additional review to determine if it is accurate and to get it to more completely jive with the rest of this page.
This glossary is missing many terms from his page.
- Entry - The term entry is used in the JSON returned by cohort_discussion_topics to represent a leaf node in the hierarchical category tree.
- An entry is always a leaf node in a tree of categories.
- An entry always as an id.
- Is this id a discussion_id or a commentable_id?
- Category - this seems to be a confused term that sometimes refers to the top-level of the hierarchy and possibly to any level in the hierarchy.
- Discussions
- Course Wide Discussions - these discussions are course wide and are not tied to a specific part of the course.
- Course wide discussions only use entries (not subcategories) in the returned JSON.
- Given that the Course Wide Discussions is itself a container of entries in the returned JSON, it is sometimes treated as a subcategory, using the definition of a subcategory as a collection of entries.
- Inline Discussions - these discussions are tied to a specific part of the course.
- Has a top-level subcategories container in the returned JSON.
- Children in the hierarchy can be a subcategory (container of more subcategories or entries), or an entry (leaf node).
- Course Wide Discussions - these discussions are course wide and are not tied to a specific part of the course.
- Subcategory - this terms is used in various and conflicting ways in the UI and in the code:
- A subcategory is sometimes a container of subcategories and entries (in the UI and in code).
- In this use, subcategory also means "not an entry".
- A subcategory is sometimes a top-level container (in the UI code and the returned JSON, but not the UI).
- A subcategory is sometimes an entry or topic (in the UI code and the UI, but not in the returned JSON).
- A subcategory is sometimes a container of subcategories and entries (in the UI and in code).
- Topics - In the LMS UI, a topic is the most general term used for categories and subcategories.
- It is used in the "All Topics" breadcrumb and "filter topics" in the Discussions tab.
- In the UI, "All Discussions" (i.e. All Posts), and "Posts I'm Following" are considered topics.