Skip to content

fix(theme): let a renamed copy of the bootstrap theme load its own assets - #3470

Merged
marevol merged 1 commit into
mainfrom
fix/theme-clone-159
Sep 23, 2026
Merged

marevol merged 1 commit into
mainfrom
fix/theme-clone-159

Conversation

@marevol

@marevol marevol commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Why

The page design editor is gone, so the way to change the look of the search pages is to copy the bundled bootstrap static theme. Following the bundled README (copy the directory, rename it, change theme.yml#name, upload it as a ZIP), the copy's CSS, logo and message edits never appeared: its index.html hardcoded themes/bootstrap/ for the stylesheet, both logos and app.js, and app.js loads the i18n and help bundles relative to itself, so the copy kept running the bootstrap files.

Relative URLs cannot fix this alone. Fess serves index.html at /, /search, /help, the error paths and so on, and inserts <base href="{context path}/">, so a relative URL resolves against the web application root at every depth (/search/x too), never against the theme's directory.

What changes

  • StaticThemeResponder replaces {{themePath}} in the entry file with themes/<theme name>, the path StaticThemeFilter serves the theme's assets under. It applies to both the normal and the error-page responses, since both read the entry through readEntryBytes(). A theme without the placeholder is served unchanged, so existing themes that name their own directory keep working.
  • The bundled index.html refers to its stylesheet, logos and app.js as {{themePath}}/assets/….
  • The README's Context path section documents the placeholder, and its Customising steps are rewritten: copy and rename, set name (and bump version), edit, ZIP with theme.yml at the top level, upload, then set the copy as the default or bind it to a virtual host.
  • Tests: StaticThemeResponderTest covers the expansion on serveIndex (under a context path) and serveErrorPage, and the unchanged pass-through. BundledBootstrapThemeTest requires index.html not to name themes/bootstrap and every {{themePath}} reference to exist.

The theme version stays 1.3.0: it was set for 15.9 and has not been released yet.

Verification

  • mvn test -Dtest=BundledBootstrapThemeTest,StaticThemeResponderTest,StaticThemeFilterTest,ErrorPageServletTest: 230 tests passed.
  • Headless Chromium against a distribution built with this change, OpenSearch 3.8. The bundled theme was copied as mytheme following the README, with one rule added to its styles.css (body { background-color: rgb(253, 246, 227) !important; }), uploaded on the admin Theme page and made the default. Before (main) → after, on /, /search?q=… and a 404 at a two-segment path:
Check Before After
Active theme (/api/v2/ui/config) mytheme mytheme
Stylesheet / module script themes/bootstrap/assets/styles.css, themes/bootstrap/assets/app.js themes/mytheme/assets/styles.css, themes/mytheme/assets/app.js
Logos themes/bootstrap/assets/logo*.png themes/mytheme/assets/logo*.png
i18n bundle requested /themes/bootstrap/i18n/messages.ja.json /themes/mytheme/i18n/messages.ja.json
Computed body background rgb(255, 255, 255) (edit ignored) rgb(253, 246, 227)

…sets

The bundled README tells theme authors to copy the bootstrap directory,
rename it and change theme.yml#name. The copy's index.html still named
themes/bootstrap/ for its stylesheet, logos and app.js, and app.js loads
the i18n and help bundles relative to itself, so the copy kept rendering
the bootstrap CSS, logos and messages: edits to them never showed up.

A relative URL cannot fix this, because Fess serves index.html at /,
/search, /help and the error paths under a <base href="{context path}/">.
StaticThemeResponder now replaces {{themePath}} in the entry file with
themes/<theme name>, the path StaticThemeFilter serves the theme's assets
under, and the bundled index.html refers to its files through it. Themes
that do not use the placeholder are served unchanged.

Rewrite the README customising steps to match, including where the ZIP
needs theme.yml and how to activate the copy.
@marevol marevol added this to the 15.9.0 milestone Sep 23, 2026
@marevol marevol self-assigned this Sep 23, 2026
@marevol
marevol merged commit fadf2af into main Sep 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant