This is an attempt to rewrite Handlebars cleanly and with modern tools, and a the same time provide a reliable specification of its language.
In the best of all cases, this repo replaces Handlebars completely when all the original features are implemented.
This project is a mono-repo. The directory packages/@handlebars-ng contains the following modules:
- specification - builds a specification site and exports testcases and AST types
- parser - a TypeScript-based parser for the Handlebars language
- runner - a TypeScript-based compiler/executor for Handlebars ASTs
- benchmark - measures the performance of the new parser/executor compared to the original Handlebars
And some auxillary modules
- playground - The SolidJS components for the HandlebarsNG playground
- common-dev - project configuration files shared by multiple sub-repositories
- eslint-plugin - eslint-rules and configuration shared by multiple sub-repositories
I use Visual Studio Code to work in this repository. The following extensions are helpful:
You can contribute by adding new sections to the specification and fixing the resulting failing tests in the parser and runner.
I use the following workflow for this:
All the yarn-commands in the following description are run in the main directory.
- In general, it is helpful to run
yarn site dev:serverwhile editing the spec. It shows the current website instantly, including live-reload on content changes. - In the directory src/spec, add a new chapter-directory or use an existing chapter, if it fits semantically.
- Create a file
index.mdand describe the feature. Use existing chapters as a template.
Grammar is written in grammarkdown which allows to use a language grammar as defined the ECMA 262 Specification.
- Adjust the file handlebars.grammar by adding more statements and extending existing ones.
- If you want to include parts of the grammar into your text, add a
// @section:MySectionNamecomment to the grammar file - Add a link
[My FeatureName](../handlebars.grammer#MySectionName)to the text, linking to the grammar file.
The part of the grammar starting with the linked section, up to the next section marker (or end-of-file) will be inlined instead of the link.
- Add one file named
[feature-name].hb-spec.json, give it a$schema,description,templateandinput(and possible more relevant data that is NOTastoroutput) - Create a link from the markdown-file to the test-file using markdown-syntax.
- Run
yarn spec generate:auto-complete-tests. This will run Handlebars 4.x and addastandoutputto the test-file - Validate output and ast. If the AST does not match your expectations, correct it and run
yarn spec generate:auto-complete-testsagain. This will add theoriginalAstfeature. - The output should match your expectation, because handlebars-ng ist supposed to be compatible to Handlebars 4.x at least in that respect. If you really think it is a bug, you can add a description of the bug to the field
possibleBug. We can discuss this later. - If the generated AST does not match, the JSON schema, you add the correct TypeScript-types to the file
packages/@handlebars-ng/abstract-syntax-tree/index.d.tsand runyarn spec generateto update the JSON schema. The Handlebars 4.x types are intypes/handlebars/index.d.ts. You can use them as hints. - Only add as many types as necessary to represent the generated AST. We want to build up the model incrementally.
- Run
yarn spec test-and-buildto make sure all the dist-files are updated correctly.
Go to "packages/@handlebars-ng/parser"
- Run
yarn parser dev:unitto run unit-tests in watch mode. Your specification-test should be run as well and fail, so you can try to fix. - Add values to the
TokenTypeand new tokens in src/model/lexer.ts if necessary. - Add a new plugin to src/plugins
- Have a look at the existing plugins for reference. In general, a plugin uses registers rules and lexer-states and parse-functions associates with those rules. It's all in one place now.
- Add your plugin to the default parser
- When the test is green, cleanup your code.
- You can run
yarn parser perfto run the performance tests, but performance optimizations can also be done later on. - Finally, run
yarn parser test-and-buildto update thedist-folder
Go to "packages/@handlebars-ng/runner"
- Run
yarn runner dev:unitto run unit-tests in watch mode. Your specification-test should be run as well and fail, so you can try to fix. - Add a new renderer to src/renderer if necessary.
- Register the new renderer in src/index.ts
- Adjust renders and needed
- Cleanup your code afterwards.
- You can run
yarn runner perfto run the performance tests, but performance optimizations can also be done later on. - Finally, run
yarn runner test-and-buildto update thedist-folder
- We need to set up a publishing progress and maybe some browser tests.
- Should we put this unter the
@handlebars-scope in npm? And move it to thenhandlebars-langorg? I am reluctant doing that unless I know that this project will get some drive from other people as well.