binja 0.5.1 → 0.5.3
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/README.md +127 -95
- package/dist/cli.js +179 -65
- package/dist/errors/index.d.ts +65 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/filters/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +375 -120
- package/dist/lexer/index.d.ts.map +1 -1
- package/dist/parser/index.d.ts +2 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -240,109 +240,141 @@ app.get('/user/:id', ({ params }) => templates.user({ id: params.id }))
|
|
|
240
240
|
|
|
241
241
|
---
|
|
242
242
|
|
|
243
|
-
## Filters
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
|
250
|
-
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
| `striptags` | `{{ "<p>
|
|
258
|
-
| `
|
|
259
|
-
| `
|
|
260
|
-
| `
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
263
|
-
| `
|
|
264
|
-
| `
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
|
269
|
-
|
|
270
|
-
| `
|
|
271
|
-
| `
|
|
272
|
-
| `
|
|
273
|
-
| `
|
|
274
|
-
| `
|
|
275
|
-
| `
|
|
276
|
-
| `
|
|
277
|
-
|
|
278
|
-
###
|
|
279
|
-
|
|
280
|
-
| Filter |
|
|
281
|
-
|
|
282
|
-
| `
|
|
283
|
-
| `
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
289
|
-
| `
|
|
290
|
-
| `
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
| `
|
|
298
|
-
| `
|
|
299
|
-
| `
|
|
300
|
-
| `
|
|
243
|
+
## Filters (84 Built-in)
|
|
244
|
+
|
|
245
|
+
binja includes **84 built-in filters** covering both Jinja2 and Django Template Language.
|
|
246
|
+
|
|
247
|
+
### String Filters (26)
|
|
248
|
+
|
|
249
|
+
| Filter | Description | Example |
|
|
250
|
+
|--------|-------------|---------|
|
|
251
|
+
| `upper` | Uppercase | `{{ "hello"\|upper }}` → `HELLO` |
|
|
252
|
+
| `lower` | Lowercase | `{{ "HELLO"\|lower }}` → `hello` |
|
|
253
|
+
| `capitalize` | First letter uppercase | `{{ "hello"\|capitalize }}` → `Hello` |
|
|
254
|
+
| `capfirst` | First char uppercase | `{{ "hello"\|capfirst }}` → `Hello` |
|
|
255
|
+
| `title` | Title case | `{{ "hello world"\|title }}` → `Hello World` |
|
|
256
|
+
| `trim` | Strip whitespace | `{{ " hi "\|trim }}` → `hi` |
|
|
257
|
+
| `striptags` | Remove HTML tags | `{{ "<p>Hi</p>"\|striptags }}` → `Hi` |
|
|
258
|
+
| `slugify` | URL-friendly slug | `{{ "Hello World!"\|slugify }}` → `hello-world` |
|
|
259
|
+
| `truncatechars` | Truncate to N chars | `{{ "hello"\|truncatechars:3 }}` → `hel...` |
|
|
260
|
+
| `truncatewords` | Truncate to N words | `{{ "a b c d"\|truncatewords:2 }}` → `a b...` |
|
|
261
|
+
| `truncatechars_html` | Truncate preserving HTML | `{{ "<b>hi</b> world"\|truncatechars_html:5 }}` |
|
|
262
|
+
| `truncatewords_html` | Truncate words in HTML | `{{ "<p>a b c</p>"\|truncatewords_html:2 }}` |
|
|
263
|
+
| `wordcount` | Count words | `{{ "hello world"\|wordcount }}` → `2` |
|
|
264
|
+
| `wordwrap` | Wrap at N chars | `{{ text\|wordwrap:40 }}` |
|
|
265
|
+
| `center` | Center in N chars | `{{ "hi"\|center:10 }}` → ` hi ` |
|
|
266
|
+
| `ljust` | Left justify | `{{ "hi"\|ljust:10 }}` → `hi ` |
|
|
267
|
+
| `rjust` | Right justify | `{{ "hi"\|rjust:10 }}` → ` hi` |
|
|
268
|
+
| `cut` | Remove substring | `{{ "hello"\|cut:"l" }}` → `heo` |
|
|
269
|
+
| `replace` | Replace substring | `{{ "hello"\|replace:"l","x" }}` → `hexxo` |
|
|
270
|
+
| `indent` | Indent lines | `{{ text\|indent:4 }}` |
|
|
271
|
+
| `linebreaks` | Newlines to `<p>/<br>` | `{{ text\|linebreaks }}` |
|
|
272
|
+
| `linebreaksbr` | Newlines to `<br>` | `{{ text\|linebreaksbr }}` |
|
|
273
|
+
| `linenumbers` | Add line numbers | `{{ code\|linenumbers }}` |
|
|
274
|
+
| `addslashes` | Escape quotes | `{{ "it's"\|addslashes }}` → `it\'s` |
|
|
275
|
+
| `format` | sprintf-style format | `{{ "Hi %s"\|format:name }}` |
|
|
276
|
+
| `stringformat` | Python % format | `{{ 5\|stringformat:"03d" }}` → `005` |
|
|
277
|
+
|
|
278
|
+
### Number Filters (9)
|
|
279
|
+
|
|
280
|
+
| Filter | Description | Example |
|
|
281
|
+
|--------|-------------|---------|
|
|
282
|
+
| `abs` | Absolute value | `{{ -5\|abs }}` → `5` |
|
|
283
|
+
| `int` | Convert to integer | `{{ "42"\|int }}` → `42` |
|
|
284
|
+
| `float` | Convert to float | `{{ "3.14"\|float }}` → `3.14` |
|
|
285
|
+
| `round` | Round number | `{{ 3.7\|round }}` → `4` |
|
|
286
|
+
| `add` | Add number | `{{ 5\|add:3 }}` → `8` |
|
|
287
|
+
| `divisibleby` | Check divisibility | `{{ 10\|divisibleby:2 }}` → `true` |
|
|
288
|
+
| `floatformat` | Format decimal places | `{{ 3.14159\|floatformat:2 }}` → `3.14` |
|
|
289
|
+
| `filesizeformat` | Human file size | `{{ 1048576\|filesizeformat }}` → `1.0 MB` |
|
|
290
|
+
| `get_digit` | Get Nth digit | `{{ 12345\|get_digit:2 }}` → `4` |
|
|
291
|
+
|
|
292
|
+
### List/Array Filters (22)
|
|
293
|
+
|
|
294
|
+
| Filter | Description | Example |
|
|
295
|
+
|--------|-------------|---------|
|
|
296
|
+
| `length` | List length | `{{ items\|length }}` → `3` |
|
|
297
|
+
| `length_is` | Check length | `{{ items\|length_is:3 }}` → `true` |
|
|
298
|
+
| `first` | First item | `{{ items\|first }}` |
|
|
299
|
+
| `last` | Last item | `{{ items\|last }}` |
|
|
300
|
+
| `join` | Join with separator | `{{ items\|join:", " }}` → `a, b, c` |
|
|
301
|
+
| `slice` | Slice list | `{{ items\|slice:":2" }}` |
|
|
302
|
+
| `reverse` | Reverse list | `{{ items\|reverse }}` |
|
|
303
|
+
| `sort` | Sort list | `{{ items\|sort }}` |
|
|
304
|
+
| `unique` | Remove duplicates | `{{ items\|unique }}` |
|
|
305
|
+
| `batch` | Group into batches | `{{ items\|batch:2 }}` |
|
|
306
|
+
| `columns` | Split into columns | `{{ items\|columns:3 }}` |
|
|
307
|
+
| `dictsort` | Sort dict by key | `{{ dict\|dictsort }}` |
|
|
308
|
+
| `dictsortreversed` | Sort dict reversed | `{{ dict\|dictsortreversed }}` |
|
|
309
|
+
| `groupby` | Group by attribute | `{{ items\|groupby:"category" }}` |
|
|
310
|
+
| `random` | Random item | `{{ items\|random }}` |
|
|
311
|
+
| `list` | Convert to list | `{{ value\|list }}` |
|
|
312
|
+
| `make_list` | String to char list | `{{ "abc"\|make_list }}` → `['a','b','c']` |
|
|
313
|
+
| `map` | Map attribute | `{{ items\|map:"name" }}` |
|
|
314
|
+
| `select` | Filter by test | `{{ items\|select:"even" }}` |
|
|
315
|
+
| `reject` | Reject by test | `{{ items\|reject:"none" }}` |
|
|
316
|
+
| `selectattr` | Filter by attr test | `{{ items\|selectattr:"active" }}` |
|
|
317
|
+
| `rejectattr` | Reject by attr test | `{{ items\|rejectattr:"hidden" }}` |
|
|
318
|
+
|
|
319
|
+
### Math Filters (4)
|
|
320
|
+
|
|
321
|
+
| Filter | Description | Example |
|
|
322
|
+
|--------|-------------|---------|
|
|
323
|
+
| `max` | Maximum value | `{{ items\|max }}` |
|
|
324
|
+
| `min` | Minimum value | `{{ items\|min }}` |
|
|
325
|
+
| `sum` | Sum of values | `{{ items\|sum }}` |
|
|
326
|
+
| `attr` | Get attribute | `{{ item\|attr:"name" }}` |
|
|
327
|
+
|
|
328
|
+
### Date/Time Filters (4)
|
|
329
|
+
|
|
330
|
+
| Filter | Description | Example |
|
|
331
|
+
|--------|-------------|---------|
|
|
332
|
+
| `date` | Format date | `{{ now\|date:"Y-m-d" }}` → `2024-01-15` |
|
|
333
|
+
| `time` | Format time | `{{ now\|time:"H:i" }}` → `14:30` |
|
|
334
|
+
| `timesince` | Time since date | `{{ past\|timesince }}` → `2 days ago` |
|
|
335
|
+
| `timeuntil` | Time until date | `{{ future\|timeuntil }}` → `in 3 hours` |
|
|
301
336
|
|
|
302
337
|
#### Timezone Support
|
|
303
338
|
|
|
304
|
-
All date/time operations respect the `timezone` option in Environment:
|
|
305
|
-
|
|
306
339
|
```typescript
|
|
307
340
|
const env = new Environment({
|
|
308
|
-
timezone: 'Europe/Rome' // All dates
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
// 2024-06-15 12:00 UTC = 2024-06-15 14:00 Rome (UTC+2)
|
|
312
|
-
await env.renderString('{{ date|date:"Y-m-d H:i" }}', {
|
|
313
|
-
date: new Date('2024-06-15T12:00:00Z')
|
|
341
|
+
timezone: 'Europe/Rome' // All dates in Rome timezone
|
|
314
342
|
})
|
|
315
|
-
// Output: 2024-06-15 14:00
|
|
316
|
-
|
|
317
|
-
// {% now %} tag also uses the configured timezone
|
|
318
|
-
await env.renderString('{% now "Y-m-d H:i" %}')
|
|
319
|
-
// Output: current date/time in Rome timezone
|
|
320
343
|
```
|
|
321
344
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
|
327
|
-
|
|
328
|
-
| `
|
|
329
|
-
| `
|
|
330
|
-
| `
|
|
331
|
-
| `
|
|
332
|
-
| `
|
|
333
|
-
| `
|
|
334
|
-
| `
|
|
335
|
-
| `
|
|
336
|
-
| `
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
|
343
|
-
|
|
344
|
-
| `
|
|
345
|
-
| `
|
|
345
|
+
### Safety & Encoding Filters (13)
|
|
346
|
+
|
|
347
|
+
| Filter | Description | Example |
|
|
348
|
+
|--------|-------------|---------|
|
|
349
|
+
| `escape` / `e` | HTML escape | `{{ html\|escape }}` |
|
|
350
|
+
| `forceescape` | Force HTML escape | `{{ html\|forceescape }}` |
|
|
351
|
+
| `safe` | Mark as safe | `{{ html\|safe }}` |
|
|
352
|
+
| `safeseq` | Mark sequence safe | `{{ items\|safeseq }}` |
|
|
353
|
+
| `escapejs` | JS string escape | `{{ text\|escapejs }}` |
|
|
354
|
+
| `urlencode` | URL encode | `{{ url\|urlencode }}` |
|
|
355
|
+
| `iriencode` | IRI encode | `{{ url\|iriencode }}` |
|
|
356
|
+
| `urlize` | URLs to links | `{{ text\|urlize }}` |
|
|
357
|
+
| `urlizetrunc` | URLs to links (truncated) | `{{ text\|urlizetrunc:15 }}` |
|
|
358
|
+
| `json` / `tojson` | JSON stringify | `{{ data\|json }}` |
|
|
359
|
+
| `json_script` | Safe JSON in script | `{{ data\|json_script:"id" }}` |
|
|
360
|
+
| `pprint` | Pretty print | `{{ data\|pprint }}` |
|
|
361
|
+
| `xmlattr` | Dict to XML attrs | `{{ attrs\|xmlattr }}` |
|
|
362
|
+
|
|
363
|
+
### Default/Conditional Filters (4)
|
|
364
|
+
|
|
365
|
+
| Filter | Description | Example |
|
|
366
|
+
|--------|-------------|---------|
|
|
367
|
+
| `default` / `d` | Default value | `{{ missing\|default:"N/A" }}` |
|
|
368
|
+
| `default_if_none` | Default if null | `{{ val\|default_if_none:"None" }}` |
|
|
369
|
+
| `yesno` | Boolean to text | `{{ true\|yesno:"Yes,No" }}` → `Yes` |
|
|
370
|
+
| `pluralize` | Pluralize suffix | `{{ count\|pluralize }}` → `s` |
|
|
371
|
+
|
|
372
|
+
### Misc Filters (2)
|
|
373
|
+
|
|
374
|
+
| Filter | Description | Example |
|
|
375
|
+
|--------|-------------|---------|
|
|
376
|
+
| `items` | Dict to pairs | `{% for k,v in dict\|items %}` |
|
|
377
|
+
| `unordered_list` | Nested list to HTML | `{{ items\|unordered_list }}` |
|
|
346
378
|
|
|
347
379
|
---
|
|
348
380
|
|