From 2f8cbe013db1ea053b1867836b0a6c87272dc71a Mon Sep 17 00:00:00 2001 From: Andrew Scholer Date: Sat, 5 Sep 2026 09:34:41 -0700 Subject: [PATCH 1/5] Clarify term start date in course creation/settings --- .../rsptx/templates/admin/instructor/course_settings.html | 2 +- components/rsptx/templates/admin/instructor/create_course.html | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/rsptx/templates/admin/instructor/course_settings.html b/components/rsptx/templates/admin/instructor/course_settings.html index db3d5e2c2..bc0c46c05 100644 --- a/components/rsptx/templates/admin/instructor/course_settings.html +++ b/components/rsptx/templates/admin/instructor/course_settings.html @@ -24,7 +24,7 @@

{{ course.course_name }}

-
Set the start date for your course term
+
Set this to the first day students will be able to do work in the course. Student work before this date will not be counted.
diff --git a/components/rsptx/templates/admin/instructor/create_course.html b/components/rsptx/templates/admin/instructor/create_course.html index a6b98d260..868c82ee2 100644 --- a/components/rsptx/templates/admin/instructor/create_course.html +++ b/components/rsptx/templates/admin/instructor/create_course.html @@ -147,7 +147,8 @@

{{ section }}



- + + Set this to the first day students will be able to do work in the course. Student work before this date will not be counted.
Step 6: (Optional !!): Support Runestone Academy
From b6bf343c9e0e980e7f96a27b9a413fb57acb0ea3 Mon Sep 17 00:00:00 2001 From: Andrew Scholer Date: Sat, 5 Sep 2026 10:47:14 -0700 Subject: [PATCH 2/5] Reformat progress container text --- bases/rsptx/interactives/public/index.html | 8 +++++--- .../plugin_layouts/sphinx_bootstrap/layout.html | 6 +++++- .../runestone/common/test/bookfuncs_progress.test.js | 8 +++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/bases/rsptx/interactives/public/index.html b/bases/rsptx/interactives/public/index.html index 8cd23507d..01ddd23c3 100644 --- a/bases/rsptx/interactives/public/index.html +++ b/bases/rsptx/interactives/public/index.html @@ -235,9 +235,11 @@

- You have attempted of - activities on this page -
+
+ You have attempted of + activities on this page. +
+
diff --git a/bases/rsptx/interactives/runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/layout.html b/bases/rsptx/interactives/runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/layout.html index 3a95ea707..359e153e5 100644 --- a/bases/rsptx/interactives/runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/layout.html +++ b/bases/rsptx/interactives/runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/layout.html @@ -400,7 +400,11 @@

Before you keep reading...

{% endif %}
- You have attempted of activities on this page
+
+ You have attempted of + activities on this page. +
+
{% include "subchapter.html" %} diff --git a/bases/rsptx/interactives/runestone/common/test/bookfuncs_progress.test.js b/bases/rsptx/interactives/runestone/common/test/bookfuncs_progress.test.js index 3c0eff6e8..eeb15e0d9 100644 --- a/bases/rsptx/interactives/runestone/common/test/bookfuncs_progress.test.js +++ b/bases/rsptx/interactives/runestone/common/test/bookfuncs_progress.test.js @@ -22,9 +22,11 @@ import { /** The markup a book emits for the progress bar. */ function progressMarkup() { return ` -
You have attempted - of -activities on this page. +
+
+ You have attempted of + activities on this page. +
`; } From 22e13cbd8d3ae8bfc1e1d8eeb9817eb6af6476f0 Mon Sep 17 00:00:00 2001 From: Andrew Scholer Date: Sat, 5 Sep 2026 10:43:05 -0700 Subject: [PATCH 3/5] Rewrite default progresscontainer HTML --- .../interactives/runestone/common/js/bookfuncs.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/bases/rsptx/interactives/runestone/common/js/bookfuncs.js b/bases/rsptx/interactives/runestone/common/js/bookfuncs.js index fe0c8cf43..73fdf44f1 100644 --- a/bases/rsptx/interactives/runestone/common/js/bookfuncs.js +++ b/bases/rsptx/interactives/runestone/common/js/bookfuncs.js @@ -1080,6 +1080,21 @@ async function handlePageSetup() { } } } + + // PTX generated pages may have stale HTML. Forcibly re-render the content + // of the progress container. + const scprogresscontainer = document.getElementById( + "scprogresscontainer", + ); + if (scprogresscontainer) + scprogresscontainer.innerHTML = ` +
+ You have attempted of + activities on this page. +
+
+ `; + console.log(`This page served by ${eBookConfig.served_by}`); if (eBookConfig.isLoggedIn) { mess = `username: ${eBookConfig.username}`; From a9a0ea05d3d9b5a67bd507895a4f9b211020fb70 Mon Sep 17 00:00:00 2001 From: Andrew Scholer Date: Sat, 5 Sep 2026 10:47:52 -0700 Subject: [PATCH 4/5] Warn when in book before termStartDate --- bases/rsptx/interactives/ptxrs-bootstrap.less | 1 + .../runestone/common/css/runestone.css | 7 +++ .../runestone/common/js/bookfuncs.js | 43 ++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/bases/rsptx/interactives/ptxrs-bootstrap.less b/bases/rsptx/interactives/ptxrs-bootstrap.less index b16bbb3b4..34667c40f 100644 --- a/bases/rsptx/interactives/ptxrs-bootstrap.less +++ b/bases/rsptx/interactives/ptxrs-bootstrap.less @@ -23,6 +23,7 @@ border-radius: 5px; height: 20px; position: relative; + margin: 10px auto; } diff --git a/bases/rsptx/interactives/runestone/common/css/runestone.css b/bases/rsptx/interactives/runestone/common/css/runestone.css index 6f2615d68..f70b55e7b 100644 --- a/bases/rsptx/interactives/runestone/common/css/runestone.css +++ b/bases/rsptx/interactives/runestone/common/css/runestone.css @@ -1432,4 +1432,11 @@ legend { .autopermalink { display: none; +} + + +.course-not-started-warning { + margin-bottom: 20px; + margin-top: 20px; + padding: 15px; } \ No newline at end of file diff --git a/bases/rsptx/interactives/runestone/common/js/bookfuncs.js b/bases/rsptx/interactives/runestone/common/js/bookfuncs.js index 73fdf44f1..9addd2753 100644 --- a/bases/rsptx/interactives/runestone/common/js/bookfuncs.js +++ b/bases/rsptx/interactives/runestone/common/js/bookfuncs.js @@ -348,6 +348,25 @@ export const NON_CONTENT_PAGES = [ "search.html", ]; +export function isCourseStarted() { + let startDate = eBookConfig.termStartDate; // format is "2026-09-22" + if (!startDate) { + return false; + } + let today = new Date(); + let start = new Date(startDate); + return today >= start; +} + +function courseNotStartedMessage() { + const formattedDate = new Date(eBookConfig.termStartDate).toLocaleDateString(undefined, { + year: 'numeric', + month: 'long', + day: 'numeric' + }); + return ("Course has not started yet. Progress will be tracked starting on " + formattedDate); +} + /** True when pathname names one of the NON_CONTENT_PAGES. */ export function isNonContentPage(pathname = window.location.pathname) { let page = pathname.split("/").pop().toLowerCase(); @@ -440,6 +459,11 @@ export class PageProgressBar { } catch (e) { value = 0; } + let progressText = document.getElementById("scprogress-activity-count"); + // Warn if course not started + if(progressText && !isCourseStarted()) { + progressText.appendChild(document.createTextNode(courseNotStartedMessage())); + } // Replace #subchapterprogress div with a native element if not already done let subchapterprogress = document.getElementById("subchapterprogress"); if (subchapterprogress && subchapterprogress.tagName !== "PROGRESS") { @@ -1082,7 +1106,8 @@ async function handlePageSetup() { } // PTX generated pages may have stale HTML. Forcibly re-render the content - // of the progress container. + // of the progress container. Any logic that modifies the progress container + // should be done after this point, or it will be overwritten. const scprogresscontainer = document.getElementById( "scprogresscontainer", ); @@ -1109,7 +1134,23 @@ async function handlePageSetup() { } } document.dispatchEvent(new Event("runestone:login")); + addReadingList(); + + // Warn if the course has not started yet + if (!isCourseStarted()) { + const ptxContent = document.getElementById("ptx-content"); + if (ptxContent) { + const warningContainer = document.createElement("div"); + warningContainer.className = "ptx-runestone-container"; + const warningDiv = document.createElement("div"); + warningDiv.className = "course-not-started-warning alert alert-danger"; + warningDiv.textContent = courseNotStartedMessage(); + warningContainer.appendChild(warningDiv); + ptxContent.insertBefore(warningContainer, ptxContent.firstChild); + } + } + // Only show the StudyClues widget for certain base courses and when the path includes "/ns/books/". // This is a temporary measure to limit the widget to courses that are known to work well with it and to avoid showing it on non-book pages where it may not be as useful. if (shouldShowStudyCluesWidget()) { From ab889db9a9e29d4c26249f14d10b99218f03fe67 Mon Sep 17 00:00:00 2001 From: Andrew Scholer Date: Sat, 5 Sep 2026 11:20:26 -0700 Subject: [PATCH 5/5] Add eBookConfig.termStartDate to student facing pages --- bases/rsptx/assignment_server_api/routers/student.py | 2 ++ .../rsptx/templates/assignment/student/chooseAssignment.html | 5 +++++ components/rsptx/templates/common/ebook_config.html | 1 + 3 files changed, 8 insertions(+) diff --git a/bases/rsptx/assignment_server_api/routers/student.py b/bases/rsptx/assignment_server_api/routers/student.py index b4160dbbd..76c45c217 100644 --- a/bases/rsptx/assignment_server_api/routers/student.py +++ b/bases/rsptx/assignment_server_api/routers/student.py @@ -201,6 +201,7 @@ def sort_key(assignment): lti1p1=is_lti1p1_course, now=now, visibility_map=visibility_map, + term_start_date=course.term_start_date, settings=settings, base_url=construct_course_url(course), activity_info="{}", @@ -1020,6 +1021,7 @@ async def doAssignment( questions_score=questions_score, readings_score=readings_score, user=user, + term_start_date=course.term_start_date, user_id=user.username, # _base.html for ptx student pages needs user_id base_course=course.base_course, # gradeRecordingUrl=URL('assignments', 'record_grade'), diff --git a/components/rsptx/templates/assignment/student/chooseAssignment.html b/components/rsptx/templates/assignment/student/chooseAssignment.html index d0077c158..574e09016 100644 --- a/components/rsptx/templates/assignment/student/chooseAssignment.html +++ b/components/rsptx/templates/assignment/student/chooseAssignment.html @@ -16,6 +16,11 @@ {% endblock %} {% block content %} + +{% if using_ptx_base != "true" %} + {% include 'common/ebook_config.html' %} +{% endif %} +

Choose Assignment

diff --git a/components/rsptx/templates/common/ebook_config.html b/components/rsptx/templates/common/ebook_config.html index 99cdd9b73..0dc4b5eeb 100644 --- a/components/rsptx/templates/common/ebook_config.html +++ b/components/rsptx/templates/common/ebook_config.html @@ -32,4 +32,5 @@ eBookConfig.authorServerUrl = "{{settings.author_server_url}}"; eBookConfig.websocketUrl = "{{settings.websocket_url}}" eBookConfig.enableDebug = true ? "{{settings.debug}}" == "True" : false; + eBookConfig.termStartDate = "{{ course.term_start_date | default('', true) }}";