feat(vite): auto-load Jinja2 templates from the Vite provider#135
Merged
Conversation
Fresh apps got no template engine because ViteProvider only injected the
vite() globals when a "templates" binding already existed. The provider
now binds a Jinja2Templates engine out of the box, config-gated and
backward-compatible.
- Add ViteConfig.template (default True) and
ViteConfig.templates_directory (default "resources/templates")
- ViteProvider.register() binds "templates" when enabled and none is
pre-bound; an existing binding always wins. The jinja2 import is
guarded with a clear "install fastapi-startkit[vite]" message
- Publish the template stub under resources/templates/index.html so all
scaffolding stays consistent under resources/
- Sync the example app's config/vite.py with the new fields
- Cover binding, override, disabled, post-boot globals and the missing
jinja2 error in tests/vite/
Rendering stays the standard Starlette way:
app.make("templates").TemplateResponse(request, name, context).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reimplements the Vite template fix from the reverted PR #133, provider-only — no helper function, no
Templateclass, no ambient/global request, no middleware or ContextVar.Fresh apps previously got no template engine:
ViteProvider.register_jinja_directives()only injected thevite()globals when atemplatesbinding already existed, so a brand-new app had nothing to render with. The provider now binds aJinja2Templatesengine out of the box.Changes
ViteConfig: addtemplate: bool = Trueandtemplates_directory: str = "resources/templates".ViteProvider.register(): whenconfig.templateis true and notemplatesbinding exists, buildJinja2Templates(directory=base_path/templates_directory)and bind it. Thejinja2/starlette.templatingimport is guarded and raises a clearinstall fastapi-startkit[vite]error. An existingtemplatesbinding always wins (backward-compatible).register_jinja_directives()is left unchanged.resources/templates/index.htmlso all published scaffolding is consistent underresources/(resources/css,resources/js,resources/templates). The stub references{{ vite('resources/js/app.ts') }}andvite.config.tsinputresources/js/app.ts— these line up.example/vite-app/config/vite.pywith the new fields. The example keeps binding its owntemplatesengine inFastAPIProvider(registered beforeViteProvider), demonstrating the "existing binding wins" path;routes/web.pyrenders the standard way and is unchanged.Rendering
Unchanged, standard Starlette/FastAPI:
No framework rendering helper is introduced.
Explicitly excluded (per task #272)
No
vite/template.py, notemplate()helper, noTemplateclass, noRequestContextMiddleware, nocurrent_requestContextVar, no global/ambient request, and nothing new exported fromvite/__init__.py.Tests
tests/vite/test_template_binding.pycovers: bindstemplateswhen enabled and none pre-bound; respects an existing binding; skips whentemplate=False;vite()/vite_asset()/vite_react_refresh()present ontemplates.env.globalsafter boot; missing-jinja2 raises the clear install error.uv run pytest tests/vite/ -v→ 36 passeduv run pytest --ignore=tests/masoniteorm/postgres --cov→ 1553 passed, 7 skipped, total coverage 67.23% (abovefail_under)ruff format+ruff checkcleanDo not merge — merging is the user's job.