Topics: reference discovery

Topics organizes published learning material by subject rather than by teaching time. It provides category selection, filtered browsing, full-text search and context-preserving document navigation.

Blogs supplies the document publishing and interactive viewing foundation. Courses organizes documents into curriculum, sprints and weeks. Topics supplies another entry into the same authored material, independent of schedules, announcements and course chat.

A document can participate in both a course and a reference collection. Its categories determine its Topics membership; its course/week metadata determines its curriculum placement. Neither viewing context takes ownership of the authored content.

System picture

Authoritative Markdown / IPYNB / DOCX sources
    |
    v
Conversion and Jekyll posts/pages
    |
    +---- categories ----> Topics
    |                      ├── Reference browser
    |                      │   ├── Topic Filter - prominent categories
    |                      │   ├── Categories Filter - remaining categories
    |                      │   ├── Cards / List browsing
    |                      │   └── Scoped full-text Search
    |                      │       ├── Title matches - highlighted cards
    |                      │       └── Text matches - highlighted excerpts
    |                      └── Topics document view
    |                          ├── Full authored content
    |                          ├── Runners and Submissions
    |                          └── Return and related-document navigation
    |
    +---- course/week ---> Courses
                           └── Curriculum and course document view

Blogs supplies shared document layouts and interactive integrations.

The diagram describes capabilities and relationships, not separate copies of authored lessons. Topics document routes are generated presentation views of the underlying documents.

Categories and primary topics

The content model uses existing frontmatter:

categories: [Java, Algorithms]

Categories are independent facets, not an ordered parent/child path. Selecting Java finds its collection; selecting Java and Algorithms finds their intersection. Both filter groups support multiple selections, and all selected categories must match a document.

The primary topics configuration orders prominent categories: SASS, Python, Java, JavaScript, Flask, Spring, CS111, CS112 and CS113. This YAML controls visibility and order, not membership. Primary categories remain selectable even when their collection is empty. Remaining discovered categories appear in the secondary group.

No separate topics: attribute is required. Membership is not inferred from filenames, week numbers, lesson language or lesson grouping. CS112 and CS113 reference their existing outline documents through explicit categories; links from an outline do not automatically assign those categories to linked lessons.

Build-time discovery

The Topics generator discovers categorized Jekyll posts and pages. It omits hidden documents, drafts, search-excluded content and generated course player pages. Documents are deduplicated by original URL and sorted by title for ordinary browsing.

The generator creates:

  • A catalog with title, description, category keys, original URL, Topics view URL, searchable content and optional course/week display metadata.
  • Primary and secondary category collections for the browser.
  • A JSON search catalog at /assets/js/topics/data.json.
  • Full-document routes under /topics/view/.

Category keys are lowercase for comparison; display labels retain authored names. Invalid category values or an invalid primary-topic configuration fail the build rather than silently changing discovery.

Search text is derived from source content with script/style blocks, Liquid tokens and HTML tags removed. It is not a crawl of rendered pages; content loaded through relative includes is not expanded into the search text.

The browser include presents two disclosures inside a filter box. Topic Filter defaults open; Categories Filter defaults closed. Clear Filters belongs to that box and clears only category selections. Search has its own clear control. Each clear button is dimmed and disabled when its corresponding state is empty.

Topics and Search use semantic h2 headings; filter disclosures use h3 headings. The Cards/List selector sits above the output and retains an accessible View label without a visible prefix.

The browser controller builds a Lunr index in the client from the static catalog. Title, description and content participate in search, with title matches boosted. User input is tokenized as terms rather than interpreted as Lunr query syntax.

Browsing and search use the same category intersection:

Mode Output
No query Selected documents in Cards or List view
Search query Title-match cards, followed by text-match excerpts
No matching documents Explicit empty-result status
Index unavailable Error status with ordinary document links still available

Each search result appears in only one group. Title hits take precedence; otherwise content or description supplies the excerpt. Each group preserves search relevance ordering and displays its count beside its heading. Search uses title cards regardless of the browsing view selection.

The model helpers implement category intersection, URL state, match grouping and excerpt construction. Highlights are created with text nodes and mark elements, not injected document HTML. Search results remain within the selected collection rather than replacing it with a global search overlay.

Document viewing and navigation

The ordinary reference browser opens /topics/view/... routes. These routes preserve full content and interactive capabilities while suppressing the course player and document-scoped chat. Original document URLs retain their normal course or standalone behavior.

Generated views retain source paths and Markdown conversion so relative includes resolve against the authored document. The shared Blogs post layout recognizes Topics context and preserves the original document URL as the submission identity. A viewing route does not create a new assignment.

The document navigation offers a return to Topics and an original-context link. The document controller restores category, query and view parameters on the return link. Links to indexed same-site documents preserve Topics context; unrelated or external links retain their destinations.

URL parameters carry browser state:

  • Repeated category values identify selected facets.
  • q carries the search text.
  • view=list selects list browsing; cards are the default.

State is shareable and restored during browser history navigation. Clearing filters preserves the query and view; clearing Search preserves filters and view.

Integration boundaries

System or resource Responsibility
Topics Category discovery, filtered collections, scoped search and reference navigation
Blogs Publishing layouts, full-document presentation and interactive integrations
Courses Curriculum selection, schedules, progression and course navigation
Authoring and conversion Maintain source content and convert notebooks/DOCX into publishable documents
Runners, Submissions and Grading Execute exercises, persist evidence and evaluate submissions
Site shell and authentication Global navigation, preferences, identity and API configuration

The browser is reusable outside its landing page. Language-reference pages can start with a category selected. A course can include the browser with course_context=true; that adapter displays week metadata and links to original course documents. Weeks remain display context, not topic membership.

Topics does not own Calendar or Chat views. Its reference-discovery interface does not require an account; interactive document capabilities retain their own authentication and backend requirements.

Sources and publication

Source Responsibility
Pages /topics/ landing and /search/ compatibility redirect
Includes Browser and document navigation
Generator Catalog, category collections and generated views
Primary-topic YAML Prominent category labels and order
JavaScript Browser state, search and document link context
SCSS Topics layout and component styling
Tests Discovery, rendering, filtering, search and identity contracts
Distribution manifest Stable Jekyll and browser publication destinations

Topics is registered as systems/topics:dev in the project registry. The shared project Makefile publishes resources through its manifest; documentation uses the shared docs target. The root Makefile coordinates publication, conversion and Jekyll build/serve. Runtime copies and converted posts are generated outputs, not authoring locations.

Lunr is a shared vendor asset. Inputs and buttons use shared OCS styling; local SCSS handles disclosure layout and result presentation. The normal project build does not require a separate npm installation.

Validation

  • bundle exec ruby scripts/test_topics.rb: catalog and primary configuration, original versus Topics rendering, source-relative includes, submission identity and browser markup.
  • node --test tests/topics.test.mjs: category intersections, scoped search, URL state, grouped matches and highlighted excerpts.
  • Jekyll builds through the repository workflow: generated routes, Liquid rendering and Ruby Sass compatibility.
  • Browser checks: disclosure defaults, independent clearing, URL restoration, result counts, document navigation and mobile layout.