{"id":19075834,"url":"https://github.com/secomind/exjsontemplate","last_synced_at":"2026-06-13T20:02:24.014Z","repository":{"id":53193085,"uuid":"280452392","full_name":"secomind/exjsontemplate","owner":"secomind","description":"JSON templating library based on JSONPath for Elixir","archived":false,"fork":false,"pushed_at":"2021-04-01T15:16:55.000Z","size":22,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-02-18T01:15:38.243Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/secomind.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-17T14:57:15.000Z","updated_at":"2024-01-25T07:49:29.000Z","dependencies_parsed_at":"2022-09-15T01:12:38.276Z","dependency_job_id":null,"html_url":"https://github.com/secomind/exjsontemplate","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/secomind/exjsontemplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secomind%2Fexjsontemplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secomind%2Fexjsontemplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secomind%2Fexjsontemplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secomind%2Fexjsontemplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/secomind","download_url":"https://codeload.github.com/secomind/exjsontemplate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secomind%2Fexjsontemplate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34298259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-11-09T01:56:07.546Z","updated_at":"2026-06-13T20:02:23.993Z","avatar_url":"https://github.com/secomind.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ExJSONTemplate\n\nExJSONTemplate is an Elixir library which allows to write JSON templates in JSON.\n\n## JSONTemplate\n\nThe most basic template operation is string interpolation:\n\n```\nin: {\"user\": \"foo\"}\ntemplate: {\"greet\": \"Hello {{ $.user }}\"}\nout: {\"greet\": \"Hello user\"}\n```\n\nWhen using string interpolation scalar values (such as boolean, numbers, ...) are converted to\nstring by default:\n\n```\nin: {\"num\": 42}\ntemplate: {\"answer\": \"The answer to the Ultimate Question of Life, the Universe, and Everything is {{ $.num }}\"}\nout: {\"answer\": \"The answer to the Ultimate Question of Life, the Universe, and Everything is 42\"}\n```\n\nBeware that non scalar values (such as arrays) cannot be converted to string, therefore a rendering\nerror is raised.\n\nString interpolation can be avoided using `{{{ }}}`, which is the preferred method for templating\nnon string values:\n```\nin: {\"number\": 5}\nt: {\"a\": \"{{{ $.number }}}\"}\nout: {\"a\": 5}\n```\n\n`{{{ }}}` cannot be mixed with string interpolation, therefore `\" {{{ $.test }}} a\"` causes a\nrendering error.\n\n### `\u0026` (Unquote) Operator\n\nUnquote operator should be used when a scalar value is represented as string (such as `\"5\"`):\n\n```\nin: {\"number\": \"5\"}\nt: {\"a\": \"{{\u0026 $.number}}\"}\nout: {\"a\": 5}\n```\n\nIf a string cannot be parsed as a scalar value, a rendering error is returned.\n\nUnquote doesn't work with arrays and objects since they are not scalar values.\n\nWhen `\u0026` operator is applied to any non string value, it behaves like `{{{ }}}`:\n\n```\nin: {\"number\": 5}\nt: {\"a\": \"{{\u0026 $.number}}\"}\nout: {\"a\": 5}\n```\n\n`\u0026` can be also used for non scalar values such as:\n\n```\nin: {\"nums\": [0, 1, 2, 3, 4, 5]}\nt: {\"nums2\": [\"{{\u0026 $.nums}}\"]}\nout: {\"nums2\": [[0, 1, 2, 3, 4, 5]]}\n```\n\n`\u0026` never renders strings, therefore it cannot be used for string interpolation.\n\n### `#` (Section) Operator\n\nArray templates can be written using `#` section operator:\n\n```\nin: {\"repo\": [{\"name\": \"Davide\"}, {\"name\": \"Riccardo\"}]}\nt: {\"{{#repo}}\": \"Hello {{ @.name }}\"}\nout: [\"Hello Davide\", \"Hello Riccardo\"]\n```\n\n```\nin: {\"repo\": [\"Davide\", \"Riccardo\"]}\nt: {\"{{#repo}}\": \"Hello {{ @ }}\"}\nout: [\"Hello Davide\", \"Hello Riccardo\"]\n```\n\n`#` operator can be also used for optional sections when applied to a boolean:\n\n```\nin: {\"person\": true, \"name\": \"Davide\"}\nt: {\"{{#person}}\": \"Hello {{$.name}}\"}\nout: \"Hello Davide\"\n```\n\n### `^` (Inverted Optional Section) Operator\n\nOptional sections can be left out using `^` operator:\n\n```\nin: {\"person\": true, \"name\": \"Davide\"}\nt: {\"a\": 1, \"b\": {\"{{^person}}\": \"Hello {{$.name}}\"}}\nout: {\"a\": 1}\n```\n\nWhen the whole template is optional, `null` is rendered.\n\n```\nin: {\"person\": true, \"name\": \"Davide\"}\nt: {\"{{^person}}\": \"Hello {{$.name}}\"}\nout: null\n```\n\n`null` is rendered only when the inverted section is used as root object, otherwise the key\nassociated to the inverted section is deleted.\n\nEach optional section object can have only a single key, (e.g. `{\"{{^ $.a }}\": 1, \"{{^ $.b}}\": 2}`\nis invalid.\n\n### `?` (Switch) Operator\n\nSwitch operator is useful when handling multiple cases, such as when dealing with enumerations:\n\n```\nin: {\"num\": 1}\nt: {\n  \"message\": {\n    \"{{?num}}\": [\n      {\"case\": 1, \"template\": \"one\"},\n      {\"case\": 2, \"template\": \"two\"},\n      {\"case\": 3, \"template\": \"three\"},\n      {\"template\": \"A lot.\"}\n    ]\n  }\n}\nout: {\"message\": \"one\"}\n```\n\nWhen a default template is not provided, it behaves like `^`:\n\n```\nin: {\"num\": 5}\nt: {\n  \"message\": {\n    \"{{?num}}\": [\n      {\"case\": 1, \"template\": \"one\"},\n      {\"case\": 2, \"template\": \"two\"},\n      {\"case\": 3, \"template\": \"three\"}\n    ]\n  }\n}\nout: {}\n```\n\nWhen an invalid default template `null` is provided a rendering error is returned:\n\n```\nin: {\"num\": 5}\nt: {\n  \"message\": {\n    \"{{?num}}\": [\n      {\"case\": 1, \"template\": \"one\"},\n      {\"case\": 2, \"template\": \"two\"},\n      {\"case\": 3, \"template\": \"three\"},\n      null\n    ]\n  }\n}\nout: Rendering error\n```\n\nSwitch operator can be used with boolens, and for testing if a value is non null as well, in this\ncase a more concise syntax can be used:\n\n```\nin: {\"person\": true, \"name\": \"Davide\"}\nt: {\"{{?person}}\": {\"true\": \"Hello {{$.name}}\", \"false\": \"Bye\"}}\nout: \"Hello Davide\"\n```\n\n```\nin: {\"person\": false, \"name\": \"Davide\"}\nt: {\"message\": {\"{{?person}}\": {\"true\": \"Hello {{$.name}}\", \"false\": \"Bye\"}}}\nout: {\"message\": \"Bye\"}\n```\n\n```\nin: {\"person\": false, \"name\": \"Davide\"}\nt: {\"message\": {\"{{?person}}\": {\"true\": \"Hello {{$.name}}\"}}}\nout: {}\n```\n\n### Interaction with JSONPath\n\nJSONPath in simple scenarios evaluates to single values, however complex queries involving (`..`,\n`*`, etc...) might evaluate to multiple values.\n\nIn the following example `$.user` evaluates to `[\"foo\"]`, JSON template will always unwrap the item\nat index 0 when using an interpolation with a JSONPath that evaluates to a single value.\n\n```\nin: {\"user\": \"foo\"}\ntemplate: {\"greet\": \"Hello {{ $.user }}\"}\nout: {\"greet\": \"Hello user\"}\n```\n\nJSON path `$..user` evaluates to a \"multiple result\" (`[\"foo\", \"bar\"]`) that is processed in the\nsame way of an array single result (`[[\"foo\", \"bar\"]]`).\n\n```\nin: [{\"user\": \"foo\"}, %{\"user\" =\u003e \"bar\"}]\nt: {\"{{# $..user }}\": \"Hello {{ @ }}\"}\nout: [\"Hello foo\", \"Hello bar\"]\n```\n\n### Escaping {{ and {{{\n\n`{{` and `{{{` can be escaped using `\\`, such as `\\{{ $.foo }}` that is rendered as `\\{{ $.foo }}`.\nAs a consequence`\\{{ test }}` should be written `\\\\{{ test }}`. Same applies to $ keys, such as\n`\\$jsontemplate`.\n\n### Template options\n\nJSON templates can have an optional envelope that can be used for specifing json template version\nand any additional option.\n\n```\n{\n   \"$jsontemplate\": \"1.0\",\n   \"template: \u003c\u003ctemplate here\u003e\u003e\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecomind%2Fexjsontemplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecomind%2Fexjsontemplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecomind%2Fexjsontemplate/lists"}