{"id":18940308,"url":"https://github.com/donejs/autorender","last_synced_at":"2025-04-15T19:31:16.526Z","repository":{"id":32064076,"uuid":"35635905","full_name":"donejs/autorender","owner":"donejs","description":"Automatically render to the body or html element","archived":false,"fork":false,"pushed_at":"2020-02-11T19:02:58.000Z","size":616,"stargazers_count":4,"open_issues_count":15,"forks_count":7,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-06T10:39:33.091Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/done-autorender","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/donejs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-14T20:43:47.000Z","updated_at":"2019-06-25T11:57:35.000Z","dependencies_parsed_at":"2022-08-29T21:50:14.731Z","dependency_job_id":null,"html_url":"https://github.com/donejs/autorender","commit_stats":null,"previous_names":["stealjs/steal-can-autorender"],"tags_count":97,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donejs%2Fautorender","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donejs%2Fautorender/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donejs%2Fautorender/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donejs%2Fautorender/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/donejs","download_url":"https://codeload.github.com/donejs/autorender/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223682653,"owners_count":17185262,"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-11-08T12:21:53.105Z","updated_at":"2024-11-08T12:21:53.588Z","avatar_url":"https://github.com/donejs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/donejs/autorender.svg?branch=master)](https://travis-ci.org/donejs/autorender)\n[![npm version](https://badge.fury.io/js/done-autorender.svg)](http://badge.fury.io/js/done-autorender)\n[![Greenkeeper badge](https://badges.greenkeeper.io/donejs/autorender.svg)](https://greenkeeper.io/)\n\n# done-autorender\n\nAutomatically renders a template, either to the `\u003chtml\u003e` or `\u003cbody\u003e` elements.\n\n## Install\n\nInstall with NPM and use with StealJS:\n\n```\nnpm install done-autorender --save\n```\n\n## Use\n\ndone-autorender enables you to use a [Stache](https://canjs.com/doc/can-stache.html) template as your application entry-point (the main). done-autorender will wait for your page to be fully loaded (including all dependencies) and then will insert the template into the `\u003chead\u003e` and `\u003cbody\u003e`.  For example:\n\n### index.stache\n\n```handlebars\n\u003chtml\u003e\n\u003chead\u003e\n  \u003ctitle\u003eMy Site\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003ccan-import from=\"~/main.css\" /\u003e\n  \u003ccan-import from=\"~/routes\" /\u003e\n  \u003ccan-import from=\"~/state\" export-as=\"viewModel\" /\u003e\n\n  {{#eq(page, \"home\")}}\n    \u003ccan-dynamic-import from=\"~/home/\"\u003e\n      {{#if(./isResolved)}}\n        \u003chome-page\u003e\u003c/home-page\u003e\n      {{/if}}\n    \u003c/can-dynamic-import\u003e\n  {{/eq}}\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### index.html\n\n```html\n\u003cscript src=\"node_modules/steal/steal.js\"\n\tmain=\"app/index.stache!done-autorender\" main\u003e\u003c/script\u003e\n```\n\nThen load *index.html* in a browser. After all dependencies are loaded your *index.stache* will be rendered and inserted into the page.\n\n#### No Zone option\n\nIf you do not use SSR but still want to use `done-autorender` to bootstrap your application you can use the `no-zone` module:\n```html\n\u003cscript src=\"node_modules/steal/steal.js\"\n\tmain=\"app/index.stache!done-autorender/no-zone\" main\u003e\u003c/script\u003e\n```\n\n## API\n\n### export-as\n\nEach done-autorender application is backed by a ViewModel (such as a [DefineMap](https://canjs.com/doc/can-define/map/map.html)) that represents the state of the entire application.\n\nTo import this View Model into your application use a [can-import](https://canjs.com/doc/can-view-import.html#_can_importfrom__MODULE_NAME___) tag like so:\n\n```html\n\u003ccan-import from=\"todo-app/app\" export-as=\"viewModel\" /\u003e\n```\n\nThe __export-as__ attribute specifies that this module represents the viewModel. The `todo-app` module might look like:\n\n```js\nimport DefineMap from \"can-define/map/map\";\nimport route from \"can-route\";\nimport RoutePushstate from \"can-route-pushstate\";\n\nroute.urlData = new RoutePushstate();\nroute.register(\"{page}\", { page: \"home\" });\n\nconst AppViewModel = DefineMap.extend(\"AppViewModel\", {\n\tpage: \"string\"\n});\n\nexport default AppViewModel;\n```\n\nInternally done-autorender will create a new instance of this DefineMap and set it as the [route.data](https://canjs.com/doc/can-route.data.html).\n\n### route-data\n\nSpecifies an alternative property on the [ViewModel](https://github.com/donejs/autorender#export-as) to use as the [route data](https://canjs.com/doc/can-route.data.html).\n\n#### Using the default route.data\n\nStarting in [can-route 4.4.0](https://github.com/canjs/can-route/releases/tag/v4.4.0) you can more easily use the default `route.data`, as it is a DefineMap.\n\nTo use this pattern, first add a property on your ApplicationViewModel that is the route.data property:\n\n```js\nimport DefineMap from \"can-define/map/map\";\nimport route from \"can-route\";\nimport RoutePushstate from \"can-route-pushstate\";\n\nroute.urlData = new RoutePushstate();\nroute.register(\"{page}\", { page: \"home\" });\n\nconst AppViewModel = DefineMap.extend(\"AppViewModel\", {\n\trouteData: {\n\t\tdefault: () =\u003e route.data\n\t}\n});\n\nexport default AppViewModel;\n```\n\nNow, in your index.stache, set the __route-data__ attribute to this property name:\n\n```handlebars\n\u003ccan-import from=\"todo-app/app\" export-as=\"viewModel\" route-data=\"routeData\" /\u003e\n```\n\nFrom here you can you use the properties on `route.data` the same way you can any other ViewModel. Here's a fuller example template:\n\n```handlebars\n\u003chtml\u003e\n\u003chead\u003e\n  \u003ctitle\u003e{{routeData.page}} | My App\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003ccan-import from=\"todo-app/app\" export-as=\"viewModel\" route-data=\"routeData\" /\u003e\n\n  \u003ch1\u003eMy App!\u003c/h1\u003e\n  \u003ch2\u003e{{routeData.page}}\u003c/h2\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### Using a custom Type\n\nSince __route-data__ allows you to specify any property on your ViewModel, one option is to use a custom type, such as a DefineMap. This allows you to separate properties that you want attached to the route from other properties on the ViewModel that you do not.\n\nBelow is an example AppViewModel module:\n\n```js\nimport DefineMap from \"can-define/map/map\";\nimport route from \"can-route\";\nimport RoutePushstate from \"can-route-pushstate\";\n\nroute.urlData = new RoutePushstate();\nroute.register(\"{page}\", { page: \"home\" });\n\nconst MyRouteData = DefineMap.extend(\"MyRouteData\", {\n\tpage: \"string\"\n});\n\nconst AppViewModel = DefineMap.extend(\"AppViewModel\", {\n\trouteData: {\n\t\tDefault: MyRouteData\n\t}\n});\n\nexport default AppViewModel;\n```\n\nAnd then to use it, set it as the __route-data__ attribute:\n\n```handlebars\n\u003chtml\u003e\n\u003chead\u003e\n  \u003ctitle\u003e{{routeData.page}} | My App\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003ccan-import from=\"todo-app/app\" export-as=\"viewModel\" route-data=\"routeData\" /\u003e\n\n  \u003ch1\u003eMy App!\u003c/h1\u003e\n  \u003ch2\u003e{{routeData.page}}\u003c/h2\u003e\n  \u003cp\u003eThis is coming from the \u003cstrong\u003eMyRouteData\u003c/strong\u003e observable!\u003c/p\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Debugging\n\nIn development mode, [can-zone/debug](https://canjs.com/doc/can-zone/debug.html) is enabled to provide debugging information in the case where the Zone times out and the app is never attached to the page.\n\nYou can control the timeout by setting the `data-autorender-timeout` attribute on the steal script tag (note that `data-` is optional here) like so:\n\n```html\n\u003cscript src=\"./node_modules/steal/steal.js\"\n\tdata-autorender-timeout=\"1000\"\u003e\u003c/script\u003e\n```\n\nThe __timeout__ is specified in milliseconds; in the above example it is 1 second. By default the zone will timeout after __5000 milliseconds__ (5 seconds).\n\nAfter the Zone has timed out the console will print out stack traces of code that failed to complete. Use these stack traces to figure out what caused reattachment to fail and fix anything that can be fixed (by, for example, using [Zone.ignore](https://canjs.com/doc/can-zone.ignore.html)). These information looks like:\n\n![debug stack traces](https://user-images.githubusercontent.com/361671/33093932-62001f4a-cecc-11e7-8cbc-376789a43781.png)\n\n#### Break on timeout\n\nAdditionally you can choose to have a `debugger;` breakpoint that is hit *after* the Zone times out. This allows you to more easily figure out which code is still running and see if something can be done about it.\n\nEnable this by setting the `data-autorender-debug-break` option on the steal script tag like so:\n\n```html\n\u003cscript src=\"./node_modules/steal/steal.js\"\n\tdata-autorender-debug-break\u003e\u003c/script\u003e\n```\n\nThis is a boolean attribute and doesn't need a value. Instead of logging stack traces you will get a breakpoint from which you can look back in the call stack and inspect the reason why the code continued to run past the timeout.\n\n![break on timeout](https://user-images.githubusercontent.com/361671/33095278-1628ab46-ced1-11e7-96e7-bf25e9cc2853.png)\n\n\n#### can-view-model\n\nIf you install [can-view-model](https://github.com/canjs/can-view-model) you can use it to access the Application ViewModel like so:\n\n```js\nvar canViewModel = require(\"can-view-model\");\n\nvar appVM = canViewModel(document.documentElement);\n```\n\n### Keeping elements in the DOM\n\nBy default done-autorender removes all elements from the `\u003chead\u003e` and `\u003cbody\u003e` and replaces them with the elements from the template. This is to facilitate use with [done-ssr](https://github.com/donejs/done-ssr) which will have duplicated content.\n\nSome times, especially if not using done-ssr, you might want to keep some elements that are in your HTML but not your stache template. Use the __data-keep__ property and done-autorender will leave them alone:\n\n```html\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cmeta name=\"some-prop\" content=\"some-value\" data-keep\u003e\n\u003c/head\u003e\n\u003c/html\u003e\n```\n\n### connectedCallback\n\ndone-autorender supports the `connectedCallback` lifecycle hook, and it works the same way [as in can-component](https://canjs.com/doc/can-component/connectedCallback.html).\n\nThe callback function receives the `document.documentElement` (aka the `\u003chtml\u003e` element) as its only argument. You can use `this.listenTo` to listen to changes in the DefineMap's properties, or to listen to events in the DOM.\n\nThe callback should return a function that will be called when the document is torn down, where cleanup should be done.\n\nThe following is an example counter that is implemented using connectedCallback:\n\n```js\nimport DefineMap from \"can-define/map/map\";\nimport route from \"can-route\";\n\nexport default DefineMap.extend({\n\tcount: {\n\t\ttype: 'number',\n\t\tdefault: 0,\n\t\tserialize: false\n\t},\n\n\tconnectedCallback(el) {\n\t\tconst button = el.querySelector(\"#increment\");\n\n\t\tthis.listenTo(button, \"click\", () =\u003e {\n\t\t\tthis.count++;\n\t\t});\n\n\t\treturn () =\u003e this.stopListening();\n\t}\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonejs%2Fautorender","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonejs%2Fautorender","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonejs%2Fautorender/lists"}