{"id":13741554,"url":"https://github.com/olian04/gleam_handles","last_synced_at":"2025-04-12T06:21:56.108Z","repository":{"id":243388557,"uuid":"812265049","full_name":"Olian04/gleam_handles","owner":"Olian04","description":"Handles is a templating language written in pure Gleam. Heavily inspired by Mustache and Handlebars.js","archived":false,"fork":false,"pushed_at":"2024-07-30T13:16:01.000Z","size":96,"stargazers_count":20,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-11T11:21:50.487Z","etag":null,"topics":["bun","deno","erlang","gleam","gleam-lang","gleam-language","handlebars","mustache","nodejs","template","template-engine","templating","templating-engine"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/handles","language":"Gleam","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/Olian04.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":"2024-06-08T12:00:40.000Z","updated_at":"2024-11-10T12:41:16.000Z","dependencies_parsed_at":"2024-06-13T03:17:59.048Z","dependency_job_id":"655fa38a-945b-407e-ae1b-f9286dd223bd","html_url":"https://github.com/Olian04/gleam_handles","commit_stats":null,"previous_names":["olian04/gleam_handlebars","olian04/gleam_handles"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fgleam_handles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fgleam_handles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fgleam_handles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fgleam_handles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Olian04","download_url":"https://codeload.github.com/Olian04/gleam_handles/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248525784,"owners_count":21118750,"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":["bun","deno","erlang","gleam","gleam-lang","gleam-language","handlebars","mustache","nodejs","template","template-engine","templating","templating-engine"],"created_at":"2024-08-03T04:01:00.260Z","updated_at":"2025-04-12T06:21:56.086Z","avatar_url":"https://github.com/Olian04.png","language":"Gleam","funding_links":[],"categories":["Packages"],"sub_categories":["Templating"],"readme":"[![Package Version](https://img.shields.io/hexpm/v/handles)](https://hex.pm/packages/handles)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/handles/)\n\n# handles\n\n`handles` is a templating language written in pure Gleam. Heavily inspired by [mustache](https://mustache.github.io/) and [Handlebars.js](https://github.com/handlebars-lang/handlebars.js).\n\n```sh\ngleam add handles\n```\n\n```gleam\nimport gleam/io\nimport gleam/string_builder\nimport handles\nimport handles/ctx\n\npub fn main() {\n  let assert Ok(greet_template) = handles.prepare(\"Hello {{.}}!\")\n  let assert Ok(template) =\n    handles.prepare(\"{{\u003egreet world}}\\n{{\u003egreet community}}\\n{{\u003egreet you}}\")\n  let assert Ok(string) =\n    handles.run(\n      template,\n      ctx.Dict([\n        ctx.Prop(\"world\", ctx.Str(\"World\")),\n        ctx.Prop(\"community\", ctx.Str(\"Gleam Community\")),\n        ctx.Prop(\"you\", ctx.Str(\"YOU\")),\n      ]),\n      [#(\"greet\", greet_template)],\n    )\n\n  string\n  |\u003e string_builder.to_string\n  |\u003e io.println\n}\n```\n\nFurther documentation can be found at \u003chttps://hexdocs.pm/handles\u003e.\n\n## Usage Documentation\n\n__Handles__ a is very simple templating language that consists of a single primitive, the \"tag\".\nA tag starts with two open braces `{{`, followed by a string body, and ends with two closing braces `}}`.\nThere are three kinds of tags, [Property tags](#property-tags), [Block tags](#block-tags), and [Partial tags](#partial-tags).\n\n### Property tags\n\nA property tag is used to access properties passed into the template engine and insert them into the resulting string in-place of the property tag.\nValues accessed by a property tag must be of type `String`, `Int`, or `Float`, or it will result in a runtime error.\nAccessing a property which was not passed into the template engine will result in a runtime error.\n\nA property tag can refer to a nested property with `.` separating keys in nested dicts.\n\n```handlebars\n{{some.property.path}}\n```\n\nA property can also refer to the current context element by passing a single `.`.\n\n```handlebars\n{{.}}\n```\n\n### Block tags\n\nA block tag is used to temporarily alter the behavior of the templating engine.\nEach block tag have two variants; A start tag indicated by a leading `#` and a stop tag indicated by a leading `/`.\nA blocks start tag accepts a property accessor, while the end tag does not.\n\n#### if\n\n`if` blocks are used to conditionally _include_ parts of a templated based on the value of a property.\nValues accessed by an if block must be of type `Bool` or it will result in a runtime error.\nAccessing a property which was not passed into the template engine will result in a runtime error.\n\n```handlebars\n{{#if some.prop}}\n  {{name}}\n{{/if}}\n```\n\n#### unless\n\n`unless` blocks are used to conditionally _exclude_ parts of a templated based on the value of a property.\nValues accessed by an `unless` block must be of type `Bool` or it will result in a runtime error.\nAccessing a property which was not passed into the template engine will result in a runtime error.\n\n```handlebars\n{{#unless some.prop}}\n  {{name}}\n{{/unless}}\n```\n\n#### each\n\n`each` blocks are used to include a part of a templated zero or more times.\nValues accessed by an `each` block must be of type `List` or it will result in a runtime error.\nAccessing a property which was not passed into the template engine will result in a runtime error.\nThe context of which properties are resolved while inside the each block will be scoped to the current item from the list.\n\n```handlebars\n{{#each some.prop}}\n  {{name}}\n{{/each}}\n```\n\n### Partial tags\n\nA partial tag is used to include other templates in-place of the partial tag.\nValues accessed by a partial tag can be of any type and will be passed to the partial as the context of which properties are resolved against while inside the partial template.\nAccessing a property which was not passed into the template engine will result in a runtime error.\n\n```handlebars\n{{\u003esome_template some.prop.path}}\n```\n\n## Development\n\nThe source code is structured in such a way that the compiled output when targeting JS does not use recursion in the main parts of the library (`tokenizer.gleam`, `parser.gleam`, `engine.gleam` \u0026 `ctx_utils.gleam`). This prevents the JS engine from throwing \"Maximum call stack size exceeded\" for regular use-cases. While most JS engines boast about implementing tail call optimization, the Gleam compiler is not yet advanced enough to properly take advantage of this. There for, any changes made to the code will need to be carefully inspected after compiling to JS to make sure that no recursion is introduced. This behavior is likely to change with changes to the Gleam compiler, so whenever a new version of the Gleam compiler is released, this library will need to be recompiled and checked (at least until the Gleam compiler becomes smart enough to properly utilize TCO in JS).\n\nLatest Gleam compiler version checked: `1.3.2`\n\nKnown recursion that needs to be resolved:\n\n* Parsing the body of a block in `parser.gleam`\n\n### Running in development\n\n```sh\ngleam test # Test Erlang\ngleam test -t js # Test Nodejs\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folian04%2Fgleam_handles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Folian04%2Fgleam_handles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folian04%2Fgleam_handles/lists"}