Skip to content

Convert the admin and editor UI from Bootstrap 3 to Bootstrap 5.3 - #156

Open
mraible wants to merge 8 commits into
feature/oidc-loginfrom
feature/bootstrap-5
Open

mraible wants to merge 8 commits into
feature/oidc-loginfrom
feature/bootstrap-5

Conversation

@mraible

@mraible mraible commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #155 (2/3 in the stack); the diff against its base branch holds only this PR's changes.

Converts the admin and editor UI from Bootstrap 3 to Bootstrap 5.3.8. The bootstrap form theme comes through struts2-bootstrap-plugin 6.2.0, which is Jakarta-native and emits Bootstrap 5 markup.

No functionality is removed. Visual and behavioral deltas beyond the restyle, so nothing merges unnoticed:

  • Alert banners are dismissible again: the old Bootstrap 3 close-button markup rendered broken under Bootstrap 5, and a .fade { opacity: 0 } override in roller.css (a Bootstrap 3-era leftover) made any fade show component invisible — both fixed, auto-hide after 10 seconds unchanged
  • Entries/Comments count badges on the main menu are visible pills again (a bare .badge has no background in Bootstrap 5)
  • Themed submit buttons across ~25 JSPs now use the simple theme, so button pairs (Save/Cancel, Upload/Cancel, Yes/No, the entry editor's Save as Draft/Post to Weblog) sit on one row with a primary action instead of stacking in their own form rows
  • Field help renders as opt-in Bootstrap tooltips via a tooltip.ftl template override initialised in roller.js; the stylesheet editor's button hints use native title tooltips since the simple theme has no icon slot
  • bootstrap-icons replaces glyphicons
  • The entry editor loads Summernote's Bootstrap 5 build, so its toolbar dropdowns and dialogs work with Bootstrap 5's data attributes
  • Master's new setup-token page is converted to Bootstrap 5 as well
  • The profile page shows the OIDC issuer and subject as separate read-only fields instead of the raw federated identity string

The result was audited page by page against a seeded master baseline: all 24 admin/editor pages were screenshot-compared with identical data on both sides. That comparison caught two regressions, fixed here: the entry editor's collapsible section headers rendered as blue links, and the date-picker calendar icons in the Entries/Comments sidebars wrapped below their inputs.

The Basic Mobile theme drops jQuery 2.1.1 and jQuery Mobile 1.4.2, which it loaded from code.jquery.com over plain http. Both have known XSS vulnerabilities, jQuery Mobile is unmaintained, and the standard template's own CSP already blocked the script, so its View Mobile Weblog link did nothing:

  • The mobile templates keep their data-role markup and basic-mobile-custom.css styles it directly; the category chooser opens with CSS :target
  • The view switch links carry ?deviceType=, which the server already honors, and a few lines of plain JavaScript remember the choice in the existing cookie
  • Mobile pages request the mobile stylesheet explicitly (jQuery Mobile's CSS had been hiding that the server served the standard one), and entry teasers no longer print a literal $entry.transformedSummary
  • roller-ui/styles/jquery.mobile-theme stays for weblogs whose customized copies of the theme still reference it

roller.js, which every weblog's comment form includes, now runs its jQuery Validation block only when jQuery Validation is loaded, so themes without jQuery no longer log $ is not defined.

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.
@mraible
mraible force-pushed the feature/bootstrap-5 branch from 539f9de to 26ed950 Compare August 13, 2026 13:18
# 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants