Jinjagen 🌀
A CLI tool for generating files using Jinja2 templates with smart delimiters and dynamic data.
Features ✨
- Auto-detects delimiters for code/file types (e.g.,
#for Python/Shell,/*%for C/JS). - Supports JSON/YAML data inputs for dynamic templates.
- Lightweight CLI with stdin/stdout support.
☕ Support
If you find this project helpful, consider supporting me:
Usage 🛠️
Basic Example
Generate a file from a template and JSON data:
python -m jinjagen template.txt.j2 output.txt -d data.json
Real-World Use Case: Bash Script Generation
1. Template (backup.sh.j2):
#!/bin/bash
#jinjagen: -D#
BACKUP_PATHS=(#% for path in backup_paths %# "#{ path }#" #% endfor %#)
#% if notify.enabled %#
EMAIL="#{ notify.email }#"
#% endif %#
2. Data (config.json):
{
"backup_paths": ["/home/user/docs", "/etc/nginx"],
"notify": { "enabled": true, "email": "admin@example.com" }
}
3. Generate Script:
python -m jinjagen backup.sh.j2 backup.sh -d config.json
Output (backup.sh):
#!/bin/bash
BACKUP_PATHS=( "/home/user/docs" "/etc/nginx" )
EMAIL="admin@example.com"
Advanced Options ⚙️
| Flag | Description | Example |
|---|---|---|
-d/--data FILE |
Load variables from JSON/YAML. | -d config.yml |
-D/--delimiters |
Force delimiters (#, /, or .). |
-D# (for Bash/Python) |
-t/--templates |
Specify template directory. | -t ./templates |
INPUT - OUTPUT |
Use - for stdin/stdout. |
template.j2 - -d data.json |
Delimiters Explained 🔠
Jinjagen automatically adapts Jinja2 delimiters to avoid conflicts with different file types. You can also override this behavior manually.
Default Behavior (Auto-Detection)
The tool guesses delimiters based on file extensions:
| File Type | Example Extensions | Delimiters |
|---|---|---|
| C/JS/Java | .c, .js, .java |
/*% %*/ (blocks)/*{ }*/ (variables) |
| Python/Shell | .py, .sh, .yaml |
#% %# (blocks)#{ }# (variables) |
| Generic/Other | .txt, .html |
{% %} (blocks){{ }} (variables) |
Example: For a .c file, Jinjagen uses /_% if x %_/instead of{% if x %}.
Manual Override
Force specific delimiters with -D/--delimiters:
# Use #-style (for Python/Shell)
python -m jinjagen template.txt output.txt -D#
# Use /-style (for C/JS)
python -m jinjagen template.c output.c -D/
# Use default Jinja2 delimiters (.)
python -m jinjagen template.html output.html -D.
Custom Delimiter Logic
The delimiter system handles these cases:
- Conflict Prevention:
Avoids syntax clashes (e.g.,{{ }}in Vue.js or{% %}in Django). - Comment Safety:
Respects language comment styles (e.g.,#in Bash won’t break#%blocks). - Edge Cases:
If no extension matches (or for.txt), falls back to standard Jinja2 delimiters.
Practical Usage 🛠️
Jinjagen shines in generating configs, scripts, and code files. Here are common scenarios:
1. Generate Config Files
Scenario: Create an nginx.conf with dynamic ports and SSL settings.
Template (nginx.conf.j2):
#jinjagen: -D#
server {
listen #{ port }#;
server_name #{ domain }#;
#% if ssl_enabled %#
ssl_certificate #{ ssl_cert }#;
ssl_certificate_key #{ ssl_key }#;
#% endif %#
}
Data (deploy.yml):
port: 443
domain: "example.com"
ssl_enabled: true
ssl_cert: "/etc/ssl/certs/example.crt"
ssl_key: "/etc/ssl/private/example.key"
Command:
python -m jinjagen nginx.conf.j2 nginx.conf -d deploy.yml
2. Dynamic Script Generation
Scenario: Create a backup script with conditional email alerts.
Template (backup.sh.j2):
#!/bin/bash
#jinjagen: -D#
BACKUP_DIRS=(#% for dir in backup_dirs %# "#{ dir }#" #% endfor %#)
#% if notify %#
echo "Backup done" | mail -s "Backup Log" #{ email }#
#% endif %#
Data (config.json):
{
"backup_dirs": ["/home", "/etc"],
"notify": true,
"email": "admin@example.com"
}
Command:
python -m jinjagen backup.sh.j2 backup.sh -d config.json -D#
3. CI/CD Pipeline Integration
Scenario: Generate environment-specific .env files during deployment.
Template (.env.j2):
#jinjagen: -D.
DB_HOST=#{ db_host }#
DB_USER=#{ db_user }#
#% if env == "prod" %#
DB_PASSWORD=#{ "vault.get('db_prod_pass')" }#
#% else %#
DB_PASSWORD=devpass
#% endif %#
Command (using environment variables):
python -m jinjagen .env.j2 .env -D# -d <(echo '{"env":"prod","db_host":"10.0.0.1","db_user":"admin"}')
4. Code Generation
Scenario: Generate a Python class from a template.
Template (model.py.j2):
#jinjagen: -D#
class #{ class_name }#:
def __init__(self):
#% for field in fields %#
self.#{ field }# = None
#% endfor %#
Data (model.json):
{
"class_name": "UserModel",
"fields": ["id", "name", "email"]
}
Command:
python -m jinjagen model.py.j2 UserModel.py -d model.json
Pro Tips 💡
- Use
-for stdin/stdout: Pipe templates/data between tools.echo "Hello #{ name }#" | python -m jinjagen -D# - -d <(echo '{"name":"World"}')
- Override delimiters when auto-detection fails:
python -m jinjagen template.sql output.sql -D/ # Force /*% style for SQL
- Template directories: Use
-t ./templatesto enable{% include %}.
Release files for jinjagen 0.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jinjagen-0.0.4.tar.gz | 9.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jinjagen-0.0.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.3 kB
Release files / jinjagen-0.0.4.tar.gz
| Download URL | jinjagen-0.0.4.tar.gz |
|---|---|
| Size | 9.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0932d2b58a1c27361c23ef99bf27f07067bea5a8ae58d4886d0a0dd672c8cb3e
|
|
BLAKE2b-256 checksum How to use checksums |
6c0a6aae5a61cc05942187a69a8c2cfb35fc25e4f44c653407013874ce5b0ca3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.17
|
Release files / jinjagen-0.0.4-py3-none-any.whl
| Download URL | jinjagen-0.0.4-py3-none-any.whl |
|---|---|
| Size | 7.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6ac2b6f7082663a606ed50c3428613faf42a05aa9f196b8f69df59821259d612
|
|
BLAKE2b-256 checksum How to use checksums |
f73c212305ad305e73bc75b9793771b745d8bd431f3fcb7b70b285d4fc057f81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.17
|