miki-template 2.0.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +13 -37
- package/.github/workflows/docs.yml +105 -0
- package/.github/workflows/npm-publish-github-packages.yml +36 -0
- package/README.md +69 -14
- package/assets/logo.png +0 -0
- package/benchmarks/ejs-results.json +4 -4
- package/benchmarks/handlebars-results.json +6 -6
- package/benchmarks/miki-results.json +4 -4
- package/benchmarks/pug-results.json +4 -4
- package/benchmarks/stress.mjs +1 -1
- package/docs/api/async-render.md +85 -0
- package/docs/api/cache.md +87 -0
- package/docs/api/compile.md +128 -0
- package/docs/api/context-processors.md +77 -0
- package/docs/api/filters.md +217 -0
- package/docs/api/finder.md +94 -0
- package/docs/api/helpers.md +53 -0
- package/docs/api/i18n.md +157 -0
- package/docs/api/index.md +54 -0
- package/docs/api/libraries.md +207 -0
- package/docs/api/render-partial.md +81 -0
- package/docs/api/render.md +92 -0
- package/docs/api/security.md +145 -0
- package/docs/api/setup-express.md +76 -0
- package/docs/api/tags.md +134 -0
- package/docs/assets/banner.png +0 -0
- package/docs/assets/logo.png +0 -0
- package/docs/guide/advanced-usage.md +397 -0
- package/docs/guide/async-rendering.md +308 -0
- package/docs/guide/context-processors.md +257 -0
- package/docs/guide/custom-filters.md +311 -0
- package/docs/guide/custom-tags.md +271 -0
- package/docs/guide/filters.md +642 -0
- package/docs/guide/getting-started.md +102 -0
- package/docs/guide/installation.md +95 -0
- package/docs/guide/partial-templates.md +367 -0
- package/docs/guide/quick-start.md +222 -0
- package/docs/guide/security.md +345 -0
- package/docs/guide/tags.md +783 -0
- package/docs/guide/template-discovery.md +170 -0
- package/docs/guide/template-inheritance.md +273 -0
- package/docs/guide/what-is-miki-template.md +28 -0
- package/docs/guide/why-miki-template.md +75 -0
- package/docs/index.md +104 -0
- package/docs/integrations/elysia.md +78 -0
- package/docs/integrations/express.md +219 -0
- package/docs/integrations/fastify.md +77 -0
- package/docs/integrations/hono.md +78 -0
- package/docs/integrations/index.md +68 -0
- package/docs/integrations/koa.md +88 -0
- package/docs/integrations/nestjs.md +78 -0
- package/docs/integrations/tsed.md +81 -0
- package/docs/javascripts/extra.js +174 -0
- package/docs/performance.md +37 -0
- package/docs/stylesheets/extra.css +819 -0
- package/mkdocs.yml +217 -0
- package/overrides/main.html +26 -0
- package/overrides/partials/footer.html +9 -0
- package/package.json +4 -2
- package/requirements-docs.txt +1 -0
- package/docs/README.md +0 -18
- package/docs/advanced_usage.md +0 -71
- package/docs/api.md +0 -122
- package/docs/filters.md +0 -708
- package/docs/installation.md +0 -106
- package/docs/integrations.md +0 -214
- package/docs/overview.md +0 -79
- package/docs/partialdef.md +0 -70
- package/docs/security.md +0 -27
- package/docs/tags.md +0 -673
- package/docs/usage.md +0 -646
package/docs/filters.md
DELETED
|
@@ -1,708 +0,0 @@
|
|
|
1
|
-
# Filters Reference
|
|
2
|
-
|
|
3
|
-
`miki-template` includes a comprehensive set of built-in filters matching Django's filter library. Filters are applied to variables using the pipe `|` character, and can be chained: `{{ value|filter1|filter2:"arg" }}`.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Filter Chaining
|
|
8
|
-
|
|
9
|
-
Filters can be chained — the output of each filter becomes the input of the next:
|
|
10
|
-
|
|
11
|
-
```html
|
|
12
|
-
{{ name|lower|capfirst }}
|
|
13
|
-
<!-- "miki" → "miki" → "Miki" -->
|
|
14
|
-
|
|
15
|
-
{{ user.bio|striptags|truncatewords:20 }}
|
|
16
|
-
<!-- Strip HTML tags, then truncate to 20 words -->
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Text Filters
|
|
22
|
-
|
|
23
|
-
### `upper`
|
|
24
|
-
Converts a string to UPPERCASE.
|
|
25
|
-
```html
|
|
26
|
-
{{ "hello"|upper }} → "HELLO"
|
|
27
|
-
{{ name|upper }} → "JOHN"
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### `lower`
|
|
31
|
-
Converts a string to lowercase.
|
|
32
|
-
```html
|
|
33
|
-
{{ "HELLO"|lower }} → "hello"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### `title`
|
|
37
|
-
Converts to Title Case (first letter of each word capitalized).
|
|
38
|
-
```html
|
|
39
|
-
{{ "hello world"|title }} → "Hello World"
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### `capfirst`
|
|
43
|
-
Capitalizes only the first character.
|
|
44
|
-
```html
|
|
45
|
-
{{ "hello"|capfirst }} → "Hello"
|
|
46
|
-
{{ "h"|capfirst }} → "H"
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### `slugify`
|
|
50
|
-
Converts to a URL-safe slug by lowercasing, removing accents, and replacing spaces with hyphens.
|
|
51
|
-
```html
|
|
52
|
-
{{ "Hello World!"|slugify }} → "hello-world"
|
|
53
|
-
{{ "Café con Leche"|slugify }} → "cafe-con-leche"
|
|
54
|
-
{{ " Multiple Spaces "|slugify }} → "multiple-spaces"
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### `wordcount`
|
|
58
|
-
Returns the number of words (whitespace-separated tokens).
|
|
59
|
-
```html
|
|
60
|
-
{{ "one two three"|wordcount }} → 3
|
|
61
|
-
{{ " "|wordcount }} → 0
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### `truncatewords:N`
|
|
65
|
-
Truncates the string to approximately N words, appending `...`.
|
|
66
|
-
```html
|
|
67
|
-
{{ "one two three four five"|truncatewords:3 }} → "one two three ..."
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### `truncatechars:N`
|
|
71
|
-
Truncates to N characters (including the `...` suffix if truncation occurs).
|
|
72
|
-
```html
|
|
73
|
-
{{ "Hello World"|truncatechars:8 }} → "Hello..."
|
|
74
|
-
{{ "Hi"|truncatechars:5 }} → "Hi" (no truncation needed)
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### `truncatechars_html:N`
|
|
78
|
-
Like `truncatechars` but respects HTML tags — tags are preserved in full and only visible text counts toward the limit.
|
|
79
|
-
```html
|
|
80
|
-
{{ "<p>Hello world</p>"|truncatechars_html:10 }} → "<p>Hello worl...</p>"
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### `linebreaks`
|
|
84
|
-
Converts newlines into paragraphs (`<p>`) and standalone line breaks into `<br>`.
|
|
85
|
-
```html
|
|
86
|
-
{{ "Line one\n\nLine two\nLine three"|linebreaks }}
|
|
87
|
-
<!-- Output: <p>Line one</p><p>Line two<br>Line three</p> -->
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### `linebreaksbr`
|
|
91
|
-
Converts all newlines to `<br>` tags. Does **not** wrap in `<p>` tags.
|
|
92
|
-
```html
|
|
93
|
-
{{ "Line one\nLine two"|linebreaksbr }}
|
|
94
|
-
<!-- Output: Line one<br>Line two -->
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### `urlize`
|
|
98
|
-
Automatically converts URLs in text into clickable `<a>` links.
|
|
99
|
-
```html
|
|
100
|
-
{{ "visit https://example.com for more"|urlize }}
|
|
101
|
-
<!-- Output: visit <a href="https://example.com">https://example.com</a> for more -->
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### `cut:value`
|
|
105
|
-
Removes all occurrences of the specified value from the string.
|
|
106
|
-
```html
|
|
107
|
-
{{ "Hello World"|cut:" " }} → "HelloWorld"
|
|
108
|
-
{{ "a|b|c"|cut:"|" }} → "abc"
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### `addslashes`
|
|
112
|
-
Adds backslashes before single quotes, double quotes, and backslashes.
|
|
113
|
-
```html
|
|
114
|
-
{{ 'He said "Hello"'|addslashes }} → 'He said \"Hello\"'
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### `removetags:tag1,tag2,...`
|
|
118
|
-
Removes the named HTML tags (and their contents).
|
|
119
|
-
```html
|
|
120
|
-
{{ "<p>Hello</p><b>World</b>"|removetags:"p,b" }} → "HelloWorld"
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### `reverse`
|
|
124
|
-
Reverses a string or array.
|
|
125
|
-
```html
|
|
126
|
-
{{ "hello"|reverse }} → "olleh"
|
|
127
|
-
{{ items|reverse }} → [3, 2, 1]
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### `split:separator`
|
|
131
|
-
Splits a string into an array. Default separator is a single space.
|
|
132
|
-
```html
|
|
133
|
-
{{ "a,b,c"|split:"," }} → ["a", "b", "c"]
|
|
134
|
-
{{ "hello world"|split }} → ["hello", "world"]
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### `replace:old,new`
|
|
138
|
-
Replaces occurrences of `old` with `new` in the string.
|
|
139
|
-
```html
|
|
140
|
-
{{ "hello world"|replace:"world,Earth" }} → "hello Earth"
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### `length_is:N`
|
|
144
|
-
Returns `true` if the value's length equals N, otherwise `false`.
|
|
145
|
-
```html
|
|
146
|
-
{{ "hello"|length_is:5 }} → true
|
|
147
|
-
{{ items|length_is:3 }} → true/false
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## HTML / Security Filters
|
|
153
|
-
|
|
154
|
-
### `safe`
|
|
155
|
-
Marks the value as **HTML-safe**, bypassing auto-escaping. Use with caution — never pass unsanitized user input through `|safe`.
|
|
156
|
-
```html
|
|
157
|
-
{{ "<b>Bold</b>"|safe }} → <b>Bold</b> (NOT <b>Bold</b>)
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### `escape`
|
|
161
|
-
Explicitly escapes HTML entities. Useful when `autoescape` is `off`.
|
|
162
|
-
```html
|
|
163
|
-
{% autoescape off %}
|
|
164
|
-
{{ user_input|escape }} → <script>alert()</script>
|
|
165
|
-
{% endautoescape %}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
## URL / Encoding Filters
|
|
171
|
-
|
|
172
|
-
### `urlencode`
|
|
173
|
-
URL-encodes the string. By default, uses query-string encoding (spaces → `+`).
|
|
174
|
-
```html
|
|
175
|
-
{{ "Hello World"|urlencode }} → "Hello+World"
|
|
176
|
-
{{ "a/b c"|urlencode }} → "a%2Fb+c"
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### `escapeuri`
|
|
180
|
-
Percent-encodes all special characters in a URI.
|
|
181
|
-
```html
|
|
182
|
-
{{ "https://example.com?q=hello world"|escapeuri }}
|
|
183
|
-
→ "https%3A%2F%2Fexample.com%3Fq%3Dhello%20world"
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### `base64_encode`
|
|
187
|
-
Encodes a string to Base64.
|
|
188
|
-
```html
|
|
189
|
-
{{ "hello"|base64_encode }} → "aGVsbG8="
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### `base64_decode`
|
|
193
|
-
Decodes a Base64 string. Returns the original value if decoding fails or produces invalid UTF-8.
|
|
194
|
-
```html
|
|
195
|
-
{{ "aGVsbG8="|base64_decode }} → "hello"
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
## String Formatting Filters
|
|
201
|
-
|
|
202
|
-
### `stringformat:"fmt"`
|
|
203
|
-
Formats the value using Python-style format strings (`%s`, `%d`, etc.).
|
|
204
|
-
```html
|
|
205
|
-
{{ 42|stringformat:"d" }} → "42"
|
|
206
|
-
{{ 3.14159|stringformat:".2f" }} → "3.14"
|
|
207
|
-
{{ "x"|stringformat:"s" }} → "x"
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### `json`
|
|
211
|
-
Safely serializes a value to JSON, marked safe for use inside `<script>` blocks.
|
|
212
|
-
```html
|
|
213
|
-
{{ data|json }}
|
|
214
|
-
<!-- Output: {"users":[{"name":"Alice"}]} (not HTML-escaped) -->
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## List / Sequence Filters
|
|
220
|
-
|
|
221
|
-
### `length`
|
|
222
|
-
Returns the length of an array, object, string, or any object with a `.length` property.
|
|
223
|
-
```html
|
|
224
|
-
{{ items|length }} → 5 (for arrays)
|
|
225
|
-
{{ "hello"|length }} → 5
|
|
226
|
-
{{ object|length }} → number of keys
|
|
227
|
-
{{ undefined|length }} → 0
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### `join:separator`
|
|
231
|
-
Joins an array with the specified separator.
|
|
232
|
-
```html
|
|
233
|
-
{{ tags|join:", " }} → "js, python, rust"
|
|
234
|
-
{{ items|join:" + " }} → "a + b + c"
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### `slice:"start:end"`
|
|
238
|
-
Slices an array or string like Python (`[start:end]`). Supports negative indices.
|
|
239
|
-
```html
|
|
240
|
-
{{ items|slice:"1:3" }} → items[1], items[2]
|
|
241
|
-
{{ items|slice:":2" }} → first 2 items
|
|
242
|
-
{{ items|slice:"1:" }} → items from index 1 onwards
|
|
243
|
-
{{ "hello"|slice:"1:4" }} → "ell"
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### `sort`
|
|
247
|
-
Sorts an array in ascending order. Strings use locale-aware comparison.
|
|
248
|
-
```html
|
|
249
|
-
{{ [3, 1, 2]|sort }} → [1, 2, 3]
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
### `unique`
|
|
253
|
-
Removes duplicate values from an array.
|
|
254
|
-
```html
|
|
255
|
-
{{ [1, 2, 2, 3]|unique }} → [1, 2, 3]
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### `random`
|
|
259
|
-
Returns a random element from an array.
|
|
260
|
-
```html
|
|
261
|
-
{{ ["a", "b", "c"]|random }} → "b" (random)
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### `dictsort:"key"`
|
|
265
|
-
Sorts an array of objects by the specified attribute (ascending).
|
|
266
|
-
```html
|
|
267
|
-
{% for item in items|dictsort:"name" %}
|
|
268
|
-
{{ item.name }}
|
|
269
|
-
{% endfor %}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### `dictsortreversed:"key"`
|
|
273
|
-
Sorts an array of objects by the specified attribute (descending).
|
|
274
|
-
```html
|
|
275
|
-
{% for item in items|dictsortreversed:"price" %}
|
|
276
|
-
{{ item.name }} - ${{ item.price }}
|
|
277
|
-
{% endfor %}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
---
|
|
281
|
-
|
|
282
|
-
## Default / Fallback Filters
|
|
283
|
-
|
|
284
|
-
### `default:fallback`
|
|
285
|
-
Uses the fallback value if the original value is falsy (`null`, `undefined`, or empty string `""`).
|
|
286
|
-
```html
|
|
287
|
-
{{ user.name|default:"Anonymous" }} → "Anonymous" if name is missing
|
|
288
|
-
{{ ""|default:"empty" }} → "empty"
|
|
289
|
-
{{ 0|default:"zero" }} → "zero"
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### `default_if_none:fallback`
|
|
293
|
-
Uses the fallback value only if the original value is `null` or `undefined` (not empty string).
|
|
294
|
-
```html
|
|
295
|
-
{{ value|default_if_none:"N/A" }} → "N/A" if value === null or value === undefined
|
|
296
|
-
{{ ""|default_if_none:"N/A" }} → "" (empty string is not none)
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### `firstof`
|
|
300
|
-
Returns the first truthy value from the arguments.
|
|
301
|
-
```html
|
|
302
|
-
{{ ""|firstof:user.name:guest:default }} → user.name or "guest" or "default"
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
## Date / Time Filters
|
|
308
|
-
|
|
309
|
-
All date filters accept `Date` objects, ISO strings, or timestamps.
|
|
310
|
-
|
|
311
|
-
### `date:"format"`
|
|
312
|
-
Formats a date using Django-style format codes:
|
|
313
|
-
| Code | Meaning | Example |
|
|
314
|
-
|------|---------|---------|
|
|
315
|
-
| `d` | Day with leading zero | `01–31` |
|
|
316
|
-
| `j` | Day without leading zero | `1–31` |
|
|
317
|
-
| `m` | Month with leading zero | `01–12` |
|
|
318
|
-
| `n` | Month without leading zero | `1–12` |
|
|
319
|
-
| `Y` | Full year | `2026` |
|
|
320
|
-
| `y` | 2-digit year | `26` |
|
|
321
|
-
| `H` | 24-hour with leading zero | `00–23` |
|
|
322
|
-
| `i` | Minutes | `00–59` |
|
|
323
|
-
| `s` | Seconds | `00–59` |
|
|
324
|
-
| `F` | Full month name | `January` |
|
|
325
|
-
| `M` | Short day/month name | `Jan` |
|
|
326
|
-
|
|
327
|
-
```html
|
|
328
|
-
{{ post.published|date:"Y-m-d" }} → "2026-08-31"
|
|
329
|
-
{{ post.published|date:"F j, Y" }} → "August 31, 2026"
|
|
330
|
-
{{ post.published|date:"H:i" }} → "14:30"
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### `time:"format"`
|
|
334
|
-
Same as `date` but only outputs time portion.
|
|
335
|
-
|
|
336
|
-
### `strftime:"format"`
|
|
337
|
-
Uses `date-fns` format patterns (PPpp, yyyy-MM-dd, etc.) for full locale support.
|
|
338
|
-
```html
|
|
339
|
-
{{ now|strftime:"PPpp" }} → "Aug 31, 2026 at 2:30 PM"
|
|
340
|
-
{{ now|strftime:"yyyy-MM-dd" }} → "2026-08-31"
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### `date_format:"format"`
|
|
344
|
-
Alias for `strftime` with additional custom patterns.
|
|
345
|
-
|
|
346
|
-
### `timesince`
|
|
347
|
-
Returns a human-readable "time ago" string (e.g., "4 minutes", "2 hours", "3 days").
|
|
348
|
-
```html
|
|
349
|
-
{{ post.created|timesince }} → "2 hours"
|
|
350
|
-
{{ post.created|timesince:other_date }} → "3 days" (relative to other_date)
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### `timeuntil`
|
|
354
|
-
Returns a human-readable "time until" string.
|
|
355
|
-
```html
|
|
356
|
-
{{ event.date|timeuntil }} → "5 days"
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
### `time_diff:date`
|
|
360
|
-
Returns the absolute time difference between two dates as a human-readable string.
|
|
361
|
-
```html
|
|
362
|
-
{{ event.date|time_diff }} → "3 days"
|
|
363
|
-
{{ event.date|time_diff:now }} → difference from now
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### `ago`
|
|
367
|
-
Returns a human-readable relative time string like "2 days ago", "1 hour ago", etc.
|
|
368
|
-
```html
|
|
369
|
-
{{ comment.created|ago }} → "2 days ago"
|
|
370
|
-
{{ comment.created|ago }} → "just now" (if less than 1 minute ago)
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
### `until`
|
|
374
|
-
Returns a human-readable string representing time until the given date.
|
|
375
|
-
```html
|
|
376
|
-
{{ event.date|until }} → "3 days"
|
|
377
|
-
{{ event.date|until }} → "now" (if less than 1 minute away)
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
---
|
|
381
|
-
|
|
382
|
-
## Numeric Filters
|
|
383
|
-
|
|
384
|
-
### `add:N`
|
|
385
|
-
Adds N to the value. Also works for string concatenation and array concatenation.
|
|
386
|
-
```html
|
|
387
|
-
{{ count|add:5 }} → count + 5
|
|
388
|
-
{{ items|add:other }} → concatenated array or string
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
### `sub:N`
|
|
392
|
-
Subtracts N from the value.
|
|
393
|
-
```html
|
|
394
|
-
{{ 10|sub:3 }} → 7
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
### `mult:N`
|
|
398
|
-
Multiplies the value by N.
|
|
399
|
-
```html
|
|
400
|
-
{{ 4|mult:5 }} → 20
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
### `square`
|
|
404
|
-
Returns the square of the value.
|
|
405
|
-
```html
|
|
406
|
-
{{ 6|square }} → 36
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
### `sqrt`
|
|
410
|
-
Returns the square root of the value. Returns 0 for negative numbers.
|
|
411
|
-
```html
|
|
412
|
-
{{ 9|sqrt }} → 3
|
|
413
|
-
{{ -1|sqrt }} → 0
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
### `mod:N`
|
|
417
|
-
Returns the modulo (remainder) of the value divided by N. Returns 0 if N is 0.
|
|
418
|
-
```html
|
|
419
|
-
{{ 10|mod:3 }} → 1
|
|
420
|
-
{{ 10|mod:0 }} → 0
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
### `divisibleby:N`
|
|
424
|
-
Returns `true` if the value is divisible by N.
|
|
425
|
-
```html
|
|
426
|
-
{{ 10|divisibleby:5 }} → true
|
|
427
|
-
{{ 7|divisibleby:2 }} → false
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### `floatformat:N`
|
|
431
|
-
Formats a number to N decimal places. Django default is 1 decimal.
|
|
432
|
-
|
|
433
|
-
| arg | behavior |
|
|
434
|
-
|-----|----------|
|
|
435
|
-
| (none) | 1 decimal (`3.4`) |
|
|
436
|
-
| `0` | 0 decimals (`3`) |
|
|
437
|
-
| `1` | 1 decimal (`3.4`) |
|
|
438
|
-
| `2` | 2 decimals (`3.40`) |
|
|
439
|
-
| `-1` | all decimals, trimmed |
|
|
440
|
-
|
|
441
|
-
```html
|
|
442
|
-
{{ 3.14159|floatformat }} → "3.1"
|
|
443
|
-
{{ 3.14159|floatformat:2 }} → "3.14"
|
|
444
|
-
{{ 3.000|floatformat:0 }} → "3"
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
### `abs`
|
|
448
|
-
Returns the absolute value of a number.
|
|
449
|
-
```html
|
|
450
|
-
{{ -5|abs }} → 5
|
|
451
|
-
{{ 5|abs }} → 5
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
### `round:N`
|
|
455
|
-
Rounds to N decimal places (default: 0 decimals).
|
|
456
|
-
```html
|
|
457
|
-
{{ 3.14159|round:2 }} → 3.14
|
|
458
|
-
{{ 3.5|round }} → 4
|
|
459
|
-
{{ 3.4|round }} → 3
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
### `floor`
|
|
463
|
-
Rounds down to the nearest integer.
|
|
464
|
-
```html
|
|
465
|
-
{{ 3.7|floor }} → 3
|
|
466
|
-
{{ -3.7|floor }} → -4
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
### `ceil`
|
|
470
|
-
Rounds up to the nearest integer.
|
|
471
|
-
```html
|
|
472
|
-
{{ 3.2|ceil }} → 4
|
|
473
|
-
{{ -3.2|ceil }} → -3
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
### `min:N` / `min:array`
|
|
477
|
-
Returns the minimum of the value and N, or the minimum element in an array.
|
|
478
|
-
```html
|
|
479
|
-
{{ 5|min:2 }} → 2
|
|
480
|
-
{{ [5, 2, 8]|min }} → 2
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
### `max:N` / `max:array`
|
|
484
|
-
Returns the maximum of the value and N, or the maximum element in an array.
|
|
485
|
-
```html
|
|
486
|
-
{{ 5|max:2 }} → 5
|
|
487
|
-
{{ [5, 2, 8]|max }} → 8
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
### `sum`
|
|
491
|
-
Returns the sum of all elements in an array.
|
|
492
|
-
```html
|
|
493
|
-
{{ [1, 2, 3, 4]|sum }} → 10
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
### `average`
|
|
497
|
-
Returns the arithmetic mean of an array. Returns 0 for empty arrays.
|
|
498
|
-
```html
|
|
499
|
-
{{ [1, 2, 3, 4]|average }} → 2.5
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
---
|
|
503
|
-
|
|
504
|
-
## Miscellaneous Filters
|
|
505
|
-
|
|
506
|
-
### `yesno:"yes,no,maybe"`
|
|
507
|
-
Maps truthy / falsy / null values to custom strings.
|
|
508
|
-
```html
|
|
509
|
-
{{ flag|yesno:"yes,no,maybe" }} → "yes" if true, "no" if false, "maybe" if null
|
|
510
|
-
{{ active|yesno:"Active,Inactive" }} → "Active" or "Inactive"
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
### `pluralize:"s,plural"`
|
|
514
|
-
Returns the singular or plural suffix based on the value. Supports custom suffixes.
|
|
515
|
-
```html
|
|
516
|
-
{{ items|length }} {{ items|pluralize }} item{{ items|pluralize }}
|
|
517
|
-
<!-- 1 item | 5 items -->
|
|
518
|
-
|
|
519
|
-
{{ count|pluralize:"y,ies" }} → "1 candy" | "2 candies"
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
### `filesizeformat`
|
|
523
|
-
Formats a byte count as a human-readable file size.
|
|
524
|
-
```html
|
|
525
|
-
{{ 1024|filesizeformat }} → "1.0 KB"
|
|
526
|
-
{{ 1048576|filesizeformat }} → "1.0 MB"
|
|
527
|
-
{{ 0|filesizeformat }} → "0 bytes"
|
|
528
|
-
{{ 1536|filesizeformat }} → "1.5 KB"
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
---
|
|
532
|
-
|
|
533
|
-
## Data Formatting Filters
|
|
534
|
-
|
|
535
|
-
### `currency:symbol`
|
|
536
|
-
Formats a number as currency with thousands separators and 2 decimal places. Default symbol is `$`.
|
|
537
|
-
```html
|
|
538
|
-
{{ 1234.5|currency }} → "$1,234.50"
|
|
539
|
-
{{ 1234.5|currency:"€" }} → "€1,234.50"
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### `phone_number`
|
|
543
|
-
Formats a 10-digit US phone number as `(123) 456-7890`. Handles 11-digit numbers with leading `1` as `+1 (123) 456-7890`.
|
|
544
|
-
```html
|
|
545
|
-
{{ "1234567890"|phone_number }} → "(123) 456-7890"
|
|
546
|
-
{{ "11234567890"|phone_number }} → "+1 (123) 456-7890"
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
### `email`
|
|
550
|
-
Wraps an email address in a `mailto:` link.
|
|
551
|
-
```html
|
|
552
|
-
{{ "user@example.com"|email }} → "mailto:user@example.com"
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
### `url`
|
|
556
|
-
Ensures a URL has a protocol prefix. Prepends `https://` if missing.
|
|
557
|
-
```html
|
|
558
|
-
{{ "example.com"|url }} → "https://example.com"
|
|
559
|
-
{{ "https://example.com"|url }} → "https://example.com"
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### `mask:char`
|
|
563
|
-
Masks all but the last 4 characters of a string. Default mask character is `*`.
|
|
564
|
-
```html
|
|
565
|
-
{{ "1234567890"|mask }} → "******7890"
|
|
566
|
-
{{ "1234567890"|mask:"#" }} → "######7890"
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
### `whatsapp_link:message`
|
|
570
|
-
Generates a WhatsApp link (`https://wa.me/NUMBER`) with an optional pre-filled message.
|
|
571
|
-
```html
|
|
572
|
-
{{ "1234567890"|whatsapp_link }} → "https://wa.me/1234567890"
|
|
573
|
-
{{ "1234567890"|whatsapp_link:"Hello" }} → "https://wa.me/1234567890?text=Hello"
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
### `credit_card`
|
|
577
|
-
Formats a credit card number with dashes every 4 digits.
|
|
578
|
-
```html
|
|
579
|
-
{{ "4111111111111111"|credit_card }} → "4111-1111-1111-1111"
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
### `ssn`
|
|
583
|
-
Formats a 9-digit Social Security Number as `XXX-XX-XXXX`.
|
|
584
|
-
```html
|
|
585
|
-
{{ "123456789"|ssn }} → "123-45-6789"
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
### `ip_address`
|
|
589
|
-
Formats a 10 or 12 digit string as a dotted IP address.
|
|
590
|
-
```html
|
|
591
|
-
{{ "192168011001"|ip_address }} → "192.168.11.001"
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### `uuid`
|
|
595
|
-
Generates a random UUID v4 string.
|
|
596
|
-
```html
|
|
597
|
-
{{ ""|uuid }} → "9787a126-cb81-4825-b63b-73345a51a1c1"
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
---
|
|
601
|
-
|
|
602
|
-
## Humanize Filters (Built-in Library)
|
|
603
|
-
|
|
604
|
-
These filters are part of the `humanize` library, activated by default or via `{% load humanize %}`.
|
|
605
|
-
|
|
606
|
-
### `intcomma`
|
|
607
|
-
Adds commas to thousands places.
|
|
608
|
-
```html
|
|
609
|
-
{{ 1234567|intcomma }} → "1,234,567"
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
### `intword`
|
|
613
|
-
Converts large numbers to human-friendly strings.
|
|
614
|
-
```html
|
|
615
|
-
{{ 1234567|intword }} → "1.2 million"
|
|
616
|
-
{{ 1000|intword }} → "1.0 thousand"
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
### `apnumber`
|
|
620
|
-
Converts numbers to their word equivalent (0–19).
|
|
621
|
-
```html
|
|
622
|
-
{{ 3|apnumber }} → "three"
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
### `ordinal`
|
|
626
|
-
Returns the ordinal suffix for a number.
|
|
627
|
-
```html
|
|
628
|
-
{{ 1|ordinal }} → "1st"
|
|
629
|
-
{{ 2|ordinal }} → "2nd"
|
|
630
|
-
{{ 11|ordinal }} → "11th"
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
### `naturalday`
|
|
634
|
-
Returns "today", "yesterday", "tomorrow", or the date string for other dates.
|
|
635
|
-
```html
|
|
636
|
-
{{ today|naturalday }} → "today"
|
|
637
|
-
{{ yesterday|naturalday }} → "yesterday"
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
---
|
|
641
|
-
|
|
642
|
-
## i18n Filters
|
|
643
|
-
|
|
644
|
-
### `trans:"fallback"`
|
|
645
|
-
Translate a string using the i18n registry. Falls back to the original value if no translation is found.
|
|
646
|
-
|
|
647
|
-
```html
|
|
648
|
-
{{ "Hello, World!"|trans }}
|
|
649
|
-
{{ greeting|trans:"Hello, %s!" }}
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
---
|
|
653
|
-
|
|
654
|
-
## Regroup Filter
|
|
655
|
-
|
|
656
|
-
### `regroup:"key"`
|
|
657
|
-
Group an array of objects by a common attribute. Returns an array of `{ grouper, list }` objects.
|
|
658
|
-
|
|
659
|
-
```html
|
|
660
|
-
{% for group in items|regroup:"category" %}
|
|
661
|
-
<h3>{{ group.grouper }}</h3>
|
|
662
|
-
{% for item in group.list %}
|
|
663
|
-
<p>{{ item.name }}</p>
|
|
664
|
-
{% endfor %}
|
|
665
|
-
{% endfor %}
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
---
|
|
669
|
-
|
|
670
|
-
## Custom Filters
|
|
671
|
-
|
|
672
|
-
Register custom filters with `registerFilter`:
|
|
673
|
-
|
|
674
|
-
```javascript
|
|
675
|
-
const { registerFilter } = require('miki-template');
|
|
676
|
-
|
|
677
|
-
// Simple filter
|
|
678
|
-
registerFilter('reverse', (val) => String(val).split('').reverse().join(''));
|
|
679
|
-
|
|
680
|
-
// Filter with argument
|
|
681
|
-
registerFilter('truncate', (val, length) => {
|
|
682
|
-
const str = String(val);
|
|
683
|
-
if (str.length <= length) return str;
|
|
684
|
-
return str.slice(0, length) + '...';
|
|
685
|
-
});
|
|
686
|
-
|
|
687
|
-
// Chaining works automatically:
|
|
688
|
-
// {{ name|reverse|truncate:5 }}
|
|
689
|
-
```
|
|
690
|
-
|
|
691
|
-
---
|
|
692
|
-
|
|
693
|
-
## Filter Argument Types
|
|
694
|
-
|
|
695
|
-
Filters accept the following argument types:
|
|
696
|
-
|
|
697
|
-
| Syntax | Type | Example |
|
|
698
|
-
|--------|------|---------|
|
|
699
|
-
| Unquoted | Variable lookup | `{{ value|filter:count }}` |
|
|
700
|
-
| Double-quoted | String literal | `{{ value|filter:"hello" }}` |
|
|
701
|
-
| Single-quoted | String literal | `{{ value|filter:'world' }}` |
|
|
702
|
-
| Number | Integer literal | `{{ value|truncatewords:10 }}` |
|
|
703
|
-
|
|
704
|
-
```html
|
|
705
|
-
{{ user.name|default:"Guest" }} <!-- String default -->
|
|
706
|
-
{{ items|slice:"1:3" }} <!-- Slice notation -->
|
|
707
|
-
{{ price|floatformat:2 }} <!-- Decimal places -->
|
|
708
|
-
```
|