{"id":20492079,"url":"https://github.com/zotonic/template_compiler","last_synced_at":"2026-04-01T17:30:21.458Z","repository":{"id":38050380,"uuid":"59116392","full_name":"zotonic/template_compiler","owner":"zotonic","description":"Dynamic template compiler for Erlang ","archived":false,"fork":false,"pushed_at":"2026-03-27T08:16:17.000Z","size":385,"stargazers_count":16,"open_issues_count":1,"forks_count":6,"subscribers_count":10,"default_branch":"master","last_synced_at":"2026-03-27T08:48:15.029Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zotonic.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-05-18T13:07:36.000Z","updated_at":"2026-03-27T08:15:51.000Z","dependencies_parsed_at":"2024-04-26T11:46:04.461Z","dependency_job_id":"a56edc12-869b-4f12-98ca-628faa91ca7c","html_url":"https://github.com/zotonic/template_compiler","commit_stats":{"total_commits":115,"total_committers":5,"mean_commits":23.0,"dds":0.09565217391304348,"last_synced_commit":"5c2187648ea0ef5b1cbe8cf28668db82a95c97ed"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/zotonic/template_compiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zotonic%2Ftemplate_compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zotonic%2Ftemplate_compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zotonic%2Ftemplate_compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zotonic%2Ftemplate_compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zotonic","download_url":"https://codeload.github.com/zotonic/template_compiler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zotonic%2Ftemplate_compiler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"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":[],"created_at":"2024-11-15T17:27:35.558Z","updated_at":"2026-04-01T17:30:21.382Z","avatar_url":"https://github.com/zotonic.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"Template Compiler for Erlang / Elixir\n=====================================\n\n![Test](https://github.com/zotonic/template_compiler/workflows/Test/badge.svg)\n\nThis is the template compiler used by [The Erlang Content Management Framework and CMS Zotonic](https://zotonic.com/).\n\nThis compiler is a complete rewrite of the erlydtl fork used in Zotonic. In contrast with ErlyDTL the template_compiler generates small Erlang modules which are shared between different templates and sites.\n\nBuilding\n--------\n\nRun `make`.\nTo test, run: `make test`\n\nTo use in your project with rebar3, use the [Hex package](https://hex.pm/packages/template_compiler):\n\n```erlang\n{deps, [\n    template_compiler\n]}.\n```\n\nOr directly from git:\n\n```erlang\n{deps, [\n    {template_compiler, {git, \"https://github.com/zotonic/template_compiler\", {branch, \"master\"}}}.\n]}.\n```\n\nTemplate Language\n-----------------\n\nThe template language is largely the same as Django Template Language with some additions:\n\n * Runtime includes, all templates are compiled to separate BEAM modules\n * `overrules` to override same-named templates\n * translation tags `{_ my translatable text _}` and `{% include \"a.tpl\" arg=_\"my translatable text\" %}`\n\n\nRuntime Just in Time compilation\n---------------------------------\n\nThe template_compiler is a runtime compiler. It compiles templates from source files to in-memory BEAM modules.\nTemplates are re-compiled if the source file changes or new translation strings are loaded.\n\nTemplates are compiled to functions containinge entry point to all blocks.\n\nA template like:\n\n```django\nHello\n{% block a %}this is block a{% endblock %}\nWorld\n{% block b %}this is block b{% endblock %}\n{% optional include \"foo.tpl\" %}\n```\n\nWill be compiled to an Erlang module with the following structure:\n\n\n```erlang\n-module(tpl_7bae8076a5771865123be7112468b79e9d78a640).\n-export([\n    render/3,\n    render_block/4,\n    timestamp/0,\n    blocks/0,\n    module/0,\n    extends/0,\n    includes/0,\n    debug_points/0,\n    enabled_debug_points/0,\n    content_checksum/0,\n    is_debug_compiled/0,\n    filename/0,\n    mtime/0,\n    is_autoid/0,\n    runtime/0\n]).\n\n%% The main render function.\nrender(Args, BlockMap, Context) -\u003e [ ... ].\n\n%% Render functions per block, the 'Blocks' is a block trace used internally.\nrender_block(a, Vars, Blocks, Context) -\u003e [ ... ];\nrender_block(b, Vars, Blocks, Context) -\u003e [ ... ];\nrender_block(_, _Vars, _Blocks, _Context) -\u003e \u003c\u003c\u003e\u003e.\n\n%% Timestamp on module compilation (os:timestamp/0)\ntimestamp() -\u003e {1574,685843,340548}.\n\n%% Block defined in this template.\nblocks() -\u003e [ a, b ].\n\n%% The module name\nmodule() -\u003e tpl_7bae8076a5771865123be7112468b79e9d78a640.\n\n%% The template that this template extends on.\nextends() -\u003e undefined.\n\n%% The templates that this template includes.\n%% Includes which use variable names for the template name are not listed.\nincludes() -\u003e [\n        #{\n            template =\u003e \u003c\u003c\"foo.tpl\"\u003e\u003e,\n            line =\u003e 5,\n            column =\u003e 20,\n            method =\u003e optional,   % normal | all | optional\n            is_catinclude =\u003e false\n        }\n    ].\n\n%% All possible debug checkpoints in this template module.\ndebug_points() -\u003e [\n        {\u003c\u003c\"foo/bar/a.tpl\"\u003e\u003e, 1, 1},\n        {\u003c\u003c\"foo/bar/a.tpl\"\u003e\u003e, 3, 5}\n    ].\n\n%% The subset of debug checkpoints enabled when this module was compiled.\nenabled_debug_points() -\u003e #{\n        {3, 5} =\u003e true\n    }.\n\n%% Content checksum of the compiled template source.\ncontent_checksum() -\u003e \u003c\u003c\"...\"\u003e\u003e.\n\n%% Flag if the template was compiled with debug checkpoints enabled.\nis_debug_compiled() -\u003e false.\n\n%% The filename of this template\nfilename() -\u003e \u003c\u003c\"foo/bar/a.tpl\"\u003e\u003e.\n\n%% The modification time of the template file on compilation\nmtime() - {{2023,9,28},{11,51,49}}.\n\n%% Flag if the autoid (\"#id\") construct is used in this template.\nis_autoid() -\u003e false.\n\n%% Runtime module this template is linked against.\nruntime() -\u003e template_compiler_runtime.\n```\n\nThe module includes debug information so that stack traces show the correct template file and line number.\n\n\nRuntime Module\n--------------\n\nThe template_compiler uses a runtime module which implements template lookup and vatiable resolution methods.\nThere is a default runtime module in `template_compiler_runtime`.\n\nThe runtime can also implement tracing hooks:\n\n * `trace_compile/4` is called when a template module is compiled.\n * `trace_render/3` is called when a template is rendered or included.\n * `trace_block/4` is called when a block function is rendered.\n * `trace_debug/3` is called as `trace_debug(SrcPos, Vars, Context)` when an enabled debug checkpoint is hit.\n\n\nHow to use\n----------\n\nRender a template to an iolist:\n\n```erlang\nVars = #{ \u003c\u003c\"a\"\u003e\u003e =\u003e 1 },           % Template variables, use a map\nOptions = [],                       % Render and compilation options\nContext = your_request_context,     % Context passed to the runtime module and filters\n{ok, IOList} = template_compiler:render(\"hello.tpl\", Vars, Options, Context).\n```\n\nThe `template_compiler:render/4` function looks up the template, ensures it is compiled, and then\ncalls the compiled render function of the template or the templates it extends (which are also compiled etc.).\n\n\n#### Compile a template to a module\n\nUse `template_compiler:compile_file/3` and `template_compiler:compile_binary/4` to compile a template file or in-memory binary to a module:\n\n```erlang\n{ok, Module} = template_compiler:compile_binary(\u003c\u003c\"...\"\u003e\u003e, Filename, Options, Context).\n```\n\nThe Filename is used to reference the compiled binary.\n\n\n#### Syntax highlighted HTML\n\nUse `template_compiler:highlight_file/1` to return syntax highlighted HTML for a template source file:\n\n```erlang\n{ok, Html} = template_compiler:highlight_file(\"/full/path/to/hello.tpl\").\n```\n\nThis returns an HTML binary generated by tokenizing the source and merging syntax annotations back into\nthe original template text.\n\nUse `template_compiler:highlight_binary/2` to highlight an in-memory template source:\n\n```erlang\n{ok, Html} = template_compiler:highlight_binary(\u003c\u003c\"Hello {{ name }}\"\u003e\u003e, \u003c\u003c\"hello.tpl\"\u003e\u003e).\n```\n\nThe filename argument is used for source positions in the generated output.\n\nFor a convenience variant without an explicit filename:\n\n```erlang\n{ok, Html} = template_compiler:highlight_binary(\u003c\u003c\"Hello {{ name }}\"\u003e\u003e).\n```\n\nThis uses a dummy template filename internally.\n\nUse `template_compiler:highlight_module/1` to return syntax highlighted HTML for an already compiled template module:\n\n```erlang\n{ok, Mod} = template_compiler:lookup(TemplateFilename, Options, Context),\n{ok, Html} = template_compiler:highlight_module(Mod).\n```\n\nWhen highlighting a compiled template module, the highlighter also reads the module's `debug_points/0`\ncallback and inserts checkbox inputs for those source positions in the generated HTML. The checkbox\nvalue is `Line:Column`.\n\n\n#### Force recompilation\n\nSometimes (for example when template lookups or translations are changed) it is necessary to check all templates if they\nneed to be recompiled.\n\nFor this are the flush functions:\n\n * `template_compiler:flush()` forces a check on all templates.\n * `template_compiler:flush_debug()` forces a recheck of all templates currently compiled with debug checkpoints enabled.\n * `template_compiler:flush_debug(ContextName)` forces a recheck of debug-compiled templates for the given context name.\n * `template_compiler:flush_file(TemplateFile)` forces check on the given template.\n * `template_compiler:flush_context(Context)` forces check on templates compiled within the given request context.\n\nThe template_compiler parses the templates till their _Form_ format and then calculates a checksum. If the checksum\nis not changed from the previous compilation then the _Form_ is not compiled, sparing valuable processing time.\n\n\n#### Debug options\n\nTemplates can optionally be compiled with specific debug checkpoints enabled:\n\n```erlang\nOptions = [\n    {debug_points, [\n        {3, 5}\n    ]}\n].\n```\n\nThe supported debug-related options are:\n\n * `{debug_points, all | [{Line, Column}] | map()}` selects which checkpoints are compiled into the current template module.\n   Lists are internally converted to a map for quick lookup.\n   This option is meant for explicit compilation via `compile_file/3` or `compile_binary/4`.\n   Rendering does not automatically recompile a template when this option changes.\n   When the option is empty (the default), templates are compiled without debug checkpoints.\n\nAll possible checkpoints are always still available through the compiled module metadata, even when no\ndebug checkpoints are enabled in the generated code.\n\nWhen a compiled debug checkpoint is hit, the runtime callback `trace_debug(SrcPos, Vars, Context)` is called.\n`Vars` contains the current template variables at that point, and `SrcPos` contains the source filename,\nline and column of the checkpoint.\n\nCompiled template modules expose these debug-related callbacks:\n\n * `debug_points/0` returns all possible `{Filename, Line, Column}` checkpoints in the module.\n * `enabled_debug_points/0` returns the enabled checkpoint subset used when compiling the module as `{Line, Column}` keys.\n * `is_debug_compiled/0` returns `true` if the template was compiled with one or more debug checkpoints enabled.\n\nTo enable or disable checkpoints for a specific template, recompile that template explicitly with the\ndesired `debug_points` option. This is a per-template operation. Included or composed templates keep\ntheir own compile-time debug configuration and must be recompiled separately if you want debug checkpoints\ninside those templates as well.\n\nAfter a debugging session, `template_compiler:flush_debug/0` can be used to clear all cached\nmodules that are compiled with debug checkpoints enabled. The next render of those templates\nrecompiles them without debug checkpoints.\n\n\nTemplate language and Tags\n==========================\n\n**For more complete documentation see Zotonic: https://docs.zotonic.com/en/latest/developer-guide/templates.html**\n\nBelow is a short list of tags and explanation of template include / extend.\n\nThe `template_compiler` package doesn't include filters.\n\nVariables\n---------\n\nVariables are surrounded by `{{` and `}}` (double braces):\n\n```django\nHello, I’m {{ first_name }} {{ last_name }}.\n```\n\nWhen rendering this template, you need to pass the variables to it. If you pass “James” for\n`first_name` and “Bond” for `last_name`, the template renders to:\n\n```\nHello, I’m James Bond.\n```\n\nInstead of strings, variables can also be objects that contain attributes. To access the attributes, use dot notation:\n\n```django\n{{ article.title }} was created by {{ article.author.last_name }}\n```\n\nThe `article` could have been passed as a proplist or map in the _Vars_ for the template render function:\n\n```erlang\n#{\n    \u003c\u003c\"article\"\u003e\u003e =\u003e #{\n        \u003c\u003c\"title\"\u003e\u003e =\u003e \u003c\u003c\"My title\"/utf8\u003e\u003e,\n        \u003c\u003c\"author\"\u003e\u003e =\u003e #{\n            \u003c\u003c\"id\"\u003e\u003e =\u003e 1234,\n            \u003c\u003c\"last_name\"\u003e\u003e =\u003e \u003c\u003c\"Janssen\"\u003e\u003e\n        }\n    }\n}.\n```\n\nValues and expressions\n----------------------\n\nExpressions can use different values types:\n\n * Variables (see above)\n * Number: `123`\n * String: `\"hello\"` or `'hello'`\n * Translatable string: `_\"Hello\"` (see below)\n * List:  `[ 1, 2, 3 ]`\n * Map, using Elixir syntax: `%{ a: 1, b: 2 }` where the keys will become binary strings\n   equivalent to the Erlang map: `#{ \u003c\u003c\"a\"\u003e\u003e =\u003e 1, \u003c\u003c\"b\"\u003e\u003e =\u003e 2 }`\n * Map, using strings as keys: `%{ \"foaf:name\":\"Hello\" }`\n * Erlang atom: \u003ctt\u003e\u0026grave;a\u0026grave;\u003c/tt\u003e (quoted using backticks)\n * Tagged value list: `{mytag a=1 b=2}`, this translates to Erlang `{mytag, [{a,1}, {b,2}]}`\n * Unique generated id: `#foo` - an unique prefix is used for each template\n * Model calls `m.rsc.foo`\n * Model calls with an optional argument `m.rsc.foo::bar`\n\nTranslatable texts\n------------------\n\nThere are three ways translatable texts can be used.\n\nAs a tag embedded in the text of the template:\n\n```django\n{_ This text is translatable _}\n```\n\nAs double quoted string prefixed with a '_', where you could also use a string:\n\n```django\n{% include \"_a.tpl\" title=_\"Translatable text\" %}\n```\n\nAs a text with arguments:\n\n```django\n{% trans \"Hello {foo}, Bye\" foo=author.name_full %}\n```\n\nNote: to show a `{` or `}` in a `trans` tag text then double it to `{{`.\n\nThe `trans` tag is compiled to code so very efficient.\n\n\n#### List translatable strings\n\nTo get a list of all translatable texts in a template use:\n\n```erlang\ntemplate_compiler:translations(TemplateFilename).\n```\n\nThis returns a list of all strings, which could be used to generate a .po file:\n\n```erlang\n[\n    {\u003c\u003c\"Hello {foo}, Bye\"\u003e\u003e, [], {\u003c\u003c\"foo/bar.tpl\"\u003e\u003e, 1234, 5}}\n].\n```\n\nTemplate include / extends\n--------------------------\n\nTemplates can be combined to re-use parts and keep everything manageable.\n\n#### Include\n\nFirst a template can be included in another template:\n\n```django\nHello {% include \"_name.tpl\" id=foobar %}\n```\n\nThe template (`_name.tpl` in this case) will be included at the called spot.\nAll variables known at the spot of the include will be passed, with the addition of\nthe arguments of the include tags.\n\nNote: in ErlyDTL the included template is compiled inline into the surrounding\ntemplate. In template_compiler the included template is compiled as a separate module.\n\n#### Extends\n\nYou can also have a _base_ template which can be used as the basis of other templates.\nThe base template should define some _blocks_ that can be changed in the template\nthat extends the base template:\n\n```django\n{% extends \"base.tpl\" %}\n{% block name %}Piet!{% endblock %}\n```\n\nWhere the `base.tpl` could be:\n\n```django\nHello {% block name %}...{% endblock %} world.\n```\n\nThe `{% extends \"...\" %}` tag _must_ be the first tag in the template. Also any text\noutside the block tags will be dropped. So be sure to surround replaceable parts in your\nbase templates with block tags.\n\nThere is a variation on `extends` where the template extends on a same-named template\nof a lower priority. This is heavily used in Zotonic to extend templates in other modules.\n\n```django\n{% overrules %}\n{% block name %}...{% endblock %}\n```\n\nThe `overrules` is used to make it explicit that this template overrules (or extends)\nanother template with the same name.\n\n#### Block\n\nThis defines a named portion of a template that can be replaced in a template that extends\n(or overrules) this template:\n\n```django\nSome text\n{% block myname %}\n    Some text in the block that might be replaced\n{% endblock %}\nAnd text after the block\n```\n\nBlocks can be nested:\n\n```django\nSome text\n{% block myname %}\n    Some text in the block that might be replaced\n    {% block nestedblock %}\n        Text in the nested block\n    {% endblock %}\n    And more text in the outer block\n{% endblock %}\nAnd text after the block\n```\n\nThe blocks are compiled to separate functions. The template compiler uses the template\nextends chain to figure out which block-function to render from which extending template.\n\n#### Inherit\n\nThe `{% inherit %}` tag van be used inside a block to render the same-named block in\nthe extended (or overruled) template.\n\nIf base.tpl is like:\n\n```django\nthis is {% block a %}the base{% endblock %} template\n```\n\nAnd a.tpl is like:\n\n```django\n{% extends \"base.tpl\" %}\n{% block a %}hello {% inherit %} world{% endblock %}\n```\n\nThen `a.tpl` renders like:\n\n```\nthis is hello the base world template\n```\n\n#### Template compose\n\nThis includes a template, but also defines extra blocks for the template\nto overrule the blocks in the template.\n\nIt is like a nameless `{% overrules %}` template, directly defined in the\ntemplate text at the spot of the include.\n\n\n```django\n{% compose \"a.tpl\" what=\"moon\" %}\n{% block a %}{{ what }}{% endblock %}\n{% endcompose %}\n```\n\nAnd a.tpl is like:\n\n```django\nHello {% block a %}world{% endblock %}, and bye.\n```\n\nThen the above renders:\n\n```\nHello moon, and bye.\n```\n\nThere is also a `catcompose` to use a `catinclude`:\n\n```django\n{% catcompose \"a.tpl\" id what=\"moon\" %}\n{% block a %}{{ what }}{% endblock %}\n{% endcompose %}\n\n```\n\n\n#### If tag\n\nConditionally show or hide parts of a template:\n\n```django\n{% if somevar %}\n    True\n{% elif othervar %}\n    Other var\n{% else %}\n    False\n{% endif %}\n```\n\nThe `elif` can also be written as `elseif`\n\n#### With tag\n\nDefine a variable to be used within an enclosed part of the template:\n\n```django\n{% with someexpr as v %}\n    Here v can be used as any other variable\n{% endwith %}\n```\n\nThis is useful for using the result of a complicated expression multiple times\nor if a `forloop` (see below) iterator needs to be used in overruled blocks or\nincluded templates.\n\n#### For tag\n\nLoop over a list of values, printing a comma separated list:\n\n```django\n{% for k in [ 1, 2, 3, 4 ] %}\n    {{ k }}{% if nor forloop.last %},{% endif %}\n{% endfor %}\n```\n\nLoop over a list of tuples (eg. `[ {a, 1}, {b, 2} ]`):\n\n```django\n\u003ctable\u003e\n{% for key, value in someproplist %}\n    \u003ctr\u003e\n        \u003cth\u003e{{ key|escape }}\u003c/th\u003e\n        \u003ctd\u003e{{ value|escape }}\u003c/td\u003e\n    \u003c/tr\u003e\n{% empty %}\n    \u003ctr\u003e\n        \u003ctd\u003e{_ Sorry, no values _}\u003c/td\u003e\n    \u003c/tr\u003e\n{% endfor %}\n\u003c/table\u003e\n```\n\nWithin a forloop there is an iterator called `forloop` with the following\nproperties:\n\n * `forloop.first` true if this is the first iteration\n * `forloop.last` true if this is the last iteration\n * `forloop.counter` iteration counter, starts at `1`\n * `forloop.counter0` iteratiomn counter, starts at `0`\n * `forloop.revcounter` iteration counter, starts at `N`, ends at `1`\n * `forloop.revcounter0` iteration counter, starts at `N-1`, ends at `0`\n * `forloop.parentloop` the `forloop` parameter of the enclosing _for_ loop (if any)\n\n**NOTE** the `forloop` iterator is only available in the template that contains\nthe `for` loop, it is not passed to any included or extending templates.\nIf you want to use it in a block or included template then explicitly assign it to\na variable using `with` or include arguments.\n\nIf the template compiler does sees that the `forloop` is not used inside the template\nwhere the forloop is defined then the code for tracking the forloop iterators is not\ngenerated.\n\n\n#### Comment tag\n\nEverything surrounded by the tag is excluded:\n\n```django\n{% comment %}\n    Some explanation that will not be part of the compiled template\n{% endcomment %}\n```\n\nUseful to disable parts of a template or add some explanatory texts.\n\n\n#### Raw tag\n\nTo echo some part without rendering it:\n\n```django\n{% raw %}\n    {{ hello }} {% this is }} %} echo'd as-is\n{% endraw %}\n```\n\n#### Spaceless tag\n\nRemove spaces between HTML tags:\n\n```django\na-{% spaceless %} \u003ca\u003e x\u003cspan\u003exxx \u003c/span\u003e \u003c/a\u003e {% endspaceless %}-b\n```\n\nRenders as:\n\n```html\na-\u003ca\u003e x\u003cspan\u003exxx \u003c/span\u003e\u003c/a\u003e-b\n```\n\n#### Print tag\n\nPrint a value in `\u003cpre\u003e` tags, used to inspect variables or dump some value\nwhen you are still writing the template:\n\n```django\n{% print somexpr %}\n```\n\nThe expression value will be printed using `io_lib:format(\"~p\", [ SomExpr ])`, then\nescaped and surrounded with `\u003cpre\u003e...\u003c/pre\u003e`.\n\nWhitespace Handling\n-------------------\n\n- A single trailing newline is stripped, from the template, if present.\n- Other whitespace, like tabs, newlines and spaces are returned unchanged.\n\nLicense\n=======\n\nThe template_compiler is released under the APLv2 license. See the file LICENSE for the exact terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzotonic%2Ftemplate_compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzotonic%2Ftemplate_compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzotonic%2Ftemplate_compiler/lists"}