Skip to content

Commit 2ff1d5f

Browse files
committed
support Jinja2 template backend, providing extension and tags
1 parent abf0a5d commit 2ff1d5f

18 files changed

+1116
-196
lines changed

README.md

+43
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,49 @@ If you want to overrides default attributes just add them like new attributes :
216216

217217
Although it's recommended to keep the default `type="module"` attribute as ViteJS build scripts as ES6 modules.
218218

219+
### Jinja2 template backend
220+
221+
If you are using Django with the Jinja2 template backend then alternative versions of the templatetags are provided, via an Extension.
222+
223+
If you are using [`django-jinja` library](https://niwi.nz/django-jinja/latest/#_add_additional_extensions) then you can:
224+
225+
```python
226+
from django_jinja.builtins import DEFAULT_EXTENSIONS
227+
228+
"OPTIONS": {
229+
"extensions": DEFAULT_EXTENSIONS + [
230+
# Your extensions here...
231+
"django_vite.templatetags.jinja.DjangoViteExtension"
232+
]
233+
}
234+
```
235+
236+
Or for a [vanilla Django + Jinja2 setup](https://docs.djangoproject.com/fr/4.2/topics/templates/#django.template.backends.jinja2.Jinja2) you can do something like:
237+
238+
```python
239+
from django.templatetags.static import static
240+
from django.urls import reverse
241+
242+
from jinja2 import Environment
243+
from django_vite.templatetags.jinja import DjangoViteExtension
244+
245+
246+
def environment(**options):
247+
options.setdefault("extensions", []).append(DjangoViteExtension)
248+
env = Environment(**options)
249+
return env
250+
```
251+
252+
Then usage in your templates is similar, but adjusted as is normal for Jinja2 rather than Django template language.
253+
254+
- Omit the `{% load django_vite %}` which is not needed.
255+
- Replace tag syntax with function calls, e.g.
256+
- `{% vite_react_refresh %}` becomes:
257+
`{{ vite_react_refresh() }}`
258+
- `{% vite_asset '<path to your asset>' foo="bar" %}` becomes:
259+
`{{ vite_asset('<path to your asset>', foo="bar") }}`
260+
etc
261+
219262
## Vite Legacy Plugin
220263

221264
If you want to consider legacy browsers that don't support ES6 modules loading

django_vite/templatetags/base.py

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
from typing import Dict
2+
3+
from django_vite.core.asset_loader import DjangoViteAssetLoader, DEFAULT_APP_NAME
4+
5+
6+
def vite_hmr_client(app: str = DEFAULT_APP_NAME, **kwargs: Dict[str, str]) -> str:
7+
"""
8+
Generates the script tag for the Vite WS client for HMR.
9+
Only used in development, in production this method returns
10+
an empty string.
11+
12+
Arguments:
13+
config {str} -- Configuration to use.
14+
15+
Returns:
16+
str -- The script tag or an empty string.
17+
18+
Keyword Arguments:
19+
**kwargs {Dict[str, str]} -- Adds new attributes to generated
20+
script tags.
21+
"""
22+
23+
return DjangoViteAssetLoader.instance().generate_vite_ws_client(app, **kwargs)
24+
25+
26+
def vite_asset(
27+
path: str,
28+
app: str = DEFAULT_APP_NAME,
29+
**kwargs: Dict[str, str],
30+
) -> str:
31+
"""
32+
Generates a <script> tag for this JS/TS asset, a <link> tag for
33+
all of its CSS dependencies, and a <link rel="modulepreload">
34+
for all js dependencies, as listed in the manifest file
35+
In development Vite loads all by itself.
36+
37+
Arguments:
38+
path {str} -- Path to a Vite JS/TS asset to include.
39+
config {str} -- Configuration to use.
40+
41+
Returns:
42+
str -- All tags to import this file in your HTML page.
43+
44+
Keyword Arguments:
45+
**kwargs {Dict[str, str]} -- Adds new attributes to generated
46+
script tags.
47+
48+
Raises:
49+
RuntimeError: If cannot find the file path in the
50+
manifest (only in production).
51+
52+
Returns:
53+
str -- The <script> tag and all <link> tags to import this
54+
asset in your page.
55+
"""
56+
assert path is not None
57+
return DjangoViteAssetLoader.instance().generate_vite_asset(path, app, **kwargs)
58+
59+
60+
def vite_preload_asset(path: str, app: str = DEFAULT_APP_NAME) -> str:
61+
"""
62+
Generates preloadmodule tag for this JS/TS asset and preloads
63+
all of its CSS and JS dependencies by reading the manifest
64+
file (for production only).
65+
In development does nothing.
66+
67+
Arguments:
68+
path {str} -- Path to a Vite JS/TS asset to include.
69+
70+
Returns:
71+
str -- All tags to import this file in your HTML page.
72+
73+
Raises:
74+
RuntimeError: If cannot find the file path in the
75+
manifest (only in production).
76+
77+
"""
78+
assert path is not None
79+
return DjangoViteAssetLoader.instance().preload_vite_asset(path, app)
80+
81+
82+
def vite_asset_url(path: str, app: str = DEFAULT_APP_NAME) -> str:
83+
"""
84+
Generates only the URL of an asset managed by ViteJS.
85+
Warning, this function does not generate URLs for dependant assets.
86+
87+
Arguments:
88+
path {str} -- Path to a Vite asset.
89+
config {str} -- Configuration to use.
90+
91+
Raises:
92+
RuntimeError: If cannot find the asset path in the
93+
manifest (only in production).
94+
95+
Returns:
96+
str -- The URL of this asset.
97+
"""
98+
assert path is not None
99+
return DjangoViteAssetLoader.instance().generate_vite_asset_url(path, app)
100+
101+
102+
def vite_legacy_polyfills(app: str = DEFAULT_APP_NAME, **kwargs: Dict[str, str]) -> str:
103+
"""
104+
Generates a <script> tag to the polyfills generated
105+
by '@vitejs/plugin-legacy' if used.
106+
This tag must be included at end of the <body> before including
107+
other legacy scripts.
108+
109+
Arguments:
110+
app {str} -- Configuration to use.
111+
112+
Keyword Arguments:
113+
**kwargs {Dict[str, str]} -- Adds new attributes to generated
114+
script tags.
115+
116+
Raises:
117+
RuntimeError: If polyfills path not found inside
118+
the 'manifest.json' (only in production).
119+
120+
Returns:
121+
str -- The script tag to the polyfills.
122+
"""
123+
return DjangoViteAssetLoader.instance().generate_vite_legacy_polyfills(
124+
app, **kwargs
125+
)
126+
127+
128+
def vite_legacy_asset(
129+
path: str,
130+
app: str = DEFAULT_APP_NAME,
131+
**kwargs: Dict[str, str],
132+
) -> str:
133+
"""
134+
Generates a <script> tag for legacy assets JS/TS
135+
generated by '@vitejs/plugin-legacy'
136+
(in production only, in development do nothing).
137+
138+
Arguments:
139+
path {str} -- Path to a Vite asset to include
140+
(must contains '-legacy' in its name).
141+
app {str} -- Configuration to use.
142+
143+
Keyword Arguments:
144+
**kwargs {Dict[str, str]} -- Adds new attributes to generated
145+
script tags.
146+
147+
Raises:
148+
RuntimeError: If cannot find the asset path in
149+
the manifest (only in production).
150+
151+
Returns:
152+
str -- The script tag of this legacy asset.
153+
"""
154+
155+
assert path is not None
156+
157+
return DjangoViteAssetLoader.instance().generate_vite_legacy_asset(
158+
path, app, **kwargs
159+
)
160+
161+
162+
def vite_react_refresh(
163+
app: str = DEFAULT_APP_NAME,
164+
**kwargs: Dict[str, str],
165+
) -> str:
166+
"""
167+
Generates the script for the Vite React Refresh for HMR.
168+
Only used in development, in production this method returns
169+
an empty string.
170+
171+
Keyword Arguments:
172+
**kwargs {Dict[str, str]} -- Adds new attributes to generated
173+
script tags.
174+
175+
Returns:
176+
str -- The script or an empty string.
177+
"""
178+
return DjangoViteAssetLoader.instance().generate_vite_react_refresh_url(
179+
app, **kwargs
180+
)

0 commit comments

Comments
 (0)