{"id":17117757,"url":"https://github.com/anderspitman/tuplates-js","last_synced_at":"2025-10-07T02:07:35.406Z","repository":{"id":81835978,"uuid":"225057092","full_name":"anderspitman/tuplates-js","owner":"anderspitman","description":"Commit working code; not templates","archived":false,"fork":false,"pushed_at":"2019-12-31T17:45:27.000Z","size":11,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-13T10:37:18.061Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/anderspitman.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-30T18:59:14.000Z","updated_at":"2020-12-14T06:05:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"c82d7ac8-f8e7-4a72-8c20-f55b958824b3","html_url":"https://github.com/anderspitman/tuplates-js","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/anderspitman/tuplates-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderspitman%2Ftuplates-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderspitman%2Ftuplates-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderspitman%2Ftuplates-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderspitman%2Ftuplates-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anderspitman","download_url":"https://codeload.github.com/anderspitman/tuplates-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderspitman%2Ftuplates-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278708004,"owners_count":26031932,"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-07T02:00:06.786Z","response_time":59,"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-10-14T17:52:37.955Z","updated_at":"2025-10-07T02:07:35.375Z","avatar_url":"https://github.com/anderspitman.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\n\nTale as old as time. I started developing a new static site for\n[patchbay.pub](https://patchbay.pub/). At first it was just a single page. But\nof course eventually I needed to add a header. And of course HTML doesn't have\na way to\n[include another HTML file](https://css-tricks.com/the-simplest-ways-to-handle-html-includes/),\nbecause why would that be useful?\n\ntuplates is a simple way to template your static sites, without creating a\ndependency on your templating tool. Rather than replacing your template tags,\nit works by replacing lines between your template tags. This means that both\nyour template and code live together in your files. When you need to make a \nchange, you update the fragment and re-run tuplates, and it replaces the old\ncode. This way you can check your actual code into source control, rather than\nyour templates.\n\nThe name comes from \"update templates\".\n\n\n# Installation\n\n```bash\nnpm install -g tuplates\n```\n\n# Usage\n\nCreate a `tuplates` directory containing your fragments as files. You can\nname them whatever you want.\n\n```\nproject_directory/\n  index.html\n  index.js\n  tuplates/\n    header.html\n    footer.html\n    data.txt\n```\n\nInsert tuplate tags as comments in your code:\n\n\u003c!-- tuplate_start(index.html.md) --\u003e\n```html\n\u003c!-- index.html --\u003e\n\u003c!doctype html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /\u003e\n    \u003ctitle\u003etuplates\u003c/title\u003e\n\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003c!-- tuplate_start(header.html) --\u003e\n    \u003c!-- tuplate_end() --\u003e\n\n    \u003cmain\u003e\n      \u003ch1\u003eMy Awesome Content\u003c/h1\u003e\n    \u003c/main\u003e\n\n    \u003c!-- tuplate_start(footer.html) --\u003e\n    \u003c!-- tuplate_end() --\u003e\n  \u003c/body\u003e\n\n\u003c/html\u003e\n```\n\n\u003c!-- tuplate_end() --\u003e\n\n\u003c!-- tuplate_start(index.js.md) --\u003e\n```javascript\n// index.js\nconsole.log(\"Hi there\");\n\n// tuplate_start(data.js)\n// tuplate_end()\n\nconsole.log(data);\n```\n\n\u003c!-- tuplate_end() --\u003e\n\nRun the `tuplates` command in the directory above the `tuplates` directory.\nIt will walk the directory and replace the lines between the tags with the\ntuplates.\n\nAfter running once, the source files look like this:\n\n```html\n\u003c!-- index.html --\u003e\n\u003c!doctype html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /\u003e\n    \u003ctitle\u003etuplates\u003c/title\u003e\n\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003c!-- tuplate_start(header.html) --\u003e\n    \u003c!-- tuplates/header.html --\u003e\n    \u003cdiv class='header'\u003e\n      \u003ch1\u003eMy Awesome Header\u003c/h1\u003e\n    \u003c/div\u003e\n    \n    \n    \u003c!-- tuplate_end() --\u003e\n\n    \u003cmain\u003e\n      \u003ch1\u003eMy Awesome Content\u003c/h1\u003e\n    \u003c/main\u003e\n\n    \u003c!-- tuplate_start(footer.html) --\u003e\n    \u003c!-- tuplates/footer.html --\u003e\n    \u003cdiv class='footer'\u003e\n      \u003ch1\u003eAwesome Footer\u003c/h1\u003e\n    \u003c/div\u003e\n    \n    \u003c!-- tuplate_end() --\u003e\n  \u003c/body\u003e\n\n\u003c/html\u003e\n```\n\n```javascript\n// index.js\nconsole.log(\"Hi there\");\n\n// tuplate_start(data.js)\n// tuplates/data.js\nconst data = {\n  a: 1,\n  b: 2,\n  c: 3,\n};\n\n// tuplate_end()\n\nconsole.log(data);\n```\n\nIf you re-run it again, the result is the same, even though there's already\ncode between the tuplate tags. It simply replaces whatever is in there (if\nthere is anything).\n\nNote that this README was partially generated with tuplates (see the Markdown\ntuplates in this project's `tuplates` directory). Unfortunately it takes some\nmanual intervention to work, in part because tuplates doesn't currently support\nnesting.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanderspitman%2Ftuplates-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanderspitman%2Ftuplates-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanderspitman%2Ftuplates-js/lists"}