{"_id":"@apicart/brackets","_rev":"2-5fe77a466489cb0ef448c4e2aedbdfc9","name":"@apicart/brackets","dist-tags":{"latest":"1.0.0-alpha2"},"versions":{"1.0.0-alpha1":{"name":"@apicart/brackets","version":"1.0.0-alpha1","description":"Small, flexible, easy to use, component-oriented javascript template engine.","main":"dist/braces.min.js","unpkg":"dist/braces.min.js","jsdelivr":"dist/braces.min.js","scripts":{"dev":"rollup -w src -c scripts/dev.js","build:prod":"rollup -c scripts/prod.js","build:prod-min":"rollup -c scripts/prod.min.js","build:test-stack":"rollup -c scripts/test-stack.js","lint":"eslint src/","lint:fix":"eslint src/ --fix","test:chrome":"karma start --single-run --browsers ChromeHeadless karma.conf.js"},"repository":{"type":"git","url":"git+https://github.com/apicart/brackets.git"},"keywords":["brackets","apicart","template engine"],"author":{"name":"Vladimír Macháček"},"license":"MIT","bugs":{"url":"https://github.com/apicart/brackets/issues"},"homepage":"https://github.com/apicart/brackets/#readme","devDependencies":{"chai":"^4.1.2","eslint":"^5.12.0","karma":"^2.0.5","karma-chai":"^0.1.0","karma-chrome-launcher":"^2.2.0","karma-mocha":"^1.3.0","mocha":"^5.2.0","rollup":"^1.1.0","rollup-plugin-banner":"^0.2.0","rollup-plugin-uglify":"^6.0.1"},"licenseText":"MIT License\n\nCopyright (c) 2019 Apicart\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"@apicart/brackets@1.0.0-alpha1","dist":{"shasum":"7aacc985b2c8b44fa4efcf6d6fc7ee6f586720da","tarball":"https://registry.npmjs.org/@apicart/brackets/-/brackets-1.0.0-alpha1.tgz","integrity":"sha512-3vxM5zYXRUHCuINUT73szKmYdEZC0tB/9gHwH8yppN4De+ZoLoQmRRzHzgTPnwr2SrXs1z2tKeTmq8u2227kjA==","fileCount":31,"unpackedSize":86887,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcQKbeCRA9TVsSAnZWagAA4AgQAI9NQ2ubtWoh2LjZxeav\n/RgQlgf9VkiQMu9r4/NRTJojlhnLLvz3aEQSlOaK20yUrURRX4g/x2MIoJzL\naFY/IjSeGGTL1Ahw9MVwbgvTzG7uRGotC0Y9t4BI6LhxP6XIts7r5m1gWYBj\n0xZ4UiccfOlKjxQo72JbGAl8tJl7MGAJW8Va3s5iXrFUvZbOHgvBZdE1EerE\nOb5H+HQ7KoCstao8dUjtTPKC6VRrd8WFrU9S+2xdawx2rnLRiAjlrnne3zat\nHt6M1UODH5v7en8685ylEilVJsbUnhh0wudV/8d+QMnlGH8AHIq4QDgZ/vT7\nB7QaRdduHJV9BrRuCuYPqP9HCkeONQYS8L5+GWwi5sG9O4FvXnfEtpavxjTe\nzSEZFEvso8LE8mzwhhWW5NTg6Hl6AsH31lfaxreQpouhuVzh6Uk7CxPFHYlJ\nRFDcu/r2yetB7LaogCa1C1zvNlNIuk+msVBiWD7UbATw6/Op45uOquG0aWtE\niUUVDudFQpS/KQyNvj2kiEoaA078qgcHg5TK491Wlk3WypIXJM3D+vCiwmcE\nTyZ8TPr3uyVygPhPrnPxqJD3klXtrjYNC/JisR99bzz3XQrlIdWab53wT2e1\nHQ39reUURMC5fNfsjm0+ovhADjQFBd8468pWAfkblJ82F58mpzacfHRGLqqO\noeQ/\r\n=KylC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCLrTa89HoNKBUTKc//42UC74N54EPbFsrCjUe4F0QkrwIhAL7sumX574Gxyl7HsNFzfivkcvWe03bdUgVA1DF4p3EY"}]},"maintainers":[{"name":"apicart","email":"tools@apicart.net"}],"_npmUser":{"name":"apicart","email":"tools@apicart.net"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/brackets_1.0.0-alpha1_1547740893878_0.07693003313227065"},"_hasShrinkwrap":false},"1.0.0-alpha2":{"name":"@apicart/brackets","version":"1.0.0-alpha2","description":"Small, flexible, easy to use, component-oriented javascript template engine.","main":"dist/brackets.min.js","unpkg":"dist/brackets.min.js","jsdelivr":"dist/brackets.min.js","scripts":{"dev":"rollup -w src -c scripts/dev.js","build":"rollup -c scripts/prod.js && rollup -c scripts/prod.min.js && rollup -c scripts/test-stack.js","build:prod":"rollup -c scripts/prod.js","build:prod-min":"rollup -c scripts/prod.min.js","build:test-stack":"rollup -c scripts/test-stack.js","lint":"eslint src/","lint:fix":"eslint src/ --fix","test:chrome":"karma start --single-run --browsers ChromeHeadless karma.conf.js"},"repository":{"type":"git","url":"git+https://github.com/apicart/brackets.git"},"keywords":["brackets","apicart","template engine"],"author":{"name":"Vladimír Macháček"},"license":"MIT","bugs":{"url":"https://github.com/apicart/brackets/issues"},"homepage":"https://github.com/apicart/brackets/#readme","devDependencies":{"chai":"^4.1.2","eslint":"^5.12.0","karma":"^2.0.5","karma-chai":"^0.1.0","karma-chrome-launcher":"^2.2.0","karma-mocha":"^1.3.0","mocha":"^5.2.0","rollup":"^1.1.0","rollup-plugin-banner":"^0.2.0","rollup-plugin-uglify":"^6.0.1"},"licenseText":"MIT License\n\nCopyright (c) 2019 Apicart\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"@apicart/brackets@1.0.0-alpha2","dist":{"shasum":"4a9acd816107051f9d0aa01acc0ace7561832f77","tarball":"https://registry.npmjs.org/@apicart/brackets/-/brackets-1.0.0-alpha2.tgz","integrity":"sha512-rkYsyV0SiJGGH63YkBsoIGpc2fXX1NhfrxXlCxXcrZQXOffl7yb9pGwO76/6tvq70SOj+I/ckg9gl50GL+KmwA==","fileCount":31,"unpackedSize":92886,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcca3GCRA9TVsSAnZWagAA1AcP/0FYO7H2s2ULpqOVpzDU\n0K7XqGaH7VqZ8tdcB+pYH/g+bv6KHuagOsCu99RsqPzGPOjn6PMvT3kX9nqL\naWKHATd05pEAmgmV1lUuoinzOlBGPifA75EgrWA4VM6qtlYHT3DW6qor6uNa\n90gCa/k5lKwPzfLNTyvCkdRbRuYSmsJPgulznr6SM7FcaTWyW9y8W1P2Jurd\nMmTDjaSqmLLmP1YBWaPzNaj0/vz7we3MJPyMfJyiNBFkCXPDiRKKQ0WHTjbu\nC34WHISzHf+q5bepl76yedlc8RRhNArzkYWddUCnaCVSbu9NKuUtxslOK+/C\nzfQ2dxX4chgb/YTOEXlxR8lYhe1YCsaGTxG8zknQZUanrYweKI45eTTEPT/e\nH45XNWBr4QLazpzNykotkq/ZTifyCsptTVFrJjkk4d0Tc9Zz4F2FRYffdw1U\nZmQEB9Oc+T2F836Hf7hFLN0z1G/nlw/d/iMNRRBqWwPmeVgX7cAUn01zJegI\n2ILpF7NcRNGEj7ddmt9+XNaG/dGA8rnHqyP9VfRY9FWPMrV81BRpAiEGrcdB\ndUxjSZ5Hx+6zU6O2Iir4dQd/8OT1LyJJJODb3y1BhD2C1Rm7etH3R0aqSFqW\nshlyQQ3xhVd+QeqU5FR2wqe419rUGZPQMazerm/zNlLmWb0nFZJMZC5KN4a0\n5H9Y\r\n=ky/L\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD9Q1Jsq2TZ5SwffJU9azTKOq163sStGJCPooFpU5mUPgIgMY1bZxtbPQ8cBoJCsw7CZAyDdfC+CuKnzIfJFbw92gE="}]},"maintainers":[{"name":"apicart","email":"tools@apicart.net"}],"_npmUser":{"name":"apicart","email":"tools@apicart.net"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/brackets_1.0.0-alpha2_1550953925695_0.8622533809972162"},"_hasShrinkwrap":false}},"time":{"created":"2019-01-17T16:01:33.677Z","1.0.0-alpha1":"2019-01-17T16:01:34.009Z","modified":"2022-04-04T14:34:57.104Z","1.0.0-alpha2":"2019-02-23T20:32:05.853Z"},"maintainers":[{"name":"apicart","email":"tools@apicart.net"}],"description":"Small, flexible, easy to use, component-oriented javascript template engine.","homepage":"https://github.com/apicart/brackets/#readme","keywords":["brackets","apicart","template engine"],"repository":{"type":"git","url":"git+https://github.com/apicart/brackets.git"},"author":{"name":"Vladimír Macháček"},"bugs":{"url":"https://github.com/apicart/brackets/issues"},"license":"MIT","readme":"<h1 align=\"center\">\n\t<img src=\"https://github.com/apicart/brackets/blob/master/logo.png\">\n\t<br>\n\t<a href=\"https://travis-ci.org/apicart/brackets\" target=\"blank\" rel=\"noopener\">\n\t\t<img alt=\"\" src=\"https://travis-ci.org/apicart/brackets.svg?branch=master\">\n\t</a>\n\t<a href=\"https://www.npmjs.com/package/@apicart/brackets\" target=\"blank\" rel=\"noopener\">\n\t\t<img alt=\"\" src=\"https://img.shields.io/npm/v/@apicart/brackets.svg\">\n\t</a>\n\t<a href=\"https://www.npmjs.com/package/@apicart/brackets\" target=\"blank\" rel=\"noopener\">\n\t\t<img alt=\"\" src=\"https://img.shields.io/npm/dt/@apicart/brackets.svg\">\n\t</a>\n\t<a href=\"https://www.jsdelivr.com/package/npm/@apicart/brackets\" target=\"blank\" rel=\"noopener\">\n\t\t<img src=\"https://data.jsdelivr.com/v1/package/npm/@apicart/brackets/badge\" alt=\"\">\n\t</a>\n\t<a href=\"https://github.com/apicart/brackets/blob/master/LICENSE\" target=\"blank\" rel=\"noopener\">\n\t\t<img alt=\"\" src=\"https://img.shields.io/github/license/apicart/brackets.svg\">\n\t</a>\n</h1>\n\n- Small, flexible, easy to use, component-oriented javascript template engine.\n- ✅ **14 Kb minified (6 Kb Gzipped)**\n- ✅ Supports IE 10 +\n- ✅ [TRY IT ON CODEPEN](https://codepen.io/apicart/pen/OraYJj)\n\n**Content**\n- [Get Started](https://github.com/apicart/brackets/blob/master/readme.md#getting-started)\n- [Cache](https://github.com/apicart/brackets/blob/master/readme.md#cache)\n- [Templates](https://github.com/apicart/brackets/blob/master/readme.md#templates)\n- [Events](https://github.com/apicart/brackets/blob/master/readme.md#events)\n- [Event Handlers](https://github.com/apicart/brackets/blob/master/readme.md#event-handlers)\n- [Filters](https://github.com/apicart/brackets/blob/master/readme.md#filters)\n- [Macros](https://github.com/apicart/brackets/blob/master/readme.md#macros)\n- [Components](https://github.com/apicart/brackets/blob/master/readme.md#components)\n- [Complete Components Configuration](https://github.com/apicart/brackets/blob/master/readme.md#complete-components-configuration)\n- [Complete Rendering Configuration](https://github.com/apicart/brackets/blob/master/readme.md#complete-rendering-configuration)\n- [Configuration Reserved Keywords](https://github.com/apicart/brackets/blob/master/readme.md#configuration-reserved-keywords)\n- [Rendering Instances](https://github.com/apicart/brackets/blob/master/readme.md#rendering-instances)\n- [Security](https://github.com/apicart/brackets/blob/master/readme.md#security)\n\n\n## Installation\nBrackets are under development and therefore they are not yet available on npm. You can use the cdn link.\n\n**CDN**\n```html\n<!-- Master version from Github -->\n<script src=\"https://cdn.jsdelivr.net/gh/apicart/brackets/dist/brackets.min.js\"></script>\n\n<!-- v1.0.0-alpha1 from jsdelivr.net -->\n<script src=\"https://cdn.jsdelivr.net/npm/@apicart/brackets@1.0.0-alpha1/dist/brackets.min.js\" integrity=\"sha256-TxTeKLp4t4vZVi131XgcBwX9LJfTg1N9zlMxPE2XE0o=\" crossorigin=\"anonymous\"></script>\n```\n\n**Npm & Yarn**\n\n```\nnpm install @apicart/brackets\n\nyarn add @apicart/brackets\n```\n\n## Getting Started\nLet's start with a simple example. We will render a text stored in the data object into the `#app` element. Notice that variables have dollar sign `$` before the name.\n\n```html\n<div id=\"app\">\n\t{{$text}}\n</div>\n<script>\nBrackets.render({\n\tel: '#app',\n\tdata: {\n\t\ttext: \"I ❤️ Brackets!\"\n\t}\n});\n</script>\n```\n\n```\nI ❤️ Brackets!\n```\n\n## Cache\nCache speed's up the rendering process. There are two types of cache. Functions cache and results cache.\n- **Results cache**: Caches the whole content of the rendered instance. This cache is good for templates where the variables are not changed. You can enable it by setting the `resultCacheEnabled` to true.\n- **Functions cache**: Caches only the generated template function not the result of the rendering process. Is good for templates that are used multiple times and its variables needs to be changed dynamically. You can enable it by adding the template `cacheKey` name.\n\n```html\n<div id=\"app\">\n\t{{$text}}\n</div>\n<script>\nBrackets.render({\n\tel: '#app',\n\tcacheKey: 'test',\n\tresultCacheEnabled: true,\n\tdata: {\n\t\ttext: \"I ❤️ Brackets!\"\n\t}\n});\n</script>\n```\n\n## Templates\nThe template you want to render can be provided in a multiple ways. In the example above, the template was loaded from the target element `#app`. \n\nAnother way to provide the template is setting it directly as a text in the template parameter.\n\n```html\n<div id=\"app\"></div>\n<script>\nBrackets.render({\n\tel: '#app',\n\tcacheKey: 'test',\n\tdata: {\n\t\ttext: \"I ❤️ Brackets!\"\n\t},\n\ttemplate: '{{$text}}'\n});\n</script>\n```\n\nTemplate parameter can also receive an id selector `#elementId`. If so, the template will be loaded from the given element (you shouldn't load complicated templates from a typical html elements because it can cause unexpected errors, we recommend to use `<template>...</template>` or `<script type=\"text/plain\">...</script>` elements as template providers).\n\n```html\n<div id=\"app\"></div>\n<template id=\"template\">\n\t{{$text}}\n</template>\n<script>\nBrackets.render({\n\tel: '#app',\n\tcacheKey: 'test',\n\tdata: {\n\t\ttext: \"I ❤️ Brackets!\"\n\t},\n\ttemplate: '#template'\n});\n</script>\n```\n\nIn case you need some condition for providing a correct template (for example for A/B testing) you can use a function that returns the right template based on given conditions. This function is called only once and can return a template string or a selector as in examples above. You should not change any parameters or data inside this function, because the code can become unclear.\n\n```html\n<div id=\"app\"></div>\n<template id=\"templateA\">A</template>\n<template id=\"templateB\">B</template>\n<script>\nBrackets.render({\n\tel: '#app',\n\tcacheKey: 'test',\n\tdata: {\n\t\tversion: 'a',\n\t\ttext: \"I ❤️ Brackets!\"\n\t},\n\ttemplate: function () {\n\t\treturn this.version === 'a' ? '#templateA' : '#templateB';\n\t}\n});\n</script>\n```\n\n## Events\nDuring the whole rendering process, there are triggered two events. \n- Before render (beforeRender) - this event is triggered before the whole rendering process starts\n- After render (afterRender) - this event is triggered after the rendering process is complete\n\nBoth events triggers methods with the configuration object provided as `this`.\n\n```html\n<div id=\"app\">\n\t{{$number}}\n</div>\n<script>\nBrackets.render({\n\tel: '#app',\n\tdata: {\n\t\tnumber: 1\n\t},\n\tbeforeRender: function () {\n\t\tthis.data.number += 1;\n\t},\n\tafterRender: function () {\n\t\talert(\"Generated number is \" + this.data.number);\n\t}\n});\n</script>\n```\n\n## Event Handlers\nEvery website needs some interactivity. For example after clicking on a button. Every element that should be interactive must have the `b-on=\"\"` attribute. There you can set the target event and what should happen when is triggered.\nThe syntax is following `b-on=\"<event name> <callback>; <event name> <triggered callback>, ...\"`.\nThe callback can have two forms. Direct functionality, where the function is connected to the data object like `b-on=\"click number++` or an independent function `b-on=\"click updateNumber()\"`. If you want the callback to be a function, you can provide arguments. Those arguments are passed into the target function and are always a string so you have to convert it if you want to get for example a number from it. `b-on=\"click showAlert(Some text)\"`\n\n```html\n<div id=\"app\">\n\t{{$number}}<br>\n\t<button b-on=\"click showAlert(Clicked 1!); click number ++\">{{$firstButtonText}}</button><br>\n\t<button b-on=\"click secondButtonText = 'Clicked 2!'; click showAlert()\">{{$secondButtonText}}</button>\n</div>\n<script>\nBrackets.render({\n\tel: '#app',\n\tdata: {\n\t\tnumber: 0,\n\t\tfirstButtonText: 'Click me 1!',\n\t\tsecondButtonText: 'Click me 2!'\n\t},\n\tmethods: {\n\t\tshowAlert: function (event, parameters) {\n\t\t\tif (parameters) {\n\t\t\t\tthis.firstButtonText = parameters;\n\t\t\t}\n\t\t\talert('Hello World!');\n\t\t}\n\t}\n});\n</script>\n```\n\n## Filters\nFilters are used for interaction with values from variables.\nAs an example, we will create a filter called `firstToUpper` and it will convert the first character to a capital letter.\n\n```html\n<div id=\"app\">\n\t{{$text|firstToUpper}}\n</div>\n<script>\nBrackets\n\t.addFilter('firstToUpper', function (text) {\n\t\treturn text.charAt(0).toUpperCase() + text.slice(1);\n\t})\n\t.render({\n\t\tel: '#app',\n\t\tdata: {\n\t\t\ttext: 'text'\n\t\t}\n\t});\n</script>\n```\n```\nText\n```\n\nFilters can receive multiple arguments. The arguments must be added after the colon and must be separated by a comma.\nThe example below returns the default *first* text and attaches the text 'second' and 'third'.\n\n```html\n<div id=\"app\">\n\t{{$text|appendWords: 'second', 'third'}}\n</div>\n<script>\nBrackets\n\t.addFilter('appendWords', function (text, firstParameter, secondParameter) {\n\t\treturn text + ', ' + firstParameter + ', ' + secondParameter\n\t})\n\t.render({\n\t\tel: '#app',\n\t\tdata: {\n\t\t\ttext: 'First'\n\t\t}\n\t});\n</script>\n```\n\n```\nFirst, second, third\n```\n\n## Macros\nThere are the following macros defined by default.\n\n### Conditions\n<table>\n   <tbody>\n      <tr>\n         <td style=\"text-align:center\">{{if $cond}} … {{elseif $cond}} … {{else}} … {{/if}}</td>\n         <td style=\"text-align:center\">If condition</td>\n      </tr>\n   </tbody>\n</table>\n\n### Loops\n<table>\n   <tbody>\n      <tr>\n         <td style=\"text-align:center\">{{for condition} … {{/for}}</td>\n         <td style=\"text-align:center\">For loop</td>\n      </tr>\n\t  <tr>\n         <td style=\"text-align:center\">{{foreach values as key, value}} … {{/foreach}}</td>\n\t\t  <td style=\"text-align:center\">Foreach loop, the <strong>this</strong> object is an iterator object with <i>iterableLength</i> and <i>counter</i> parameters and <i>isFirst</i>, <i>isLast</i>, <i>isOddd</i> and <i>isEvent</i> functions.</td>\n      </tr>\n      <tr>\n         <td style=\"text-align:center\">{{while condition}} … {{/while}}</td>\n         <td style=\"text-align:center\">While loop</td>\n      </tr>\n\t  <tr>\n         <td style=\"text-align:center\">{{continue}}</td>\n         <td style=\"text-align:center\">Jump to the next iteration</td>\n      </tr>\n      <tr>\n         <td style=\"text-align:center\">{{continueIf condition}}</td>\n         <td style=\"text-align:center\">Conditional jump to the next iteration</td>\n      </tr>\n\t  <tr>\n         <td style=\"text-align:center\">{{break}</td>\n         <td style=\"text-align:center\">Loop break</td>\n      </tr>\n      <tr>\n         <td style=\"text-align:center\">{{breakIf condition}</td>\n         <td style=\"text-align:center\">Conditional loop break</td>\n      </tr>\n   </tbody>\n</table>\n\n### Variables\n<table>\n   <tbody>\n      <tr>\n         <td style=\"text-align:center\">{{var foo = value}}</td>\n         <td style=\"text-align:center\">Creates variable</td>\n      </tr>\n   </tbody>\n</table>\n\n### Other\n<table>\n   <tbody>\n      <tr>\n         <td style=\"text-align:center\">{{dump variable}}</td>\n         <td style=\"text-align:center\">Similar to console.log()</td>\n      </tr>\n      <tr>\n         <td style=\"text-align:center\">{{js code}}</td>\n         <td style=\"text-align:center\">Allows you to write pure javascript</td>\n      </tr>\n      <tr>\n         <td style=\"text-align:center\">{{component name, param1: value, parameter2: value}}</td>\n         <td style=\"text-align:center\">Allows you to reuse components</td>\n      </tr>\n   </tbody>\n</table>\n\n### How to create a macro\nMacro in the context of the template engine is a piece of executable code.\n\nFirst we will create a simple macro that will execute alert function. The macro name will be *alert* and *number* its parameter.\nMacro is separated into two parts `{{<name> <parameters>}}`. `#0` is a placeholder on which place the `<parameters>` will be placed.\nIn the following case, the `#0` will be replaced by `1`.\n\n```html\n<div id=\"app\">\n\t{{alert number}}\n</div>\n<script>\nBrackets\n\t.addMacro('alert', 'alert(#0);')\n\t.render({\n\t\tel: '#app',\n\t\tdata: {\n\t\t\tnumber: 1\n\t\t}\n\t});\n</script>\n```\n\nMacro can also be a function. In another example, we will use the `_template` variable available during the rendering.\nThe `_template` is used to return the generated template. We will used it, because we want to return a content from our macro.\n\nThe code during the compilation is separated by [Template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) or by single quotes (depends on browser support). The correct separator is stored in the `Brackets.templateLiteral` variable and you should use it to prevent incompatibility with older browsers.\n\nOn the end of the macro, there is a semicolon. In case you do not provide it the compilation will end with an error.\n\n```html\n<div id=\"app\">\n\t{{dumpNumber number}}\n</div>\n<script>\nvar sep = Brackets.templateLiteral;\nBrackets\n\t.addMacro('dumpNumber', function () {\n\t\treturn '_template +=' + sep + 'Number: ' +  sep + ' + number;'\n\t})\n\t.render({\n\t\tel: '#app',\n\t\tdata: {\n\t\t\tnumber: 1\n\t\t}\n\t});\n</script>\n```\n\n```\nNumber: 1\n```\n\nIt is also possible to use `_templateAdd` function. This function automatically applies the escaping filter.\n\n```html\n<div id=\"app\">\n\t{{dumpNumber number}}\n</div>\n<script>\nvar sep = Brackets.templateLiteral;\nBrackets\n\t.addMacro('dumpNumber', function () {\n\t\treturn '_template += _templateAdd(' + sep + 'Number: ' +  sep + ' + number);';\n\t})\n\t.render({\n\t\tel: '#app',\n\t\tdata: {\n\t\t\tnumber: 1\n\t\t}\n\t});\n</script>\n```\n\nThe `_templateAdd` function also allows you to use your already defined filters. Just add it as a second parameter.\n```html\n<div id=\"app\">\n\t{{dumpText text|firstToUpper}}\n</div>\n<script>\nBrackets\n\t.addFilter('firstToUpper', function (text) {\n\t\treturn text.charAt(0).toUpperCase() + text.slice(1);\n\t})\n\t.addMacro('dumpText', function () {\n\t\treturn '_template += _templateAdd(text, \\'firstToUpper\\');';\n\t})\n\t.render({\n\t\tel: '#app',\n\t\tdata: {\n\t\t\ttext: 'text!'\n\t\t}\n\t});\n</script>\n```\n\n## Complete Rendering Configuration\n```javascript\nBrackets.render({\n\tafterRender: <function|null>,\n\tbeforeRender: <function|null>,\n\taddData: <function|null>,\n\tcacheKey: <string|null>,\n\tdata: <object|null>,\n\tel: <string|Element|NodeList|function>,\n\tinstanceId <string|null>,\n\tmethods: <object|null>,\n\tonStatusChange: <function|null>,\n\tresultCacheEnabled: <function|null>,\n\ttemplate: <string|null>\n})\n```\n\n## Components\nComponents helps to create your code more reusable. You can for example create a button with some functionality\nand use it on multiple places with different parameters.\n\nIn the first example, there is a component that returns a text. The text is different in each `.app` element.\nComponents can receive arguments. Arguments are placed behind a comma (`,`) and are also separated by a comma (`,`).\n\n```html\n<div class=\"app\">{{component text}}</div>\n<div class=\"app\">{{component text, text: 'Second app'}}</div>\n<div class=\"app\">{{component text, text: 'Third app'}}</div>\n<script>\nBrackets\n\t.addComponent('text', {\n\t\tdata: {\n\t\t\ttext: 'First app'\n\t\t},\n\t\ttemplate: '{{$text}}'\n\t})\n\t.render({\n\t\tel: '.app',\n\t\tdata: {\n\t\t\ttext: 'First'\n\t\t}\n\t});\n</script>\n```\n\nNow, let's take a look on nested components. If the component is nested inside another component,\nthen it's parent component must have some root element in which the component is placed. The root element is not necessary for a plain text.\n\n```html\n<div class=\"app\">{{component shareArticle, articleName: 'Article 1'}}</div>\n<div class=\"app\">{{component shareArticle, articleName: 'Article 2'}}</div>\n<div class=\"app\">{{component shareArticle, articleName: 'Article 3'}}</div>\n<script>\nBrackets\n\t.addComponent('shareButton', {\n\t\tdata: {\n\t\t\tnumber: 0\n\t\t},\n\t\tmethods: {\n\t\t\tupdateNumber: function () {\n\t\t\t\tthis.number ++;\n\t\t\t}\n\t\t},\n\t\ttemplate: '<button b-on=\"click updateNumber()\">Share ({{$number}})</button>'\n\t})\n\t.addComponent('shareArticle', {\n\t\ttemplate: '<div>{{$articleName}} => {{component shareButton}}</div>'\n\t})\n\t.render({\n\t\tel: '.app'\n\t});\n</script>\n```\n\n### Complete Components Configuration\n```javascript\nBrackets.render({\n\tafterRender: <function|null>,\n\tbeforeRender: <function|null>,\n\taddData: <function|null>,\n\tcacheKey: <string|null>,\n\tdata: <object|null>,\n\tinstanceId <string|null>,\n\tmethods: <object|null>,\n\tonStatusChange: <function|null>,\n\tresultCacheEnabled: <function|null>,\n\ttemplate: <string>\n})\n```\n\n## Configuration Reserved Keywords\nThis keywords you must not use in the configuration object `_create, _data, _destroy, _instanceId, _hash, _type, _parent, _setStatus, _status`.\n\n## Rendering Instances\nRendering instances are interactive objects that were used during the rendering process of each template or component. \nEach rendering instance have an `id`. Because there can be multiple instances during the rendering process, you can set `instanceId` parameter. This parameter will be than used as a prefix for the instance so the instance id will be `<your-id>-<unique hash>`. This will help you to find the instance you want to work with.\n\nThe following example shows how to work with instances.\n```javascript\nBrackets.getRenderingInstances() // Returns an object containing all rendering instances\nvar myInstance = Brackets.getRenderingInstance('my-instance-1234') // Returns the selected instance\nmyInstance.data.number += 2 // Changing data structure in the renderingInstance will trigger the selected instance redrawal\nmyInstance.addData('key', 'value'); // This will add new data by key into the data object\n```\n\nInstances have also some statuses. You can use string or pass the constant from brackets object `Brackets.renderingInstancesStatuses.<status>`\n\t\n- **create**: When the instance is succesfully created.\n- **pending**: The default status after creation.\n- **redrawing**: When the instance is being redrawed.\n- **renderingToString**: When the instance template is being rendered into string.\n- **renderingToStringDone**: When the instance template is rendered to string.\n- **bindingEventHandlers**: When event handlers for the component are being attached.\n- **redrawingDone**: When the instance is completely redrawed and ready to use.\n- **destroy**: When the instance is being removed.\n\nThe default state after creating is `pending`. Then, before the whole rendering process starts and before the `beforeRender`method, the instance is set to `processing`. After the rendering the instance is set to `rendered`. \n\nYou can listen to these changes by providing `onStatusChange` parameter, that must be a function. The rendered instance is passed as `this` parameter and the status parameter is passed as a function argument. The usage is as follows.\n\n```javascript\nBrackets.render({\n\t...\n\tonStatusChange: function (status) {\n\t\tconsole.log(this) // Will log the whole instance\n\t\tconsole.log(status) // Logs current instance status\n\t}\n\t...\n})\n```\n\n## Security\nEvery variable passed into the template is autoescaped! If you want to disable the autoescaping for your variable add the `noescape` filter.\n\n```javascript\n{{$variable|noescape}}\n```\n","readmeFilename":"readme.md"}