Skip to content

feat(vite): auto-load templates + Template helper + config flag#133

Merged
bedus-creation merged 1 commit into
mainfrom
task/vite-auto-templates
Jun 20, 2026
Merged

feat(vite): auto-load templates + Template helper + config flag#133
bedus-creation merged 1 commit into
mainfrom
task/vite-auto-templates

Conversation

@bedus-creation

Copy link
Copy Markdown
Contributor

Summary

Fixes the root cause where a fresh app got no template engine: ViteProvider never bound Jinja2Templates, and register_jinja_directives() only injected the vite() globals if a templates binding already existed.

ViteProvider now provides a template engine out of the box and ships a Laravel view()-style helper for rendering.

Changes

  • Config (vite/config/vite.py): add template: bool = True and templates_directory: str = "resources/templates".
  • Provider (vite/providers/provider.py): in register(), when template is enabled and no templates binding exists yet, build Jinja2Templates(base_path / templates_directory) and bind it as templates. The jinja2 import is guarded with a clear error pointing to pip install fastapi-startkit[vite]. register_jinja_directives() is unchanged — it now finds the binding and injects the vite() globals. An existing binding always wins, so this is fully backward-compatible.
  • Template helper (vite/template.py): new template(name, context=None) module helper and Template.render(name, context=None) static class. The request is resolved implicitly — from context["request"] if present, otherwise from a per-request ContextVar — with a fallback to the legacy Starlette TemplateResponse signature.
  • Request context (fastapi/context.py, fastapi/middleware.py): a general current_request ContextVar set by RequestContextMiddleware, registered in FastAPIProvider.boot(), so helpers can resolve the active request without it being passed explicitly.
  • Exports (vite/__init__.py): Template and template are now importable from fastapi_startkit.vite.
  • Example (example/vite-app): drops the manual templates bind and uses the auto-bound engine + template() helper.

Tests

New tests/vite/test_template.py covers: binds templates when enabled and none pre-bound; respects an existing binding; skips when template=False; vite() globals present after boot; template() and Template.render() return a TemplateResponse (via explicit request and via the ContextVar); and the clear error when no engine is bound.

  • uv run pytest tests/vite/ -v → 38 passed
  • Full suite: 1555 passed, 7 skipped; coverage 67% (above fail_under)

ViteProvider now binds a Jinja2Templates engine out of the box so fresh
apps get a working template engine and the vite() globals are injected
during boot. An existing 'templates' binding always wins, keeping the
change backward-compatible.

- Add ViteConfig.template and ViteConfig.templates_directory flags
- Auto-bind templates in ViteProvider.register() with a guarded jinja2
  import that points users to the [vite] extra
- Add Template class and template() helper (Laravel view()-style) that
  resolve the request from context or a per-request ContextVar
- Add RequestContextMiddleware to expose the active request
- Export Template and template from fastapi_startkit.vite
- Cover the new behaviour with tests
- Simplify example/vite-app to rely on the auto-bound engine
@bedus-creation bedus-creation merged commit ffed730 into main Jun 20, 2026
3 checks passed
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.

1 participant