{"id":31580361,"url":"https://github.com/franbarinstance/neutralts-docs","last_synced_at":"2025-10-05T21:11:19.268Z","repository":{"id":312515730,"uuid":"1045640693","full_name":"FranBarInstance/neutralts-docs","owner":"FranBarInstance","description":"NeutralTS, Template system for the Web backend, language-agnostic via IPC/Package and natively as library/crate in Rust. ","archived":false,"fork":false,"pushed_at":"2025-09-16T10:06:53.000Z","size":2727,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-04T09:27:20.793Z","etag":null,"topics":["go-template-engine","golang-template","neutral-ts","node-template","nodejs-template-engine","php-template-engine","python-template-engine","rust-template-engine","template-engine","template-engine-rust","web-template"],"latest_commit_sha":null,"homepage":"https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/","language":null,"has_issues":false,"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/FranBarInstance.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":"2025-08-27T13:48:26.000Z","updated_at":"2025-09-18T18:33:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"2f6f34de-6b0a-44f6-9377-3be5949b8256","html_url":"https://github.com/FranBarInstance/neutralts-docs","commit_stats":null,"previous_names":["franbarinstance/neutralts-docs"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/FranBarInstance/neutralts-docs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranBarInstance%2Fneutralts-docs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranBarInstance%2Fneutralts-docs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranBarInstance%2Fneutralts-docs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranBarInstance%2Fneutralts-docs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FranBarInstance","download_url":"https://codeload.github.com/FranBarInstance/neutralts-docs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranBarInstance%2Fneutralts-docs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278519825,"owners_count":26000354,"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","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"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":["go-template-engine","golang-template","neutral-ts","node-template","nodejs-template-engine","php-template-engine","python-template-engine","rust-template-engine","template-engine","template-engine-rust","web-template"],"created_at":"2025-10-05T21:11:18.171Z","updated_at":"2025-10-05T21:11:19.256Z","avatar_url":"https://github.com/FranBarInstance.png","language":null,"readme":"![neutral](https://raw.githubusercontent.com/FranBarInstance/neutralts/refs/heads/master/top-neutralts.png)\n\nWeb Template Engine - Neutral TS\n================================\n\nNeutral TS is a **safe, modular, language-agnostic template engine** built in Rust. It works as a **native Rust library** or via **IPC** for other languages like Python and PHP. With Neutral TS you can reuse the **same template across multiple languages** with consistent results.\n\nExamples for [Rust](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/rust), [Python](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/python), [PHP](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/php), [Node.js](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/node) and [Go](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/go) here: [download](https://github.com/FranBarInstance/neutralts-docs/releases). All PWA [examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples) use the same template: [Neutral templates](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/neutral).\n\nThe documentation of the **web template** engine is here: [template engine doc](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/) and **Rust** documentation here: [Rust doc](https://docs.rs/neutralts/latest/neutralts/).\n\nTemplate Engine - Features\n--------------------------\n\nIt allows you to create templates compatible with any system and any programming language.\n\n* Safe\n* Language-agnostic\n* Modular\n* Parameterizable\n* Efficient\n* Inheritance\n* Cache modular and !cache\n* Objects\n* JS fetch\n* Parse files\n* Embed files\n* Localization\n* Debug\n* Loops: for and each\n* Snippets\n* Nesting, grouping and wrapping\n* Redirections: HTTP y JavaScript\n* Exit with error: 403, 404, 503, ...\n* Comments\n\nHow it works\n------------\n\nNeutral TS supports two integration approaches:\n\n### **Available Modes:**\n- **Rust**: Native library ([crate](https://crates.io/crates/neutralts)) **or** IPC client ([crate](https://crates.io/crates/neutralipcrs)) + IPC server\n- **Python**: Native package **or** IPC client + IPC server\n- **Other languages** (PHP, etc.): IPC client + IPC server required\n\n### **The MySQL Analogy (IPC architecture):**\nUses the exact same client-server mechanism as a database:\n\n**MySQL:**\n- TCP server that receives SQL queries\n- Processes queries internally\n- Returns results to the client\n\n**Neutral TS:**\n- TCP server that receives templates + JSON data\n- Processes templates internally\n- Returns rendered HTML to the client\n\n### **Why It Works:**\n- **Same principle**: Lightweight client + Powerful server\n- **Universal protocol**: TCP + text/JSON (supported by all languages)\n- **Consistent results**: Same engine processes everything, guaranteeing identical output\n- **Minimal dependencies**: IPC clients are extremely lightweight with minimal external dependencies\n- **Easy updates**: No application recompilation needed - simply update the IPC server for engine improvements\n\n### **Security Advantage:**\nThe IPC architecture provides important security benefits:\n- **Sandboxed execution**: Templates run in isolated processes\n- **Reduced attack surface**: Main application protected from template engine vulnerabilities\n- **Resource control**: Memory and CPU limits can be enforced at server level\n- **Crash containment**: Template engine failures don't affect the main application\n- **Zero-downtime updates**: IPC server can be updated independently without restarting client applications\n\n### **Key Advantage:**\nJust like an SQL query returns the same data from any language, a Neutral TS template returns the same HTML from Python, PHP, Rust... with added security isolation.\n\n### **Performance Consideration:**\nThe IPC approach introduces performance overhead due to inter-process communication. The impact varies depending on:\n\n- Application type\n- Programming language\n- Network latency\n\nFor most web applications, the security and interoperability benefits compensate for the performance overhead.\n\n### **IPC Components:**\n- **IPC Server**: Universal standalone application (written in Rust) for all languages - download from: [IPC Server](https://github.com/FranBarInstance/neutral-ipc/releases)\n- **IPC Clients**: Language-specific libraries to include in your project - available at: [IPC Clients](https://github.com/FranBarInstance/neutral-ipc/tree/master/clients)\n\n\nLocalization\n------------\n\nNeutral TS template engine provides powerful and easy-to-use translation utilities... define the translation in a JSON:\n\n```json\n\"locale\": {\n    \"current\": \"en\",\n    \"trans\": {\n        \"en\": {\n            \"Hello\": \"Hello\",\n            \"ref:greeting-nts\": \"Hello\"\n        },\n        \"es\": {\n            \"Hello\": \"Hola\",\n            \"ref:greeting-nts\": \"Hola\"\n        },\n        \"de\": {\n            \"Hello\": \"Hallo\",\n            \"ref:greeting-nts\": \"Hallo\"\n        },\n        \"fr\": {\n            \"Hello\": \"Bonjour\",\n            \"ref:greeting-nts\": \"Bonjour\"\n        },\n        \"el\": {\n            \"Hello\": \"Γεια σας\",\n            \"ref:greeting-nts\": \"Γεια σας\"\n        }\n    }\n}\n```\n\nNow you can use:\n\n```neutral\n{:trans; Hello :}\n```\n\nActually you can always use \"trans\" because if there is no translation it returns the text.  See: [locale](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/#locale--) and [trans](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/#trans--).\n\nBif layout (Build-in function)\n------------------------------\n\n```neutral\n\n    .-- open bif\n    |    .-- bif name\n    |    |   .-- name separator\n    |    |   |     .-- params\n    |    |   |     |    .-- params/code separator\n    |    |   |     |    |    .-- code\n    |    |   |     |    |    |   .-- close bif\n    |    |   |     |    |    |   |\n    v    v   v     v    v    v   v\n    -- ----- - -------- -- ----- --\n    {:snippet; snipname \u003e\u003e  ...  :}\n    ------------------------------\n            ^ -------------------\n            |         ^\n            |         |\n            |         `-- source\n            `-- Build-in function\n\n```\n\nBif example: (See: [syntax](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/#syntax))\n\n```neutral\n{:filled; varname \u003e\u003e\n    Hello!\n:}\n```\n\nNeutral TS template engine is based on Bifs with block structure, we call the set of nested Bifs of the same level a block:\n\n```neutral\n\n              .-- {:coalesce;\n              |       {:code;\n              |           {:code; ... :}\n              |           {:code; ... :}\n    Block --\u003e |           {:code; ... :}\n              |       :}\n              |       {:code;\n              |           {:code; ... :}\n              |       :}\n              `-- :}\n\n                  {:coalesce;\n              .------ {:code;\n              |           {:code; ... :}\n    Block --\u003e |           {:code; ... :}\n              |           {:code; ... :}\n              `------ :}\n              .------ {:code;\n    Block --\u003e |           {:code; ... :}\n              `------ :}\n                  :}\n\n```\n\nShort circuit at block level, if varname is not defined, the following \"\u003e\u003e\" is not evaluated:\n\n```neutral\n{:defined; varname \u003e\u003e\n    {:code;\n        {:code;\n            ...\n        :}\n    :}\n:}\n```\n\nBy design all Bifs can be nested and there can be a Bif anywhere in another Bif except in the name.\n\nData\n----\n\nThe data is defined in a JSON:\n\n```json\n\"data\": {\n    \"true\": true,\n    \"false\": false,\n    \"hello\": \"hello\",\n    \"zero\": \"0\",\n    \"one\": \"1\",\n    \"spaces\": \"  \",\n    \"empty\": \"\",\n    \"null\": null,\n    \"emptyarr\": [],\n    \"array\": {\n        \"true\": true,\n        \"false\": false,\n        \"hello\": \"hello\",\n        \"zero\": \"0\",\n        \"one\": \"1\",\n        \"spaces\": \"  \",\n        \"empty\": \"\",\n        \"null\": null\n    }\n}\n```\n\nAnd they are displayed with the bif {:; ... :} (var)\n\nSimple variable:\n\n```neutral\n{:;hello:}\n```\n\nArrays with the \"-\u003e\" operator\n\n```neutral\n{:;array-\u003ehello:}\n```\n\nSnippets\n--------\n\nSnippet is a tool that can be used in a similar way to a function, it defines a snippet:\n\n```neutral\n{:snippet; name \u003e\u003e\n    Any content here, including other snippet.\n:}\n```\n\nFrom then on you can invoke it like this:\n\n```neutral\n{:snippet; name :}\n```\n\nSee: [snippet](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/#snippet--).\n\nCache\n-----\n\nThe cache is modular, allowing only parts of the template to be included in the cache:\n\n```plaintext\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eTemplate engine cache\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        {:cache; /120/ \u003e\u003e\n            \u003cdiv\u003e{:code; ... :}\u003c/div\u003e\n        :}\n        \u003cdiv\u003e{:date; %H:%M:%S :}\u003c/div\u003e\n        {:cache; /120/ \u003e\u003e\n            \u003cdiv\u003e{:code; ... :}\u003c/div\u003e\n        :}\n    \u003c/body\u003e\n\u003c/html\u003e\n```\nOr exclude parts of the cache, the previous example would be much better like this:\n\n```plaintext\n{:cache; /120/ \u003e\u003e\n    \u003c!DOCTYPE html\u003e\n    \u003chtml\u003e\n        \u003chead\u003e\n            \u003ctitle\u003eTemplate engine cache\u003c/title\u003e\n        \u003c/head\u003e\n        \u003cbody\u003e\n            \u003cdiv\u003e{:code; ... :}\u003c/div\u003e\n            {:!cache;\n                {:date; %H:%M:%S :}\n            :}\n            \u003cdiv\u003e{:code; ... :}\u003c/div\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e\n:}\n```\n\nFetch\n-----\n\nNeutral TS template engine provides a basic JavaScript to perform simple `fetch` requests:\n\n```plaintext\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eTemplate engine\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        {:fetch; \"/form-login\" \u003e\u003e\n            \u003cdiv\u003eLoading...\u003c/div\u003e\n        :}\n    \u003c/body\u003e\n\u003c/html\u003e\n```\nSee: [fetch](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/#fetch--).\n\nObject\n------\n\n`obj` allows you to execute scripts in other languages like Python\n\n```html\n{:obj;\n    {\n        \"engine\": \"Python\",\n        \"file\": \"script.py\",\n        \"template\": \"template.ntpl\"\n    }\n:}\n```\nSee: [obj](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/#obj--).\n\nDebug\n------\n\nDisplay debug information\n\n```html\n{:debug; data-\u003evarname :}\n```\nSee: [debug](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/#debug--).\n\nWeb template - example\n----------------------\n\n```html\n{:*\n    comment\n*:}\n{:locale; locale.json :}\n{:include; theme-snippets.ntpl :}\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"{:lang;:}\"\u003e\n    \u003chead\u003e\n        \u003ctitle\u003e{:trans; Site title :}\u003c/title\u003e\n        \u003cmeta charset=\"utf-8\"\u003e\n        \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n        {:snippet; current-theme:head :}\n        \u003clink rel=\"stylesheet\" href=\"bootstrap.min.css\"\u003e\n    \u003c/head\u003e\n    \u003cbody class=\"{:;body-class:}\"\u003e\n        {:snippet; current-theme:body_begin  :}\n        {:snippet; current-theme:body-content :}\n        {:snippet; current-theme:body-footer  :}\n        \u003cscript src=\"jquery.min.js\"\u003e\u003c/script\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nUsage\n-----\n\nYou need two things, a template file and a json schema:\n\n```plaintext\n{\n    \"config\": {\n        \"comments\": \"remove\",\n        \"cache_prefix\": \"neutral-cache\",\n        \"cache_dir\": \"\",\n        \"cache_on_post\": false,\n        \"cache_on_get\": true,\n        \"cache_on_cookies\": true,\n        \"cache_disable\": false,\n        \"filter_all\": false,\n        \"disable_js\": false\n    },\n    \"inherit\": {\n        \"locale\": {\n            \"current\": \"en\",\n            \"trans\": {\n                \"en\": {\n                    \"Hello nts\": \"Hello\",\n                    \"ref:greeting-nts\": \"Hello\"\n                },\n                \"es\": {\n                    \"Hello nts\": \"Hola\",\n                    \"ref:greeting-nts\": \"Hola\"\n                },\n                \"de\": {\n                    \"Hello nts\": \"Hallo\",\n                    \"ref:greeting-nts\": \"Hallo\"\n                },\n                \"fr\": {\n                    \"Hello nts\": \"Bonjour\",\n                    \"ref:greeting-nts\": \"Bonjour\"\n                },\n                \"el\": {\n                    \"Hello nts\": \"Γεια σας\",\n                    \"ref:greeting-nts\": \"Γεια σας\"\n                }\n            }\n        }\n    },\n    \"data\": {\n        \"CONTEXT\": {\n            \"ROUTE\": \"\",\n            \"HOST\": \"\",\n            \"GET\": {},\n            \"POST\": {},\n            \"HEADERS\": {},\n            \"FILES\": {},\n            \"COOKIES\": {},\n            \"SESSION\": {},\n            \"ENV\": {}\n        },\n        \"site_name\": \"MySite\",\n        \"site\": {\n            \"name\": \"MySite\",\n        }\n    }\n}\n```\n\nTemplate file.ntpl:\n\n```text\n{:;site_name:}\n```\n\nOr for array:\n\n```text\n{:;site-\u003ename:}\n```\n\nNative use (Rust)\n-----------------\n\nAlternatively, you can use: [Neutral TS Rust IPC Client](https://crates.io/crates/neutralipcrs)\n\n```text\nuse neutralts::Template;\nuse serde_json::json;\n\nlet template = Template::from_file_value(\"file.ntpl\", schema).unwrap();\nlet content = template.render();\n\n// e.g.: 200\nlet status_code = template.get_status_code();\n\n// e.g.: OK\nlet status_text = template.get_status_text();\n\n// empty if no error\nlet status_param = template.get_status_param();\n\n// act accordingly at this point according to your framework\n```\n[Rust examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/rust)\n\n\nPython - Package\n----------------\n\n```text\npip install neutraltemplate\n```\n\n```text\nfrom neutraltemplate import NeutralTemplate\n\ntemplate = NeutralTemplate(\"file.ntpl\", schema)\ncontents = template.render()\n\n# e.g.: 200\nstatus_code = template.get_status_code()\n\n# e.g.: OK\nstatus_text = template.get_status_text()\n\n# empty if no error\nstatus_param = template.get_status_param()\n\n# act accordingly at this point according to your framework\n```\n[Python examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/python)\n\n\nPython - IPC\n------------\n\n- Requires the IPC server: [Neutral TS IPC Server](https://github.com/FranBarInstance/neutral-ipc/releases)\n- Requires the Python IPC client: [Neutral TS IPC Clients](https://github.com/FranBarInstance/neutral-ipc)\n\n```text\nfrom NeutralIpcTemplate import NeutralIpcTemplate\n\ntemplate = NeutralIpcTemplate(\"file.ntpl\", schema)\ncontents = template.render()\n\n# e.g.: 200\nstatus_code = template.get_status_code()\n\n# e.g.: OK\nstatus_text = template.get_status_text()\n\n# empty if no error\nstatus_param = template.get_status_param()\n\n# act accordingly at this point according to your framework\n```\n[Python examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/python)\n\n\nPHP\n---\n\n- Requires the IPC server: [Neutral TS IPC Server](https://github.com/FranBarInstance/neutral-ipc/releases)\n- Requires the PHP IPC client: [Neutral TS IPC Clients](https://github.com/FranBarInstance/neutral-ipc)\n\n[PHP examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/php)\n\nNode.js\n-------\n\n- Requires the IPC server: [Neutral TS IPC Server](https://github.com/FranBarInstance/neutral-ipc/releases)\n- Requires the Node IPC client: [Neutral TS IPC Clients](https://github.com/FranBarInstance/neutral-ipc)\n\n[Node.js examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/node)\n\nGo\n--\n\n- Requires the IPC server: [Neutral TS IPC Server](https://github.com/FranBarInstance/neutral-ipc/releases)\n- Requires the Go IPC client: [Neutral TS IPC Clients](https://github.com/FranBarInstance/neutral-ipc)\n\n[Go examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples/go)\n\nNeutral TS template engine\n--------------------------\n\n- [Rust docs](https://docs.rs/neutralts/latest/neutralts/)\n- [Template docs](https://franbarinstance.github.io/neutralts-docs/docs/neutralts/doc/)\n- [IPC server](https://github.com/FranBarInstance/neutral-ipc/releases)\n- [IPC clients](https://github.com/FranBarInstance/neutral-ipc/tree/master/clients)\n- [Repository](https://github.com/FranBarInstance/neutralts)\n- [Crate](https://crates.io/crates/neutralts)\n- [PYPI Package](https://pypi.org/project/neutraltemplate/)\n- [Examples](https://github.com/FranBarInstance/neutralts-docs/tree/master/examples)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranbarinstance%2Fneutralts-docs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffranbarinstance%2Fneutralts-docs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranbarinstance%2Fneutralts-docs/lists"}