Skip to content

fix(theme): make template lookup stateless with theme-prefixed names#116

Merged
x3ek merged 3 commits into
mainfrom
fix/110-stateless-theme-loader
Jul 3, 2026
Merged

fix(theme): make template lookup stateless with theme-prefixed names#116
x3ek merged 3 commits into
mainfrom
fix/110-stateless-theme-loader

Conversation

@x3ek

@x3ek x3ek commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Closes #110

The loader's mutable current_theme allowed concurrent requests with different theme overrides to cross-contaminate template resolution, since Jinja resolves extends/includes through the loader at render time.

  • Template names now carry a theme prefix (<theme>/<template>); the loader resolves the same custom cache, theme dir, default dir fallback chain per lookup with no shared state
  • New ThemedEnvironment.join_path keeps extends/includes within the parent template's theme
  • Removed loader.current_theme and the save/restore logic in render_partial
  • New tests/test_theme_loader.py: fallback chain, join_path, and a concurrent-render test interleaving all three themes

Verification: checks green (340 tests). Browser-verified all three bundled themes (default, blue-tech, terminal) on index and post pages, a per-post theme: blue-tech override rendering alongside a default-theme index, and 30 concurrent mixed-theme requests with zero CSS cross-contamination.

🤖 Generated with Claude Code

Route theme selection through theme-prefixed template names
(get_template("<theme>/<name>")) instead of mutable loader.current_theme.
The loader resolves the custom / theme / default fallback chain from the
prefix, and a ThemedEnvironment.join_path keeps extends/includes within
the parent's theme. Removes the shared per-request state that let
concurrent renders with different theme overrides cross-contaminate, and
the save/restore in render_partial.

Closes #110

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@x3ek x3ek added this to the SquishMark 1.0 milestone Jul 3, 2026
@x3ek x3ek requested a review from Copilot July 3, 2026 12:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #110 by removing mutable, per-request theme state from the shared Jinja loader to prevent concurrent requests with different theme overrides from contaminating each other’s template resolution. It does so by encoding the theme into template names (<theme>/<template>) and adding an environment hook to keep {% extends %} / {% include %} resolution within the parent template’s theme.

Changes:

  • Introduces theme-prefixed template names and a stateless loader lookup path (custom cache → requested theme → default fallback).
  • Adds ThemedEnvironment.join_path so bare extends/includes inherit the parent’s theme.
  • Adds focused tests covering fallback behavior, join_path, and concurrent mixed-theme rendering.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/squishmark/services/theme/loader.py Removes mutable theme state and resolves templates via theme-prefixed names with fallback chain; adds ThemedEnvironment.join_path.
src/squishmark/services/theme/engine.py Switches template loading to use theme-prefixed names and removes current_theme save/restore logic in render_partial.
tests/test_theme_loader.py Adds regression tests for split/prefix logic, loader fallback chain, join_path behavior, and concurrent interleaving.
tests/test_admin_notes.py Updates partial-render tests to assert theme-prefixed lookups instead of current_theme restoration.

Comment thread src/squishmark/services/theme/loader.py
x3ek and others added 2 commits July 3, 2026 07:58
Guard AsyncHybridLoader.get_source against theme or template names that
are absolute, contain backslashes, or have ".." segments; such names now
raise TemplateNotFound before any filesystem access.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@x3ek x3ek merged commit 4551d1b into main Jul 3, 2026
5 checks passed
@x3ek x3ek deleted the fix/110-stateless-theme-loader branch July 3, 2026 13:10
@x3ek x3ek mentioned this pull request Jul 3, 2026
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.

Theme template resolution races on shared mutable loader state

2 participants