From 7b665733fe226f3e922bdf6795fb45ff09de1135 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Tue, 21 Jul 2026 21:16:33 -0500 Subject: [PATCH 1/3] Add the capability to format `.html.ep` files with prettier. This uses the `@openwebwork/prettier-plugin-mojolicious-html-template` package to do so. That package is a `prettier` plugin that formats HTML with `prettier` and uses `perltidy` to format Perl content inside the Mojolicious template regions. The `@openwebwork/prettier-plugin-mojolicious-html-template` project repository is housed at https://github.com/openwebwork/prettier-plugin-mojolicious-html-template. I am giving ownership of the repository to webwork, because the project was developed with the usage of Claude code, and that usage was funded by the webwork project. --- .github/workflows/check-formats.yml | 19 +++++++------------ .prettierrc | 3 ++- htdocs/package-lock.json | 14 ++++++++++++++ htdocs/package.json | 10 ++++++++-- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/.github/workflows/check-formats.yml b/.github/workflows/check-formats.yml index 863b02d988..da689d89a1 100644 --- a/.github/workflows/check-formats.yml +++ b/.github/workflows/check-formats.yml @@ -12,16 +12,17 @@ on: jobs: perltidy: - name: Check Perl file formatting with perltidy + name: Check file formatting with perltidy and prettier runs-on: ubuntu-24.04 - container: - image: perl:5.38 steps: - name: Checkout code uses: actions/checkout@v6 - name: Install dependencies - run: cpanm -n Perl::Tidy@20260204 - - name: Run perltidy + run: | + sudo apt-get update && sudo apt-get install -y libmojolicious-perl cpanminus + sudo cpanm -n Perl::Tidy@20260204 + + - name: Check Perl file formatting with perltidy shell: bash run: | git config --global --add safe.directory "$GITHUB_WORKSPACE" @@ -42,17 +43,11 @@ jobs: git diff --exit-code fi - prettier: - name: Check JavaScript, style, and HTML file formatting with prettier - runs-on: ubuntu-24.04 - steps: - - name: Checkout code - uses: actions/checkout@v6 - name: Install Node uses: actions/setup-node@v6 with: node-version: '24' - name: Install Dependencies run: cd htdocs && npm ci --ignore-scripts - - name: Check formatting with prettier + - name: Check JavaScript, style, and HTML file formatting with prettier run: cd htdocs && npm run prettier-check diff --git a/.prettierrc b/.prettierrc index b21dab0657..0737ccf48d 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,5 +4,6 @@ "printWidth": 120, "semi": true, "singleQuote": true, - "trailingComma": "none" + "trailingComma": "none", + "plugins": ["@openwebwork/prettier-plugin-mojolicious-html-template"] } diff --git a/htdocs/package-lock.json b/htdocs/package-lock.json index 03f9cfd6eb..4dcc44f2c3 100644 --- a/htdocs/package-lock.json +++ b/htdocs/package-lock.json @@ -21,6 +21,7 @@ "sortablejs": "^1.15.7" }, "devDependencies": { + "@openwebwork/prettier-plugin-mojolicious-html-template": "^0.0.1", "autoprefixer": "^10.5.4", "chokidar": "^5.0.0", "cssnano": "^8.0.2", @@ -368,6 +369,19 @@ "thememirror": "^2.0.1" } }, + "node_modules/@openwebwork/prettier-plugin-mojolicious-html-template": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@openwebwork/prettier-plugin-mojolicious-html-template/-/prettier-plugin-mojolicious-html-template-0.0.1.tgz", + "integrity": "sha512-kEcmwN3bYiA+K9c0bH5My9YNoGcWZLdRTlLmQ6VUxinjDq/QSAZsJnkeZySv2UAvGR7DUA7xUYO5sF8ZaHEuvg==", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "@lezer/lr": "^1.4.10" + }, + "peerDependencies": { + "prettier": "^3.9.4" + } + }, "node_modules/@parcel/watcher": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz", diff --git a/htdocs/package.json b/htdocs/package.json index 411ac35517..c5bfbdf34a 100644 --- a/htdocs/package.json +++ b/htdocs/package.json @@ -5,8 +5,8 @@ "scripts": { "generate-assets": "node generate-assets", "prepare": "npm run generate-assets", - "prettier-format": "prettier --ignore-path=../.gitignore --write \"**/*.{js,css,scss,html}\" \"../**/*.dist.yml\"", - "prettier-check": "prettier --ignore-path=../.gitignore --check \"**/*.{js,css,scss,html}\" \"../**/*.dist.yml\"" + "prettier-format": "prettier --ignore-path=../.gitignore --write \"**/*.{js,css,scss,html}\" \"../**/*.dist.yml\" \"../templates/**/*.html.ep\"", + "prettier-check": "prettier --ignore-path=../.gitignore --check \"**/*.{js,css,scss,html}\" \"../**/*.dist.yml\" \"../templates/**/*.html.ep\"" }, "repository": { "type": "git", @@ -27,6 +27,7 @@ "sortablejs": "^1.15.7" }, "devDependencies": { + "@openwebwork/prettier-plugin-mojolicious-html-template": "^0.0.1", "autoprefixer": "^10.5.4", "chokidar": "^5.0.0", "cssnano": "^8.0.2", @@ -51,5 +52,10 @@ "allowScripts": { "@parcel/watcher": false, "iframe-resizer": false + }, + "overrides": { + "@awmottaz/prettier-plugin-void-html": { + "prettier": "^3.9.5" + } } } From 2c9697c9299c68d23d434753aed2c0fa67cd3b5b Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Wed, 22 Jul 2026 06:07:58 -0500 Subject: [PATCH 2/3] Apply prettier to all `.html.ep` files. --- .../cheevoMessage.html.ep | 9 +- .../Achievements/achievement_badges.html.ep | 19 +- .../Achievements/achievement_items.html.ep | 15 +- .../Achievements/cheevobigbox.html.ep | 8 +- .../AchievementsLeaderboard.html.ep | 12 +- .../ContentGenerator/Base/admin_links.html.ep | 9 +- .../Base/error_output.html.ep | 8 +- .../Base/feedback_macro_email.html.ep | 3 +- .../Base/feedback_macro_form.html.ep | 19 +- templates/ContentGenerator/Base/links.html.ep | 47 +- .../Base/login_status.html.ep | 7 +- .../ContentGenerator/Base/set_status.html.ep | 33 +- .../Base/warning_output.html.ep | 18 +- .../ContentGenerator/CourseAdmin.html.ep | 8 +- .../CourseAdmin/add_course_form.html.ep | 243 +++++----- .../archive_course_confirm.html.ep | 57 +-- .../CourseAdmin/archive_course_form.html.ep | 32 +- .../copy_otp_secrets_confirm.html.ep | 10 +- .../CourseAdmin/delete_course_form.html.ep | 32 +- .../CourseAdmin/edit_location_form.html.ep | 38 +- .../hide_inactive_course_form.html.ep | 32 +- .../CourseAdmin/manage_location_form.html.ep | 60 ++- .../manage_lti_course_map_form.html.ep | 48 +- .../manage_otp_secrets_form.html.ep | 153 ++++--- .../CourseAdmin/registration_form.html.ep | 39 +- .../CourseAdmin/rename_course_confirm.html.ep | 53 +-- .../rename_course_confirm_short.html.ep | 9 +- .../CourseAdmin/rename_course_form.html.ep | 35 +- .../reset_otp_secrets_confirm.html.ep | 2 +- .../unarchive_course_confirm.html.ep | 10 +- .../CourseAdmin/unarchive_course_form.html.ep | 34 +- .../upgrade_course_confirm.html.ep | 24 +- .../CourseAdmin/upgrade_course_form.html.ep | 15 +- .../ContentGenerator/EquationDisplay.html.ep | 8 +- templates/ContentGenerator/Feedback.html.ep | 38 +- .../Feedback/feedback_email.html.ep | 127 ++++-- .../ContentGenerator/ForgotPassword.html.ep | 22 +- .../ContentGenerator/GatewayQuiz.html.ep | 206 +++++---- .../ContentGenerator/GatewayQuiz/nav.html.ep | 69 ++- .../Grades/grade_items.html.ep | 1 - .../Grades/problem_table.html.ep | 4 +- .../Grades/student_grades.html.ep | 20 +- templates/ContentGenerator/Hardcopy.html.ep | 13 +- .../ContentGenerator/Hardcopy/form.html.ep | 42 +- templates/ContentGenerator/Home.html.ep | 6 +- .../Instructor/AchievementEditor.html.ep | 27 +- .../AchievementEditor/save_as_form.html.ep | 45 +- .../Instructor/AchievementList.html.ep | 30 +- .../AchievementList/assign_form.html.ep | 16 +- .../AchievementList/create_form.html.ep | 14 +- .../AchievementList/default_table.html.ep | 38 +- .../AchievementList/delete_form.html.ep | 12 +- .../AchievementList/edit_form.html.ep | 8 +- .../AchievementList/edit_table.html.ep | 20 +- .../AchievementList/edit_table_row.html.ep | 10 +- .../AchievementList/export_form.html.ep | 8 +- .../AchievementList/export_table.html.ep | 23 +- .../AchievementList/filter_form.html.ep | 25 +- .../AchievementList/import_form.html.ep | 23 +- .../AchievementList/score_form.html.ep | 8 +- .../AchievementNotificationEditor.html.ep | 30 +- .../existing_form.html.ep | 20 +- .../save_as_form.html.ep | 8 +- .../Instructor/AchievementUserEditor.html.ep | 39 +- .../Instructor/AddUsers.html.ep | 108 +++-- .../Instructor/Assigner.html.ep | 17 +- .../Instructor/Config.html.ep | 20 +- .../Instructor/Config/config_help.html.ep | 13 +- .../Instructor/FileManager.html.ep | 8 +- .../Instructor/FileManager/archive.html.ep | 29 +- .../Instructor/FileManager/refresh.html.ep | 23 +- .../FileManager/refresh_edit.html.ep | 8 +- .../Instructor/FileManager/view.html.ep | 4 +- .../ContentGenerator/Instructor/Index.html.ep | 98 ++-- .../Instructor/JobManager.html.ep | 135 +++--- .../Instructor/JobManager/delete_form.html.ep | 15 +- .../Instructor/JobManager/filter_form.html.ep | 33 +- .../Instructor/JobManager/sort_button.html.ep | 21 +- .../Instructor/JobManager/sort_form.html.ep | 98 ++-- .../Instructor/LTIUpdate.html.ep | 34 +- .../Instructor/PGProblemEditor.html.ep | 165 ++++--- .../PGProblemEditor/add_problem_form.html.ep | 32 +- .../code_maintenance_form.html.ep | 62 ++- .../PGProblemEditor/file_chooser.html.ep | 51 ++- .../PGProblemEditor/hardcopy_form.html.ep | 31 +- .../PGProblemEditor/pg_critic.html.ep | 30 +- .../PGProblemEditor/revert_form.html.ep | 65 +-- .../PGProblemEditor/save_as_form.html.ep | 120 +++-- .../PGProblemEditor/save_form.html.ep | 5 +- .../PGProblemEditor/view_form.html.ep | 28 +- .../Instructor/ProblemGrader.html.ep | 156 ++++--- .../Instructor/ProblemGrader/siblings.html.ep | 3 +- .../Instructor/ProblemSetDetail.html.ep | 293 ++++++------ .../ProblemSetDetail/attempts_row.html.ep | 6 +- .../ProblemSetDetail/ip_locations_row.html.ep | 25 +- ...tricted_login_proctor_password_row.html.ep | 25 +- .../Instructor/ProblemSetList.html.ep | 56 ++- .../ProblemSetList/create_form.html.ep | 20 +- .../ProblemSetList/delete_form.html.ep | 15 +- .../ProblemSetList/edit_form.html.ep | 6 +- .../ProblemSetList/export_form.html.ep | 11 +- .../ProblemSetList/filter_form.html.ep | 19 +- .../ProblemSetList/import_form.html.ep | 90 ++-- .../ProblemSetList/lms_date_sync_form.html.ep | 26 +- .../ProblemSetList/publish_form.html.ep | 26 +- .../ProblemSetList/score_form.html.ep | 11 +- .../ProblemSetList/set_list_field.html.ep | 24 +- .../ProblemSetList/set_list_row.html.ep | 136 +++--- .../ProblemSetList/set_list_table.html.ep | 53 ++- .../ProblemSetList/sort_button.html.ep | 14 +- .../ProblemSetList/sort_form.html.ep | 64 ++- .../Instructor/Scoring.html.ep | 31 +- .../Instructor/SendMail/main_form.html.ep | 158 +++++-- .../Instructor/SetMaker.html.ep | 32 +- .../SetMaker/browse_course_sets_panel.html.ep | 11 +- .../SetMaker/browse_library_panel.html.ep | 9 +- .../browse_library_panel_advanced.html.ep | 98 ++-- .../browse_library_panel_simple.html.ep | 48 +- .../SetMaker/browse_local_panel.html.ep | 33 +- .../SetMaker/browse_setdef_panel.html.ep | 3 +- .../Instructor/SetMaker/problem_row.html.ep | 307 ++++++++----- .../Instructor/SetMaker/top_row.html.ep | 51 ++- .../SetMaker/view_problems_line.html.ep | 28 +- .../ShowAnswers/instructor-selectors.html.ep | 26 +- .../ShowAnswers/past-answers-table.html.ep | 27 +- .../ContentGenerator/Instructor/Stats.html.ep | 2 +- .../Instructor/Stats/problem_menu.html.ep | 17 +- .../Instructor/Stats/problem_stats.html.ep | 111 +++-- .../Instructor/Stats/set_stats.html.ep | 110 +++-- .../Instructor/Stats/siblings.html.ep | 13 +- .../Stats/siblings_set_list.html.ep | 3 +- .../Stats/student_filter_menu.html.ep | 11 +- .../Instructor/StudentProgress/index.html.ep | 6 +- .../StudentProgress/set_progress.html.ep | 86 ++-- .../StudentProgress/siblings.html.ep | 10 +- .../StudentProgress/student_progress.html.ep | 2 +- .../StudentProgress/student_stats.html.ep | 17 +- .../Instructor/UserDetail.html.ep | 37 +- .../UserDetail/set_date_table.html.ep | 59 ++- .../Instructor/UserDetail/set_row.html.ep | 14 +- .../Instructor/UserList.html.ep | 42 +- .../Instructor/UserList/add_form.html.ep | 9 +- .../Instructor/UserList/delete_form.html.ep | 15 +- .../Instructor/UserList/edit_form.html.ep | 6 +- .../Instructor/UserList/export_form.html.ep | 32 +- .../Instructor/UserList/filter_form.html.ep | 31 +- .../Instructor/UserList/import_form.html.ep | 43 +- .../UserList/reset_2fa_form.html.ep | 19 +- .../Instructor/UserList/sort_button.html.ep | 21 +- .../Instructor/UserList/sort_form.html.ep | 84 ++-- .../Instructor/UserList/user_list.html.ep | 74 +-- .../UserList/user_list_field.html.ep | 52 ++- .../Instructor/UserList/user_row.html.ep | 30 +- .../Instructor/UsersAssignedToSet.html.ep | 23 +- .../LTI/content_item_course_selection.html.ep | 62 +-- .../LTI/content_item_selection.html.ep | 115 ++--- .../LTI/content_item_selection_error.html.ep | 52 ++- .../LTI/self_posting_form.html.ep | 11 +- templates/ContentGenerator/Login.html.ep | 52 ++- .../ContentGenerator/LoginProctor.html.ep | 30 +- templates/ContentGenerator/Logout.html.ep | 16 +- templates/ContentGenerator/Options.html.ep | 129 ++++-- templates/ContentGenerator/Problem.html.ep | 26 +- .../Problem/checkboxes.html.ep | 25 +- .../Problem/instructor_buttons.html.ep | 3 +- .../ContentGenerator/Problem/messages.html.ep | 11 +- .../ContentGenerator/Problem/siblings.html.ep | 62 ++- .../Problem/submit_buttons.html.ep | 102 +++-- templates/ContentGenerator/ProblemSet.html.ep | 6 +- .../ProblemSet/auxiliary_tools.html.ep | 79 ++-- .../ContentGenerator/ProblemSet/info.html.ep | 7 +- .../ProblemSet/problem_list.html.ep | 23 +- .../ProblemSet/problem_list_row.html.ep | 24 +- .../ProblemSet/version_list.html.ep | 97 ++-- .../ContentGenerator/ProblemSets.html.ep | 24 +- .../ContentGenerator/ProblemSets/info.html.ep | 7 +- .../ProblemSets/set_list_row.html.ep | 86 ++-- .../ContentGenerator/ResetPassword.html.ep | 65 ++- .../SampleProblemViewer.html.ep | 200 ++++---- .../sample_problem.html.ep | 214 +++++---- .../SampleProblemViewer/viewer.html.ep | 304 +++++++------ .../ShowMeAnother/messages.html.ep | 17 +- .../TwoFactorAuthentication.html.ep | 32 +- templates/HTML/CodeMirrorEditor/js.html.ep | 5 +- .../scrollingRecordList.html.ep | 44 +- .../HTML/SingleProblemGrader/grader.html.ep | 224 ++++----- templates/HTML/StudentNav/student_nav.html.ep | 55 ++- templates/HelpFiles/Achievements.html.ep | 4 +- .../HelpFiles/AchievementsLeaderboard.html.ep | 6 +- templates/HelpFiles/AdminAddCourse.html.ep | 41 +- .../HelpFiles/AdminArchiveCourse.html.ep | 6 +- templates/HelpFiles/AdminDeleteCourse.html.ep | 2 +- templates/HelpFiles/AdminHideCourses.html.ep | 8 +- .../HelpFiles/AdminManageLTICourseMap.html.ep | 18 +- .../HelpFiles/AdminManageLocations.html.ep | 14 +- .../HelpFiles/AdminManageOTPSecrets.html.ep | 12 +- templates/HelpFiles/AdminRenameCourse.html.ep | 4 +- .../HelpFiles/AdminUnarchiveCourse.html.ep | 12 +- .../HelpFiles/AdminUpgradeCourses.html.ep | 6 +- templates/HelpFiles/Grades.html.ep | 19 +- templates/HelpFiles/Hardcopy.html.ep | 40 +- .../InstructorAchievementEditor.html.ep | 48 +- .../InstructorAchievementList.html.ep | 65 +-- ...uctorAchievementNotificationEditor.html.ep | 19 +- .../InstructorAchievementUserEditor.html.ep | 10 +- .../HelpFiles/InstructorAddUsers.html.ep | 14 +- .../HelpFiles/InstructorAssigner.html.ep | 14 +- templates/HelpFiles/InstructorConfig.html.ep | 6 +- .../HelpFiles/InstructorFileManager.html.ep | 86 ++-- templates/HelpFiles/InstructorIndex.html.ep | 26 +- .../HelpFiles/InstructorJobManager.html.ep | 34 +- .../HelpFiles/InstructorLTIUpdate.html.ep | 10 +- .../InstructorPGProblemEditor.html.ep | 170 +++---- .../HelpFiles/InstructorProblemGrader.html.ep | 14 +- .../InstructorProblemSetDetail.html.ep | 60 +-- .../InstructorProblemSetList.html.ep | 49 +- templates/HelpFiles/InstructorScoring.html.ep | 70 +-- .../HelpFiles/InstructorSendMail.html.ep | 55 +-- .../HelpFiles/InstructorSetMaker.html.ep | 32 +- .../HelpFiles/InstructorShowAnswers.html.ep | 14 +- templates/HelpFiles/InstructorStats.html.ep | 6 +- .../InstructorStudentProgress.html.ep | 12 +- .../HelpFiles/InstructorUserDetail.html.ep | 26 +- .../HelpFiles/InstructorUserList.html.ep | 164 +++---- .../InstructorUsersAssignedToSet.html.ep | 4 +- templates/HelpFiles/Levels.html.ep | 20 +- templates/HelpFiles/Options.html.ep | 39 +- templates/HelpFiles/ProblemSets.html.ep | 12 +- templates/HelpFiles/admin_links.html.ep | 10 +- templates/HelpFiles/instructor_links.html.ep | 39 +- templates/RPCRenderFormats/default.html.ep | 337 +++++++------- templates/RPCRenderFormats/ptx.html.ep | 4 +- templates/exception.html.ep | 4 +- templates/exception_default.html.ep | 230 +++++----- templates/exception_min.html.ep | 54 ++- templates/layouts/help_macro.html.ep | 13 +- templates/layouts/pod_viewer.html.ep | 109 +++-- templates/layouts/system.html.ep | 428 ++++++++++-------- 238 files changed, 6379 insertions(+), 4603 deletions(-) diff --git a/templates/AchievementEvaluator/cheevoMessage.html.ep b/templates/AchievementEvaluator/cheevoMessage.html.ep index a602a82f90..5f795567a0 100644 --- a/templates/AchievementEvaluator/cheevoMessage.html.ep +++ b/templates/AchievementEvaluator/cheevoMessage.html.ep @@ -1,10 +1,9 @@ -