Skip to content

Convert the admin and editor UI from Bootstrap 3 to Bootstrap 5.3 (move #156 to master) - #218

Merged
mraible merged 14 commits into
apache:masterfrom
mraible:feature/bootstrap-5
Oct 24, 2026
Merged

mraible merged 14 commits into
apache:masterfrom
mraible:feature/bootstrap-5

Conversation

@mraible

@mraible mraible commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

#156 was merged into feature/jakarta-ee-10-migration instead of master, the same way #155 was before #216 moved it. So the Bootstrap 5 changes are on that branch but not on master. This PR moves them to master.

It's the same feature/bootstrap-5 branch as #156, with no new changes: 72 files, the same diff as #156. It includes the fixes for the two regressions found in the UI audit on #156 (dialogs not opening, and label-less fields losing the simple theme), and it merges cleanly with the latest master.

After this is merged, #157 (Playwright tests) will be retargeted to master.

mraible added 14 commits August 13, 2026 07:15
Restores the bootstrap form theme via struts2-bootstrap-plugin 6.1.0, which is Jakarta-native and emits Bootstrap 5 markup, and converts the JSPs and basic themes accordingly: class renames, data-bs-* attributes, navbar restructure, and bootstrap-icons in place of glyphicons. A tooltip.ftl template override emits data-bs-toggle so field help renders as opt-in Bootstrap tooltips initialised in roller.js. WebJar assets are served straight from META-INF/resources by the servlet container, so the webjars servlet is removed. The profile page shows the OIDC issuer and subject as separate read-only fields instead of the raw federated identity string.
# Conflicts:
#	app/pom.xml
#	app/src/main/webapp/WEB-INF/jsps/core/Setup.jsp
#	app/src/main/webapp/WEB-INF/jsps/editor/Bookmarks.jsp
#	app/src/main/webapp/WEB-INF/jsps/editor/Categories.jsp
#	app/src/main/webapp/WEB-INF/jsps/editor/Entries.jsp
#	app/src/main/webapp/WEB-INF/jsps/editor/MediaFileImageChooser.jsp
#	app/src/main/webapp/WEB-INF/jsps/editor/Templates.jsp
The editor was loading Summernote's default build, which targets Bootstrap 3 and wires its toolbar dropdowns and dialogs through data-toggle attributes that Bootstrap 5 no longer reads. Summernote 0.9.1 ships a Bootstrap 5 build, so the editor now uses that.
The theme loaded jQuery 2.1.1 and jQuery Mobile 1.4.2 from code.jquery.com over plain http. Both versions have known XSS vulnerabilities, jQuery Mobile is no longer maintained, and the standard weblog template's own Content-Security-Policy (script-src 'self') already blocked the script, which left its View Mobile Weblog link doing nothing.

The mobile templates keep their data-role markup, which the Velocity mobile macros also emit, and basic-mobile-custom.css now styles it directly: header and footer bars, inset list views with dividers, the next/previous navbar, and buttons. The category chooser opens with CSS :target from its existing #categories link. The view switch links carry ?deviceType=standard or ?deviceType=mobile, which MobileDeviceRepository already honors, and a few lines of plain JavaScript remember the choice in the roller_user_request_type cookie as before. permalink-mobile.vm's comment list also gets its missing closing </ul>.

roller-ui/styles/jquery.mobile-theme stays, because weblogs that customized this theme have their own copies of the templates that still reference it.
The mobile templates now request their stylesheet with ?deviceType=mobile. The server picks a stylesheet rendition from the device cookie or user agent, so a mobile page reached through a ?deviceType=mobile link got the standard stylesheet; jQuery Mobile's own CSS used to hide that.

The mobile day template chose between an entry's text and its summary by testing whether the text was empty, so entries without a summary printed a literal $entry.transformedSummary or an empty teaser. It now tests the summary and uses quiet references.

roller.js is included with every weblog's comment form, but most themes don't load jQuery, so its form validation block threw "$ is not defined" on those pages. The block now runs only when jQuery Validation is present, which the admin and editor pages still load.
Bootstrap 5's jQuery bridge treats an object argument as configuration only, so the fourteen `.modal({show: true})` calls created the dialogs without showing them. Category add, edit and delete, every blogroll dialog, entry delete from the list and the editor, Insert Media File, the media file lightbox, and the ping target dialogs now open again. The AJAX dialogs also use `.fail()` instead of jqXHR's `.error()`, which jQuery 3 removed, so saving from them no longer throws.
The Bootstrap 5 conversion switched the publishing time selects, the date field, the entry body and summary textareas, and the blogroll move-to select from Struts' simple theme to the bootstrap theme. That theme wraps each field in a labelled form row, so these fields rendered as broken rows with empty label columns. They use the simple theme again, as on master, and the publishing time is laid out on one line with fixed-width selects. The move-to select sizes to its longest folder name.
# Conflicts:
#	app/src/main/webapp/WEB-INF/jsps/editor/Bookmarks.jsp
#	app/src/main/webapp/theme/scripts/roller.js
# Conflicts:
#	app/src/main/webapp/WEB-INF/jsps/tiles/head.jsp
@mraible
mraible requested a review from snoopdave October 23, 2026 20:32
@mraible
mraible merged commit 3388f4c into apache:master Oct 24, 2026
11 checks passed
@mraible
mraible deleted the feature/bootstrap-5 branch October 24, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant