{"id":28600918,"url":"https://github.com/alexandergrooff/jinja-go","last_synced_at":"2026-04-24T21:31:45.296Z","repository":{"id":295867489,"uuid":"983756228","full_name":"AlexanderGrooff/jinja-go","owner":"AlexanderGrooff","description":"Jinja library that acts just like the Python Jinja library but written in Golang","archived":false,"fork":false,"pushed_at":"2025-08-27T09:23:12.000Z","size":14218,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-27T17:34:25.729Z","etag":null,"topics":["ansible","go","jinja"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlexanderGrooff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-14T21:42:40.000Z","updated_at":"2025-08-27T09:23:10.000Z","dependencies_parsed_at":"2025-05-27T19:44:43.493Z","dependency_job_id":"f7e9a9f5-e86f-4bd3-9d9d-caf72fab1a7b","html_url":"https://github.com/AlexanderGrooff/jinja-go","commit_stats":null,"previous_names":["alexandergrooff/jinja-go"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/AlexanderGrooff/jinja-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2Fjinja-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2Fjinja-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2Fjinja-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2Fjinja-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexanderGrooff","download_url":"https://codeload.github.com/AlexanderGrooff/jinja-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2Fjinja-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32241589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","go","jinja"],"created_at":"2025-06-11T14:39:19.539Z","updated_at":"2026-04-24T21:31:45.281Z","avatar_url":"https://github.com/AlexanderGrooff.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jinja Go\n\nA Go library that mimics Jinja's templating behavior.\n\n## Project Goals\n\nThis project aims to provide a reusable library with two main functions:\n\n-   `TemplateString(template string, context map[string]interface{}) (string, error)`: Evaluates a Jinja-like template string. Variables in the format `{{ variable_name }}` are replaced with values from the context map.\n-   `EvaluateExpression(expression string, context map[string]interface{}) (interface{}, error)`: Evaluates a Jinja-like expression string using the provided context. An error is returned if the expression cannot be evaluated.\n\nAdditionally, the library will support:\n\n-   Built-in functions and filters comparable to those in Jinja (e.g., `lookup`, `urlencode`, `map`, `default`).\n-   Basic flow control structures (e.g., `{% for item in items %}`, `{% if condition %}`).\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/AlexanderGrooff/jinja-go\"\n)\n\nfunc main() {\n\tcontext := map[string]interface{}{\n\t\t\"name\": \"World\",\n\t\t\"isAdmin\": true,\n\t}\n\n\t// TemplateString example\n\ttemplated, err := jinja.TemplateString(\"Hello {{ name }}!\", context)\n\tif err != nil {\n\t\tfmt.Printf(\"TemplateString Error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(templated) // Output: Hello World!\n\n\t// EvaluateExpression example\n\tisAdmin, err := jinja.EvaluateExpression(\"isAdmin\", context)\n\tif err != nil {\n\t\tfmt.Printf(\"EvaluateExpression Error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"Is Admin: %v\\n\", isAdmin) // Output: Is Admin: true\n} \n```\n\n## Benchmarking\n\nPerformance is critical for this library. We use benchmarking to ensure that changes don't negatively impact performance.\n\n### Running Benchmarks\n\n```bash\n# Run benchmarks without saving results\nmake benchmark\n\n# Run benchmarks and save as latest\nmake benchmark-save\n\n# Compare latest benchmarks with previous\nmake benchmark-compare\n\n# Save latest as the new previous (baseline)\nmake benchmark-save-as-previous\n\n# Compare with another branch\nmake benchmark-branch branch=main\n\n# Generate and save a benchmark report\nmake benchmark-report\n\n# Run cross-language benchmarks against Python's Jinja2\nmake cross-benchmark\n```\n\nThe repository uses [benchstat](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat) to compare benchmark results, and pre-commit hooks automatically run benchmarks and compare with previous results.\n\n## Profiling\n\nIn addition to benchmarking, the library includes profiling tools to identify performance bottlenecks and optimize critical sections of code.\n\n### Quick Start\n\n```bash\n# Profile the complex_template with CPU, memory, and block profiling\nmake profile-complex\n\n# Profile nested_loops template (one of the most performance-critical patterns)\nmake profile-nested-loops\n\n# Profile all templates from the benchmark suite\nmake profile-all\n\n# Run custom profiling\nmake profile ARGS=\"--template conditional --cpu --iterations 5000\"\n```\n\n### Analyzing Profiles\n\nAfter running a profile, analyze the results:\n\n```bash\n# Web-based visualization (most comprehensive)\ngo tool pprof -http=:8080 profile_results/complex_template/cpu.prof\n\n# Text-based analysis\ngo tool pprof profile_results/template_name/cpu.prof\n(pprof) top10                # Show top 10 functions by CPU usage\n(pprof) list TemplateString  # Show time spent in function\n```\n\nFor more detailed information on profiling and performance optimization guidelines, see [performance.md](performance.md).\n\n### Cross-Language Benchmarks\n\nYou can directly compare this Go implementation against Python's Jinja2 and other Go-based Jinja-like libraries (such as Pongo2) using the cross-language benchmarking tools:\n\n```bash\n# Run with default settings\nmake cross-benchmark\n\n# Run with custom iterations and output directory\n./cmd/benchmark/run_benchmarks.sh --iterations 5000 --output-dir custom_benchmarks\n\n# Run with custom template test cases\n./cmd/benchmark/run_benchmarks.sh --templates path/to/custom_templates.json\n```\n\nThe cross-benchmark tool:\n\n1. Runs identical templates through both the Python and Go implementations (including other Go libraries like Pongo2)\n2. Measures rendering time for each template\n3. Calculates the speed difference between implementations\n4. Generates a detailed comparison report\n\nCustom template test cases can be defined in a JSON file following this format:\n\n```json\n[\n  {\n    \"name\": \"template_name\",\n    \"template\": \"Hello, {{ name }}!\",\n    \"context\": {\"name\": \"World\"}\n  },\n  // More test cases...\n]\n```\n\nThe comparison provides insight into performance characteristics of both implementations, which is useful for:\n- Identifying areas where the Go implementation can be optimized\n- Quantifying performance gains for various template features\n- Tracking performance improvements over time\n\nYou can view the [latest comparison report](benchstat/cross/comparison_report.txt) to see the current performance differences between all implementations.\n\n## Implementation Status\n\n### Already Implemented Features\n\n- **Template Syntax**\n  - Basic variable substitution (`{{ variable }}`)\n  - Comments (`{# comment #}`)\n  - Conditional statements (`{% if %}`, `{% elif %}`, `{% else %}`, `{% endif %}`)\n  - Loop structures (`{% for item in items %}`, `{% endfor %}`) with loop variable support\n\n- **Expression Evaluation**\n  - Basic literals (integers, floats, strings, booleans, null/None)\n  - Variable access and context lookup\n  - Pythonic data types:\n    - Lists (`[1, 2, 3]`)\n    - Dictionaries (`{'key': 'value'}`)\n    - Dictionary methods like `.get()` (`dict.get('key', 'default')`)\n    - String methods like `.format()` (`\"Hello, {}!\".format(\"world\")`)\n  - Object/attribute access (`object.attribute`)\n  - Subscript access (`array[index]`, `dict['key']`, negative indices)\n  - LALR (Look-Ahead LR) parser for robust expression evaluation\n    - Improved parsing performance and reliability\n    - Proper operator precedence handling\n    - Support for complex expressions such as `a * (b + c) / d`\n  - Complex nested expression handling with multiple subscript operations\n  - Basic filters (e.g., `{{ var | default('fallback') }}`)\n\n- **Operators**\n  - Arithmetic operators (`+`, `-`, `*`, `/`, `//` (floor division), `%` (modulo), `**` (power))\n  - Unary operators (`not`, `-`, `+`)\n  - Comparison operators (`==`, `!=`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`)\n  - Logical operators (`and`, `or`) with short-circuit evaluation\n  - Identity operators (`is`, `is not`)\n  - Membership operators (`in`)\n  - String operations (concatenation, repetition)\n\n- **Filters**\n  - `default` filter\n  - `join` filter\n  - `upper` filter\n  - `lower` filter\n  - `capitalize` filter\n  - `replace` filter\n  - `trim` filter\n  - `list` filter\n  - `escape` filter\n  - `map` filter\n  - `items` filter\n  - `lookup` filter with `file` and `env` sources\n\n### Planned Features\n\n- **Template Syntax**\n  - Include support (`{% include 'page.html' %}`)\n  - Macro definitions (`{% macro %}`/`{% endmacro %}`)\n  - Block and extends for template inheritance (`{% block %}`, `{% extends %}`)\n  - Set statements (`{% set %}`)\n  - With blocks (`{% with %}`)\n  - Loop controls (`{% break %}`, `{% continue %}`)\n  - Whitespace control (using `-` in tags like `{%-` and `-%}`)\n  - Expression statements (`{% do expression %}`)\n  - Debug statements (`{% debug %}`)\n\n- **Expression Evaluation**\n  - More filters (e.g., `{{ url | urlencode }}`)\n  - Tests (`{{ user is defined }}`, `{{ user is not none }}`)\n  - String formatting and f-strings\n  - List comprehensions\n  - Generator expressions (iterables)\n  - Auto-escaping support\n\n- **Control Structures**\n  - More complex control structures\n\n- **Filters and Functions**\n  - Additional common Jinja filters (`urlencode`, etc.)\n  - Additional lookup plugin types for the `lookup` filter\n  - More built-in functions\n  - Complete set of built-in tests (`defined`, `none`, `iterable`, etc.)\n  - Translation/internationalization support (gettext)\n\n- **Advanced Features**\n  - Macro definitions\n  - Include/import functionality\n  - Block/extends for template inheritance\n  - Context scoping and namespaces\n  - Custom tests and filters\n  - Auto-escaping configuration\n\n### Broader improvements to be made\n\n1. Error handling improvements - standardize error reporting across modules\n1. Handling of edge cases in string literals and escaping\n1. Better documentation of supported features\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n### Pre-commit Hooks\n\nThe pre-commit hooks will:\n1. Run benchmarks before each commit\n2. Compare with previous benchmark results \n3. Show performance changes\n\nInstall pre-commit hooks with:\n\n```bash\npre-commit install\n``` ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandergrooff%2Fjinja-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandergrooff%2Fjinja-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandergrooff%2Fjinja-go/lists"}