{"id":13895978,"url":"https://github.com/orbitalquark/lupa","last_synced_at":"2025-05-01T18:30:31.197Z","repository":{"id":54861816,"uuid":"295565630","full_name":"orbitalquark/lupa","owner":"orbitalquark","description":"Lupa is a Jinja2 template engine implementation written in Lua and supports Lua syntax within tags and variables.","archived":true,"fork":false,"pushed_at":"2025-01-01T16:45:07.000Z","size":369,"stargazers_count":18,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"default","last_synced_at":"2025-04-10T19:58:52.729Z","etag":null,"topics":["jinja2","lpeg","lua","template-engine"],"latest_commit_sha":null,"homepage":"https://orbitalquark.github.io/lupa","language":"Lua","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/orbitalquark.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}},"created_at":"2020-09-14T23:51:15.000Z","updated_at":"2025-01-31T02:47:45.000Z","dependencies_parsed_at":"2024-11-12T12:13:14.374Z","dependency_job_id":"93f6a11e-733a-41fc-9556-69b1d219c614","html_url":"https://github.com/orbitalquark/lupa","commit_stats":{"total_commits":18,"total_committers":1,"mean_commits":18.0,"dds":0.0,"last_synced_commit":"7c9fcaf1860abbd05e15d0d36b5f424f56be02b5"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orbitalquark%2Flupa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orbitalquark%2Flupa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orbitalquark%2Flupa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orbitalquark%2Flupa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orbitalquark","download_url":"https://codeload.github.com/orbitalquark/lupa/tar.gz/refs/heads/default","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251924564,"owners_count":21665992,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["jinja2","lpeg","lua","template-engine"],"created_at":"2024-08-06T18:02:35.810Z","updated_at":"2025-05-01T18:30:30.584Z","avatar_url":"https://github.com/orbitalquark.png","language":"Lua","funding_links":[],"categories":["Lua"],"sub_categories":[],"readme":"# Lupa\n\nLupa is a [Jinja2][] template engine implementation written in Lua and supports\nLua syntax within tags and variables.\n\nLupa was sponsored by the [Library of the University of Antwerp][].\n\n[Jinja2]: http://jinja.pocoo.org\n[Library of the University of Antwerp]: http://www.uantwerpen.be/\n\n## Requirements\n\nLupa has the following requirements:\n\n* [Lua][] 5.1, 5.2, or 5.3.\n* The [LPeg][] library.\n\n[Lua]: https://www.lua.org\n[LPeg]: http://www.inf.puc-rio.br/~roberto/lpeg/\n\n## Download\n\nLupa releases can be found [here][].\n\n[here]: https://github.com/orbitalquark/lupa/releases\n\n## Installation\n\nUnzip Lupa and place the \"lupa.lua\" file in your Lua installation's\n`package.path`. This location depends on your version of Lua. Typical locations\nare listed below.\n\n* Lua 5.1: */usr/local/share/lua/5.1/* or */usr/local/share/lua/5.1/*\n* Lua 5.2: */usr/local/share/lua/5.2/* or */usr/local/share/lua/5.2/*\n* Lua 5.3: */usr/local/share/lua/5.3/* or */usr/local/share/lua/5.3/*\n\nYou can also place the *lupa.lua* file wherever you'd like and add it to Lua's\n`package.path` manually in your program. For example, if Lupa was placed in a\n*/home/user/lua/* directory, it can be used as follows:\n\n    package.path = package.path .. ';/home/user/lua/?.lua'\n\n## Usage\n\nLupa is simply a Lua library. Its `lupa.expand()` and `lupa.expand_file()`\nfunctions may called to process templates. For example:\n\n    lupa = require('lupa')\n    lupa.expand(\"hello {{ s }}!\", {s = \"world\"}) --\u003e \"hello world!\"\n    lupa.expand(\"{% for i in {1, 2, 3} %}{{ i }}{% endfor %}\") --\u003e 123\n\nBy default, Lupa loads templates relative to the current working directory. This\ncan be changed by reconfiguring Lupa:\n\n    lupa.expand_file('name') --\u003e expands template \"./name\"\n    lupa.configure{loader = lupa.loaders.filesystem('path/to/templates')}\n    lupa.expand_file('name') --\u003e expands template \"path/to/templates/name\"\n\nSee Lupa's [API documentation][] for more information.\n\n[API documentation]: https://orbitalquark.github.io/lupa/api.html\n\n## Syntax\n\nPlease refer to Jinja2's extensive [template documentation][]. Any\nincompatibilities are listed in the sections below.\n\n[template documentation]: http://jinja.pocoo.org/docs/dev/templates/\n\n## Comparison with Jinja2\n\nWhile Lua and Python (Jinja2's implementation language) share some similarities,\nthe languages themselves are fundamentally different. Nevertheless, a\nsignificant effort was made to support a vast majority of Jinja2's Python-style\nsyntax. As a result, Lupa passes Jinja2's test suite with only a handful of\nmodifications. The comprehensive list of differences between Lupa and Jinja2 is\ndescribed in the following sections.\n\n### Fundamental Differences\n\n* Expressions use Lua's syntax instead of Python's, so many of Python's\n  syntactic constructs are not valid. However, the following constructs\n  *are valid*, despite being invalid in pure Lua:\n\n  + Iterating over table literals or table variables directly in a \"for\" loop:\n\n        {% for i in {1, 2, 3} %}...{% endfor %}\n\n  + Conditional loops via an \"if\" expression suffix:\n\n        {% for x in range(10) if is_odd(x) %}...{% endfor %}\n\n  + Table unpacking for list elements when iterating through a list of lists:\n\n        {% for a, b, c in {{1, 2, 3}, {4, 5, 6}} %}...{% endfor %}\n\n  + Default values for macro arguments:\n\n        {% macro m(a, b, c='c', d='d') %}...{% endmacro %}\n\n* Strings do not have unicode escapes nor is unicode interpreted in any way.\n\n### Syntactic Differences\n\n* Line statements are not supported due to parsing complexity.\n* In `{% for ... %}` loops, the `loop.length`, `loop.revindex`,\n  `loop.revindex0`, and `loop.last` variables only apply to sequences, where\n  Lua's `'#'` operator applies.\n* The `{% continue %}` and `{% break %}` loop controls are not supported due to\n  complexity.\n* Loops may be used recursively by default, so the `recursive` loop modifier is\n  not supported.\n* The `is` operator is not supported by Lua, so tests of the form `{{ x is y }}`\n  should be written `{{ is_y(x) }}` (e.g. `{{ is_number(42) }}`).\n* Filters cannot occur after tokens within an expression (e.g.\n  `{{ \"foo\"|upper .. \"bar\"|upper }}`), but can only occur at the end of an\n  expression (e.g. `{{ \"foo\"..\"bar\"|upper }}`).\n* Blocks always have access to scoped variables, so the `scoped` block modifier\n  is not supported.\n* Named block end tags are not supported since the parser cannot easily keep\n  track of that state information.\n* Any `{% block ... %}` tags within a \"false\" block (e.g. `{% if a %}` where `a`\n  evaluates to `false`) are never read and stored due to the parser\n  implementation.\n* Inline \"if\" expressions (e.g. `{% extends b if a else c %}`) are not\n  supported. Instead, use a Lua conditional expression\n  (e.g. `{% extends a and b or c %}`).\n* Any `{% extends ... %}` tags within a sub-scope are not effective outside that\n  scope (e.g. `{% if a %}{% extends a %}{% else %}{% extends b %}{% endif %}`).\n  Instead, use a Lua conditional expression (e.g. `{% extends a or b %}`).\n* Macros are simply Lua functions and have no metadata attributes.\n* Macros do not have access to a `kwargs` variable since Lua does not support\n  keyword arguments.\n* `{% from x import y %}` tags are not supported. Instead, you must use either\n  `{% import x %}`, which imports all globals in `x` into the current\n  environment, or use `{% import x as z %}`, which imports all globals in `x`\n  into the variable `z`.\n* `{% set ... %}` does not support multiple assignment. Use `{% do ...%}`\n  instead. The catch is that `{% do ... %}` does not support filters.\n* The `{% trans %}` and `{% endtrans %}` tags, `{% with %}` and `{% endwith %}`\n  tags, and `{% autoescape %}` and `{% endautoescape %}` tags are not supported\n  since they are outside the scope of this implementation.\n\n### Filter Differences\n\n* Only the `batch`, `groupby`, and `slice` filters return generators which\n  produce one item at a time when looping. All other filters that produce\n  iterable results generate all items at once.\n* The `float` filter only works in Lua 5.3 since that version of Lua has a\n  distinction between floats and integers.\n* The `safe` filter must appear at the end of a filter chain since its output\n  cannot be passed to any other filter.\n\n### Function Differences\n\n* The global `range(n)` function returns a sequence from 1 to `n`, inclusive,\n  since lists start at 1 in Lua.\n* No `lipsum()`, `dict()`, or `joiner()` functions for the sake of simplicity.\n\n### API Differences\n\n* Lupa has a much simpler API consisting of just four functions and three\n  fields:\n\n  + `lupa.expand()`: Expands a string template subject to an environment.\n  + `lupa.expand_file()`: Expands a file template subject to an environment.\n  + `lupa.configure()` Configures delimiters and template options.\n  + `lupa.reset()`: Resets delimiters and options to their defaults.\n  + `lupa.env`: The default environment for templates.\n  + `lupa.filters`: The set of available filters (`escape`, `join`, etc.).\n  + `lupa.tests`: The set of available tests (`is_odd`, `is_defined`, etc.).\n\n* There is no bytecode caching.\n* Lupa has no extension mechanism. Instead, modify `lupa.env`, `lupa.filters`,\n  and `lupa.tests` directly. However, the parser cannot be extended.\n* Sandboxing is not supported, although `lupa.env` is safe by default (`io`,\n  `os.execute`, `os.remove`, etc. are not available).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forbitalquark%2Flupa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forbitalquark%2Flupa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forbitalquark%2Flupa/lists"}