{"id":13793376,"url":"https://github.com/marcodpt/tint","last_synced_at":"2025-04-10T02:26:23.608Z","repository":{"id":111253068,"uuid":"534183952","full_name":"marcodpt/tint","owner":"marcodpt","description":"A natural template engine for the HTML DOM","archived":false,"fork":false,"pushed_at":"2023-09-27T22:04:26.000Z","size":1273,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T03:53:19.152Z","etag":null,"topics":["dom","dom-templating","handlebars","html","html-template","hyperapp","javascript","logic-less","mustache","natural","rivets","spa","template","template-engine","template-language","transparency","virtual-dom","vuejs","xml","xml-template"],"latest_commit_sha":null,"homepage":"https://marcodpt.github.io/tint/","language":"JavaScript","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/marcodpt.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":"2022-09-08T11:39:01.000Z","updated_at":"2024-09-15T10:21:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"b85b1992-363c-4b83-babe-2abb075aab7a","html_url":"https://github.com/marcodpt/tint","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcodpt%2Ftint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcodpt%2Ftint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcodpt%2Ftint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcodpt%2Ftint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcodpt","download_url":"https://codeload.github.com/marcodpt/tint/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248143704,"owners_count":21054826,"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":["dom","dom-templating","handlebars","html","html-template","hyperapp","javascript","logic-less","mustache","natural","rivets","spa","template","template-engine","template-language","transparency","virtual-dom","vuejs","xml","xml-template"],"created_at":"2024-08-03T23:00:20.052Z","updated_at":"2025-04-10T02:26:23.581Z","avatar_url":"https://github.com/marcodpt.png","language":"JavaScript","readme":"# ![](assets/favicon.ico) Tint\nA natural template engine for the HTML DOM. \n\n[Docs](https://marcodpt.github.io/tint/)\n\n - takes valid `HTML` as input.\n - converts the result to any \n[hyperscript](https://github.com/hyperhype/hyperscript)\nfunction you want to use.\n - layouts completely separate from javascript logic.\n - works with all javascript frameworks that support\n[hyperscript](https://github.com/hyperhype/hyperscript).\n - you can use the template as a server-side rendered version of your app.\n - you can use a regular HTML file as a single file component without ANY\njavascript build tools.\n - [hyperscript](https://github.com/hyperhype/hyperscript) frameworks can be\nused by any team of designers or people with no javascript knowledge.\n - the template syntax allow very simple and elegant templates without\nrepeat yourself.\n - see also [Merlin](https://github.com/marcodpt/merlin), a tint based framework.\n\n## Showcase\nThe classic TODO app, with an initial server-rendered state.\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cscript type=\"module\"\u003e\n      import compile from \"https://cdn.jsdelivr.net/gh/marcodpt/tint/template.js\"\n      const render = compile(document.getElementById(\"app\"))\n\n      const state = {\n        todos: [\n          \"read a book\",\n          \"plant a tree\"\n        ],\n        value: \"\",\n        AddTodo: () =\u003e {\n          state.todos.push(state.value)\n          state.value = \"\"\n          render(state)\n        },\n        NewValue: ev =\u003e {\n          state.value = ev.target.value\n        }\n      }\n\n      render(state)\n    \u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cmain id=\"app\"\u003e\n      \u003ch1\u003eTo do list\u003c/h1\u003e\n      \u003cinput type=\"text\" value:=\"value\" oninput:=\"NewValue\"\u003e\n      \u003cul\u003e\n        \u003cli each:=\"todos\" text:\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n      \u003cbutton onclick:=\"AddTodo\"\u003eNew!\u003c/button\u003e\n    \u003c/main\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nResult: \n```html\n\u003cmain id=\"app\"\u003e\n  \u003ch1\u003eTo do list\u003c/h1\u003e\n  \u003cinput type=\"text\" value=\"\"\u003e\n  \u003cul\u003e\n    \u003cli\u003eread a book\u003c/li\u003e\n    \u003cli\u003eplant a tree\u003c/li\u003e\n  \u003c/ul\u003e\n  \u003cbutton\u003eNew!\u003c/button\u003e\n\u003c/main\u003e\n```\n\nIt looks like a normal template engine, but internally compiles the template to:\n```js\n({ todos, value, NewValue, AddTodo }) =\u003e\n  h(\"main\", {}, [\n    h(\"h1\", {}, text(\"To do list\")),\n    h(\"input\", { type: \"text\", oninput: NewValue, value }),\n    h(\"ul\", {},\n      todos.map((todo) =\u003e h(\"li\", {}, text(todo)))\n    ),\n    h(\"button\", { onclick: AddTodo }, text(\"New!\")),\n  ])\n```\nwhere `h` and `text` can be any hyperscript function you want to use.\n\nYou can use it with these frameworks:\n\n- [Merlin](https://github.com/marcodpt/merlin)\n- [Hyperapp](https://marcodpt.github.io/tint/lib/hyperapp.html)\n- [Superfine](https://marcodpt.github.io/tint/lib/superfine.html)\n- [Mithril](https://marcodpt.github.io/tint/lib/mithril.html)\n- [Preact](https://marcodpt.github.io/tint/lib/preact.html)\n\nWith your help, we can grow this list and improve the work done on already\nsupported frameworks.\n\nWith a little trick, you can even render your application on the server side,\nwithout the complications of the build steps.\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cscript type=\"module\"\u003e\n      import compile from \"https://cdn.jsdelivr.net/gh/marcodpt/tint/template.js\"\n      const app = document.getElementById(\"app\")\n      const render = compile(app)\n\n      const state = {\n        todos: Array.from(app.querySelectorAll('li')).map(e =\u003e e.textContent),\n        value: \"\",\n        AddTodo: () =\u003e {\n          state.todos.push(state.value)\n          state.value = \"\"\n          render(state)\n        },\n        NewValue: ev =\u003e {\n          state.value = ev.target.value\n        }\n      }\n\n      render(state)\n    \u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cmain id=\"app\"\u003e\n      \u003ch1\u003eTo do list\u003c/h1\u003e\n      \u003cinput type=\"text\" value:=\"value\" oninput:=\"NewValue\"\u003e\n      \u003cul\u003e\n        \u003cli each:=\"todos\" text:\u003eread a book\u003c/li\u003e\n        \u003cli not:\u003eplant a tree\u003c/li\u003e\n      \u003c/ul\u003e\n      \u003cbutton onclick:=\"AddTodo\"\u003eNew!\u003c/button\u003e\n    \u003c/main\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n- [Example in action](https://marcodpt.github.io/tint/samples/ssr_dynamic.html)\n- [Static HTML rendered by the server](https://marcodpt.github.io/tint/samples/ssr_static.html)\n\nWhat have you achieved:\n - The happiness of designers who can write in plain html.\n - The happiness of customers, which has a very fast and interactive\napplication, rendered on the server side, search engine friendly and at the\nsame time as dynamic as necessary.\n - The happiness of developers, who don't need complicated settings for the\n build steps, they can use normal html files to create single file components\nand they can use any hyperscript framework they want.\n\nTo celebrate the widespread happiness, how about taking a look at the\n[documentation](https://marcodpt.github.io/tint/).\n\n## [Docs](https://marcodpt.github.io/tint/)\nTo generate the docs and create a server for tests.\n\n```\nmdbook serve\n```\n\n## Deno support\nTesting `tint` in `deno`\n```\ndeno test --allow-read tests/deno.js\n```\n\nCurrently this is the only suported and tested version (deno_dom@v0.1.38)\n```js\nimport {DOMParser} from \"https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts\";\n\nconst parser = new DOMParser()\nconst document = parser.parseFromString(\n  Deno.readTextFileSync('path/to/file.html'),\n  \"text/html\"\n)\n```\n\n## Philosophy\n - Separation: Functions and data transformations belong in javascript, design\nand visual presentation to the html and css, and the data belongs to the database.\n - Designers and people with no javascript knowledge should understand it\nand quickly become productive.\n - Templates must be valid `XML`/`HTML` that can be inserted into a\n`template` tag or anywhere in the DOM.\n - It must not conflict with other template engines and frameworks.\n - Each layout should be written only once, without repetition.\n - Simplicity matters.\n - Elegant syntax is important.\n\n## Contributing\nEverything within this documentation is tested \n[here](https://marcodpt.github.io/tint/tests/).\nAnd it will always like this. Any changes to the documentation,\nany contributions MUST be present in the tests.\n\nIf the tests do not pass in your browser, if you find any bugs, please raise\nan issue.\n\nAny changes must be within the philosophy of this project.\n\nIt's a very simple project. Any contribution is greatly appreciated.\n\n## Influences and thanks\nThis work is hugely influenced by these amazing template engines and frameworks:\n - [mustache](https://mustache.github.io/mustache.5.html)\n - [transparency](https://github.com/leonidas/transparency)\n - [thymeleaf](https://www.thymeleaf.org/)\n - [handlebars](https://handlebarsjs.com/)\n - [jinja](https://jinja.palletsprojects.com/en/3.1.x/)\n - [tera](https://tera.netlify.app/docs)\n - [vue](https://vuejs.org/)\n - [superfine](https://github.com/jorgebucaran/superfine)\n - [hyperapp](https://github.com/jorgebucaran/hyperapp)\n - [rivets](http://rivetsjs.com/docs/reference/)\n - [knockout](https://knockoutjs.com/documentation/introduction.html)\n\nA huge thank you to all the people who contributed to these projects.\n","funding_links":[],"categories":["Utilities"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcodpt%2Ftint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcodpt%2Ftint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcodpt%2Ftint/lists"}