{"id":16006095,"url":"https://github.com/pfrazee/tintjs","last_synced_at":"2025-07-23T23:36:28.464Z","repository":{"id":3139331,"uuid":"4168244","full_name":"pfrazee/tintjs","owner":"pfrazee","description":"Logicless templates","archived":false,"fork":false,"pushed_at":"2012-12-19T17:27:15.000Z","size":136,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-10T10:21:37.732Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/pfrazee.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":"2012-04-28T15:51:37.000Z","updated_at":"2014-02-10T03:50:52.000Z","dependencies_parsed_at":"2022-08-19T11:41:35.025Z","dependency_job_id":null,"html_url":"https://github.com/pfrazee/tintjs","commit_stats":null,"previous_names":["pfraze/tintjs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrazee%2Ftintjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrazee%2Ftintjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrazee%2Ftintjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrazee%2Ftintjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pfrazee","download_url":"https://codeload.github.com/pfrazee/tintjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247276188,"owners_count":20912288,"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":[],"created_at":"2024-10-08T11:23:25.989Z","updated_at":"2025-04-05T02:14:18.652Z","avatar_url":"https://github.com/pfrazee.png","language":"JavaScript","readme":"TintJS\n======\n\nTint uses templates which specify an interface of variables, namespaces, and functions. That interface is used to compile a prototype for objects which build the output.\n\nThe template:\n\n```HTML\n\u003cdiv id=\"container\"\u003e\n    \u003cdiv id=\"nav\"\u003e\n        $nav{\n        \u003cul class=\"nav-list\"\u003e\n            $item() {\n                $header(label){\u003cli class=\"nav-header\"\u003e$label;\u003c/li\u003e}header;\n                $link(label, uri){\u003cli\u003e\u003ca href=\"$uri;\"\u003e$label;\u003c/a\u003e\u003c/li\u003e}link;\n            }item;\n        \u003c/ul\u003e\n        }nav;\n    \u003c/div\u003e\n    \u003cdiv id=\"content\"\u003e\n        \u003ch3\u003e$title;\u003c/h3\u003e\n        \u003ctable\u003e\n            $message(uri, author, title, date) {\n                \u003ctr\u003e\n                    \u003ctd\u003e$author;\u003c/td\u003e\n                    \u003ctd\u003e\u003ca href=\"$uri;\"\u003e$title;\u003c/a\u003e\u003c/td\u003e\n                    \u003ctd\u003e$date;\u003c/td\u003e\n                \u003c/tr\u003e\n            }message;\n        \u003c/table\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n\nThe javascript:\n\n```javascript\n// Compile the prototype\n// `templateString` contains the above template\nvar Tmpl = Tint.compile(templateString);\n\n// ...\n\n// Instantiate the builder object\nvar tmpl = new Tmpl();\n\n// nav\ntmpl.nav.item().header('Inbox');\ntmpl.nav.item().link('Inbox', '/');\ntmpl.nav.item().link('Settings', '/settings');\ntmpl.nav.item().header('Services');\ntmpl.nav.item().link('MyService', '/myservice');\n\n// content\ntmpl.title = \"Your Inbox\";\nfor (var i=0; i \u003c messages.length; i++) {\n    var message = messages[i];\n    tmpl.message(message.uri, message.author, message.summary, message.date);\n}\n\n// Generate output\nvar html = tmpl.toString();\n```\n\nYou can also extend the prototype, if you like:\n\n```javascript\n// Add a custom constructor\nvar Tmpl = new Tint.compile(templateString, function(services) {\n    this.nav.item().header('Inbox');\n    this.nav.item().link('Inbox', '');\n    this.nav.item().link('Settings', '/settings');\n    this.nav.item().header('Services');\n    for (var i=0; i \u003c services.length; i++) {\n        this.nav.item().link(services[i].name, services[i].uri);\n    }\n});\nTmpl.prototype.addMessage = function(message) {\n    this.message(message.uri, message.author, message.summary, message.date);\n};\n\n// ...\n\n// Instantiate the builder object\nvar tmpl = new Tmpl(my_services);\ntmpl.title = \"Your Inbox\";\nfor (var i=0; i \u003c messages.length; i++) {\n    tmpl.addMessage(messages[i]);\n}\nvar html = tmpl.toString();\n```\n\n## How it works\n\nTint's templates use 3 different constructs:\n\n - Blocks\n - Variables\n - Functions\n\n**Blocks** are just namespaces for parts of the template. They don't change the output.\n\n`$block_name{ whatever }block_name;`\n\n**Variables** are direct substitutions. They're replaced with whatever value they're assigned.\n\n`$variable_name;`\n\n**Functions** are blocks which can be added multiple times, and which take parameter lists.\n\n`$func_name(param1, param2) { whatever $param1; whatever $param2; }func_name;`\n\nThat's it; those building blocks are enough to generate your output. Any logic you need (like conditionals, escaping, or lists with commas on all but the last item) is added to the prototype, by you, using a language that's designed for it (Javascript).\n\n## A few additional notes\n\nFunction calls generate blocks which are stored in an array with a prefix added to the name. That is, if my template has a `$profile(username)` function, then I can access the blocks it creates at `_profile[]`. Function parameters are stored as variables with the same name as the parameter itself: `_profile[0].username`.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpfrazee%2Ftintjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpfrazee%2Ftintjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpfrazee%2Ftintjs/lists"}