Phase 4: Page() collects component media; drop manual scripts= threading
Page() now calls collect_media(content) and emits the ModuleScript / StaticScript tags itself, so views no longer thread scripts= for component-owned JS. The list views (game/session/purchase/device/ platform/playevent) compose with Fragment(filter_bar, content) instead of mark_safe(str(filter_bar) + str(content)) — keeping the node tree intact so the filter bar's media (filter_bar.js + search_select.js + range_slider.js, and date_range_picker.js on purchases) reaches Page(). The stats views drop _STATS_SCRIPTS; YearPicker's datepicker.umd.js is collected from its declared media. The scripts= argument remains for page-specific glue not owned by a component (the add-form helpers add_game.js / add_purchase.js / add_session.js, alongside search_select.js for their form widgets). Adds regression tests asserting the list and stats pages auto-load their widget scripts with no scripts= in the view, and documents the node/ media model in CLAUDE.md. https://claude.ai/code/session_01BKurBhE3Qj25p7Bfsg7EeK
This commit is contained in:
+16
-2
@@ -276,9 +276,23 @@ def Page(
|
||||
scripts: SafeText | str = "",
|
||||
mastered: bool = False,
|
||||
) -> SafeText:
|
||||
"""Assemble a full HTML document around `content` (the fast_app equivalent)."""
|
||||
"""Assemble a full HTML document around `content` (the fast_app equivalent).
|
||||
|
||||
Scripts are collected from `content`'s component tree: every component
|
||||
declares its JS via `Media`, and `collect_media` gathers (deduped) the union
|
||||
for the whole page. The `scripts` argument remains for page-specific glue
|
||||
that isn't owned by a reusable component (e.g. the add-form helpers).
|
||||
"""
|
||||
from common.components import ModuleScript, StaticScript, collect_media
|
||||
from games.views.general import global_current_year, model_counts
|
||||
|
||||
media = collect_media(content)
|
||||
collected_scripts = "".join(
|
||||
[str(ModuleScript(name)) for name in media.js]
|
||||
+ [str(StaticScript(name)) for name in media.js_external]
|
||||
)
|
||||
all_scripts = collected_scripts + (str(scripts) if scripts else "")
|
||||
|
||||
counts = model_counts(request)
|
||||
year = global_current_year(request)["global_current_year"]
|
||||
navbar = Navbar(
|
||||
@@ -328,7 +342,7 @@ def Page(
|
||||
f' <div id="main-container" class="flex flex-1 flex-col pt-8 pb-16">{content}</div>\n'
|
||||
f' <span class="fixed left-2 bottom-2 text-xs text-slate-300 dark:text-slate-600">{version()} ({version_date()})</span>\n'
|
||||
" </div>\n"
|
||||
f" {scripts}\n"
|
||||
f" {all_scripts}\n"
|
||||
f" {_main_script(mastered)}\n"
|
||||
" <!-- hx-swap-oob makes sure the modal gets removed upon any HTMX response -->\n"
|
||||
' <div id="global-modal-container" hx-swap-oob="true"></div>\n'
|
||||
|
||||
Reference in New Issue
Block a user