{"id":13514928,"url":"https://github.com/steve8708/compylr","last_synced_at":"2025-03-31T04:36:05.587Z","repository":{"id":13168113,"uuid":"15851111","full_name":"steve8708/compylr","owner":"steve8708","description":"Compile your angular apps to render on any server. Blazing fast page loads, ultra simple configuration, full support for angular templates, expression, and actions","archived":false,"fork":false,"pushed_at":"2016-03-29T20:42:08.000Z","size":2160,"stargazers_count":26,"open_issues_count":2,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-17T23:57:53.262Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"CoffeeScript","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/steve8708.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}},"created_at":"2014-01-12T21:20:16.000Z","updated_at":"2024-02-26T03:07:07.000Z","dependencies_parsed_at":"2022-08-25T17:02:13.406Z","dependency_job_id":null,"html_url":"https://github.com/steve8708/compylr","commit_stats":null,"previous_names":[],"tags_count":116,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steve8708%2Fcompylr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steve8708%2Fcompylr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steve8708%2Fcompylr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steve8708%2Fcompylr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steve8708","download_url":"https://codeload.github.com/steve8708/compylr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246418658,"owners_count":20773934,"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-08-01T05:01:03.995Z","updated_at":"2025-03-31T04:36:05.054Z","avatar_url":"https://github.com/steve8708.png","language":"CoffeeScript","funding_links":[],"categories":["CoffeeScript"],"sub_categories":[],"readme":"![Compylr](http://i.imgur.com/A3XYEWM.png)\n\nAngular.js apps rendered on the server, no node.js required!\n\nCompile angular apps for rendering on any backend, regardless of language or platform.\nServer side rendering, full angular expression support, 100% SEO compatible,\noptional client/server route, logic, and state sharing.\n\n\n## Purpose\n* Simplicity: write your angular app, let Compylr do the rest\n* Best of both worlds: first render on the server, then let angular take over once the page is displayed\n* Minimal pageload times pre-load\n* Maximum performance post-load\n* Backend agnostic\n* Easily share state and route logic on client and server\n* Support full RESTful URL structure for optimal page crawling\n\n\n## How it works\n* Compiles angular templates to handlebars templates\n* (Optionally) Standardizes route configuration using JSON for angular and any backend (via an adapter)\n* (Optionally) Standardizes state management with angular and any backend (via an adapter)\n\n## Installation\n`npm install --save compylr`\n\n\n## Example\n\n#### Angular Template Input\n```html\n\u003ca ng-repeat=\"product in products\" href=\"products/{{product.id}}\"\u003e\n  \u003cimg src=\"{{user.image}}\" ng-show=\"foo \u0026\u0026 bar\"\u003e\n\n  {{foo}}\n\n  \u003cdiv ng-include=\"'path/to/partial'\"\u003e\n  \u003c/div\u003e\n\u003c/a\u003e\n\n\u003cimg class=\"small\" ng-class=\"{ active: imgVisible }\" ng-if=\"foo.length\"\u003e\n\u003cimg ng-style=\"{ color: mainColor }\" ng-if=\"foo \u0026\u0026 bar\"\u003e\n\n{{ foo \u0026\u0026 bar }}\n```\n\n#### Compiled Temlpate Output\nIncludes {{}} for handlebars and attributes + escaped {{}} (\u0026amp;#123;) for angular interpolations\n```html\n{{#forEach 'foo' in bar}}\n  \u003ca ng-repeat=\"foo in bar\" href=\"products/{{product.id}}\" ng-href=\"products/\u0026#123;\u0026#123;product.id\u0026#125;\u0026#125;\"\u003e\n    \u003cimg src=\"{{user.image}}\" ng-show=\"foo\" {{hbsShow \"foo \u0026\u0026 bar\"}} ng-attr-src=\"\u0026#123;\u0026#123;user.image\u0026#125;\u0026#125;\"\u003e\n\n    \u003cspan ng-bind=\"foo\"\u003e{{foo}}\u003c/span\u003e\n\n    \u003cdiv ng-include=\"'path/to/partial'\"\u003e\n      {{\u003e path/to/partial}}\n    \u003c/div\u003e\n  \u003c/a\u003e\n{{/forEach}}\n\n{{#if foo.length}}\n  \u003cimg class=\"small {{#if imgVisible}}active{{/if}}\" ng-class=\"{ active: imgVisible }\" ng-if=\"foo.length\"\u003e\n{{/if}}\n\n{{#ifExpression \"foo \u0026\u0026 bar\"}}\n  \u003cimg ng-if=\"foo \u0026\u0026 bar\" style=\"{{styleExpression '{ color: mainColor }'}}\"\u003e\n{{/ifExpression}}\n\n\u003cspan ng-bind=\"foo \u0026\u0026 bar\"\u003e\n  {{expression \"foo \u0026\u0026 bar\"}}\n\u003c/span\u003e\n```\n\n#### Render Your Template\nRender your template with handlebars\nand pass in any data you need\n\n**Coffeescript Example**\n```coffeescript\napp.engine 'handlebars'\nres.render 'index', products: products\n```\n\n**Java Example**\n```java\nHandlebars handlebars = new Handlebars();\nTemplate template = handlebars.compile(\"index\");\nSystem.out.println(template.apply(\"Handlebars.java\"));\n```\n\n\n#### State \u0026 Route Configuration (Optional)\nConfigure your state and routes in one place and Compylr\nwill compile them into application logic for both your client and server.\n\n`compylr.json`\n\n```javascript\n{\n  \"routes\": {\n    \"/:page/:tab/:product\": {\n      \"data\": {\n        \"showModal\": true\n      },\n      \"compute\": {\n        \"activeTab.name\": \"$params.tab\",\n        \"activeProduct\": \"results[$params.product]\"\n      }\n    }\n  },\n  \"data\": {\n    \"activeProduct\": {},\n    \"query\": {\n      \"value\": \"\"\n    },\n    \"mode\": {\n      \"name\": \"search\"\n    },\n    \"openTab\": {\n      \"name\": \"insights\"\n    }\n  }\n}\n```\n\n\n#### Server Events \u0026 Actions (Optional)\nCompilr runs your applications routes and states on both the client\nand the server. This means that you can run things like\n\n* `\u003ca ng-click=\"selectedProduct = products[i]\"\u003e\u003c/a\u003e`\n* `\u003ca ng-click=\"showModal = true\"\u003e\u003c/a\u003e`\n* `\u003ca ng-click=\"user.loggedIn = false\"\u003e\u003c/a\u003e`\n\nAnd this will update state logic in your templates, such as\n* `\u003cdiv class=\"modal\" ng-show=\"showModal\"\u003e...\u003c/div\u003e`\n* `\u003ch1\u003e{{selectedProduct.name}}\u003c/h1\u003e\u003cp\u003e{{selectedProduct.description}}\u003c/p\u003e`\n* `\u003cdiv ng-if=\"user.loggedIn\" id=\"main-container\"\u003e\u003c/div\u003e`\n\nThis means your applications not only render on the server, but can\nfunction as fully standalone applications without any JS at all!\nThis is all taken care of automatigically by Compylr.\n\nFor example, this interactive webpage written in angular can function 100%\non the server and without JS when copiled by Compylr.\n\n\nPre-compile:\n\n```html\n\u003ca ng-click=\"selectedProduct = product\" ng-repeat=\"product in productResults\"\u003e\n  {{selectedProduct.name}}\n\u003c/a\u003e\n\u003cdiv ng-if=\"selectedProduct\"\u003e\n  \u003ch1\u003e{{selectedProduct.name}}\u003c/h1\u003e\n  \u003cp\u003e{{selectedProduct.description}}\u003c/p\u003e\n\u003c/div\u003e\n```\n\nPost-compile:\n\n```html\n{{#forEach 'product' in productResults}}\n  \u003ca href=\"?action=selectedProduct%3Dproduct\" ng-click=\"selectedProduct = product\" ng-repeat=\"product in productResults\" ng-bind=\"selectedProduct.name\"\u003e\n    {{selectedProduct.name}}\n  \u003c/a\u003e\n{{/forEach}}\n{{#if selectedProduct}}\n  \u003cdiv ng-if=\"selectedProduct\"\u003e\n    \u003ch1 ng-bind=\"selectedProduct.name\"\u003e{{selectedProduct.name}}\u003c/h1\u003e\n    \u003cp ng-bind=\"selectedProduct.description\"\u003e{{selectedProduct.description}}\u003c/p\u003e\n  \u003c/div\u003e\n{{/if}}\n```\n\nNote in the above example the key to this is in the href \"?action=\". This is compiled\nfrom your angular template and tells the server adapter the state and/or route\nchanges to make\n\nThis is all possible because of compylr's concept of a shared session state tree\nand route configuration\n\n\n## Key Features\n* 100% SEO friendly\n* Ultra high performance\n  * You don't need to run your whole app on the server to render a template. So don't.\n    Instead cross compile templates and sync state.\n* Angular application logic\n  * Use ng-click to trigger client __and__ server actions\n  (e.g. changing states and routes) even without any browser javascript!\n* Client and server rendering (render on server, once app loaded renders on client)\n* Pushtate support (always keep urls in sync)\n* Simple state and route configuration\n* Shared session state on client and server with simple configuration\n* Shared route logic on client and server with simple configuration\n* Backend agnostic. Supports any backend with a simple adapter\n* Full expression support - e.g. `ng-show=\"foo \u0026\u0026 bar[foo] || bar.foo\"`\n* Event support - e.g. `ng-click=\"foo = !foo\"`\n* Form support\n* Offline support\n* Templates compile to 100% valid handlebars\n  * Handlebars helpers compatible - extend with your own\n* Template resolution\n  * All angular template attributes are 100% safe. They are converted\n    to handlebars expressions and to ng-attributes so the template\n    can be immediately displayed in the browser but angular can still\n    find all necessary hooks to take control of the application once loaded\n  * e.g. `{{foo}}` ➜ `\u003cspan ng-bind=\"foo\"\u003e{{foo}}\u003cspan\u003e`\n\n\n## Supported Attributes\n* ng-repeat\n* ng-include\n* ng-show\n* ng-hide\n* ng-if\n* ng-click (With optional state syncing)\n* ng-class\n* ng-style\n* ng-attr-*\n* ng-href, ng-value, ng-src\n* ng-bind\n* interpolations\n * `{{foo}} \u003cimg src=\"{{bar}}.png\"\u003e`\n* expressions\n * `{{foo \u0026\u0026 bar}} \u003cimg ng-show=\"bar || foo\"\u003e`\n\n\n## Project Status\nFunctional demo complete. Working on production ready v1.0.0\n\n\n## Usage\n\n```coffeescript\ncompylr = require 'compylr'\ncompiled = compylr path: 'path/to/angular/template.html'\n```\n\nOr, more a more complete example\n\n```coffeescript\n# Load our dependencies\ncompylr = require 'compylr'\nfs = require 'fs'\nexpressHandlebars = require 'express3-handlebars'\nexpress = require 'express'\nhandlebars = require 'handlebars'\n\n# Set handlebars as our rendering engine\napp.engine 'html', expressHandlebars templatesDir: './templates'\n\n# Specify our templates directory\napp.set 'views', './templates'\n\n# Write our main template\nfs.writeFileSync 'templates/index.html', compylr path: 'path/to/angular/template.html'\n\n# Load compylr handlebars heleprs for rendering\ncompylr.setHelpers handelbars\n\n# Create an express app\napp = express()\n\n# Get the index route and render our compiled index.html with some data\napp.get 'index', (req, res) -\u003e\n  res.render 'index', foo: 'bar'\n\n```\n\nCLI (coming soon...)\n\n`compylr src/path/* dest/path/*`  \n`./node_modules/.bin/compylr src/path/* dest/path/*`\n\n## Development\nView and run `example/script.coffee` for an example on how to run uncompiled\ncoffeescript on a sample file. Modify `example/sample-angular-template.tpl.html`\nthen run `coffee example/script.coffee` to verify that your changes work as\nexpected.\n\n\u003c!--\n## Contributing\nWe need more adapters! Node + express is built. We need python, ruby, and more!\n --\u003e\n\n## Todo\n* Localization\n* Compile whole directories with src and dest directories\n* Support for angular filters\n* Support for other templating languages (e.g. jinja on python)\n* Support for logic sharing\n  * On node through code sharing\n  * On other platforms (python, java, etc) through expression parsing\n\n\n## Demo\nComing soon...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteve8708%2Fcompylr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteve8708%2Fcompylr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteve8708%2Fcompylr/lists"}