Skip to content

nknapp/handlebars-ng

Folders and files

NameName
Last commit message
Last commit date

Latest commit

1b0663b · Oct 1, 2023
Oct 1, 2023
Jan 29, 2023
Dec 19, 2022
Oct 1, 2023
Jan 29, 2023
Oct 1, 2023
Jan 28, 2023
May 28, 2023
Oct 1, 2023
Oct 1, 2023
Oct 1, 2023
Jan 28, 2023
Dec 23, 2022
Jun 25, 2023
Feb 16, 2023
Oct 1, 2023
Oct 1, 2023
Oct 1, 2023

Repository files navigation

Handlebars next-generation

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.

Contents

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

Contributing

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.

Write a description of the feature

  • In general, it is helpful to run yarn site dev:server while 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.md and describe the feature. Use existing chapters as a template.

Add grammar

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:MySectionName comment 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 a testcase to the spec

  • Add one file named [feature-name].hb-spec.json, give it a $schema, description, template and input (and possible more relevant data that is NOT ast or output)
  • 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 add ast and output to the test-file
  • Validate output and ast. If the AST does not match your expectations, correct it and run yarn spec generate:auto-complete-tests again. This will add the originalAst feature.
  • 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.ts and run yarn spec generate to update the JSON schema. The Handlebars 4.x types are in types/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-build to make sure all the dist-files are updated correctly.

Adjust the parser

Go to "packages/@handlebars-ng/parser"

  • Run yarn parser dev:unit to 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 TokenType and 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 perf to run the performance tests, but performance optimizations can also be done later on.
  • Finally, run yarn parser test-and-build to update the dist-folder

Adjust the runner

Go to "packages/@handlebars-ng/runner"

  • Run yarn runner dev:unit to 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 perf to run the performance tests, but performance optimizations can also be done later on.
  • Finally, run yarn runner test-and-build to update the dist-folder

Work in progress

  • 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 then handlebars-lang org? I am reluctant doing that unless I know that this project will get some drive from other people as well.