Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

moving to async createHandlebars function to do dynamic import #64

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .c8rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"exclude": [
"test/**",
"dist/**",
"**/*.test.js",
"**/*.spec.ts",
"node_modules/**"
]
}
62 changes: 47 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,63 +12,95 @@ Handlebars + Helpers Together

[Handlebars](https://github.com/handlebars-lang/handlebars.js) + [Handlebars-helpers](https://github.com/helpers/handlebars-helpers) (helpers are now maintained in this project) combined into a single package. Easily use in your nodejs as it is a drop in replacement when using handlebars directly.

## Table of Contents
We plan to make significant changes over time with this project such as the following:
- **(Completed)** Remove all dependencies on `handlebars-helpers` and maintain all helpers in this project
- **(In Progress)** Migrate to Typescript with full typing support
- **(In Progress)** Replace module dependencies that are no longer supported with supported ones
- Migration to ESM and CJS support using cross compatible code
- Migration to `vitest` as a testing framework
- Migration to `xo` as a linting framework
- Move to better documentation and examples where it makes sense
- Add in browser support via CDN (this will remove the nodejs specific helpers)

# Breaking Changes from v2 to v3

Because of the complexity in the legacy helpers library we have moved to exporting the libraries and a helper function to make it easier to use. Here are the exports:

- `handlebars` - This is an instance of handlebars library without any helpers. It is the same as calling `Handlebars.create()`
- `helpers` - This is a function that takes an object with a `handlebars` key and adds all the helpers to the handlebars instance. This is the same as calling `helpers({ handlebars: handlebars })`
- `createHandlebars` - This is an async function that returns a handlebars instance with all the helpers added. This is the same as calling `helpers({ handlebars: handlebars })` but async.
- `Handlebars` - This is the handlebars library itself. It is the same as calling `require('handlebars')`

Please see the examples below for how to use the library.

# Table of Contents
* [Using in Nodejs](#using-in-nodejs)
* [Just using Handlebar Helpers](#using-handlebars-helpers)
* [Helpers](#helpers)
* [How to Contribute](#how-to-contribute)
* [License and Copyright](#license-and-copyright)

## Usage Nodejs

# Usage Nodejs

```bash
npm install @jaredwray/fumanchu --save
```

```javascript
var handlebars = require('@jaredwray/fumanchu');
var {handlebars, helpers} = require('@jaredwray/fumanchu');
helpers({ handlebars: handlebars });
var template = handlebars.compile('{{#if (eq foo "bar")}}<p>Foo is bar</p>{{/if}}');
var html = template({foo: 'bar'});
console.log(html);
```

If using it with es6 you can access `handlebars` via destructuring:
If using it with es6 you can access `handlebars` and `helpers`:

```javascript
import handlebars from '@jaredwray/fumanchu';
import {handlebars, helpers} from '@jaredwray/fumanchu';
helpers({ handlebars: handlebars });
const template = handlebars.compile('{{#if (eq foo "bar")}}<p>Foo is bar</p>{{/if}}');
const html = template({foo: 'bar'});
console.log(html);
```

If you want to just get an instance of handlebars via `createHandlebars` you can do the following **(it is async)**:

```javascript
import {createHandlebars} from '@jaredwray/fumanchu';
const handlebars = await createHandlebars(); //this will return a handlebars instance with all helpers
const template = handlebars.compile('{{#if (eq foo "bar")}}<p>Foo is bar</p>{{/if}}');
const html = template({foo: 'bar'});
console.log(html); // <p>Foo is bar</p>
```

It's just that easy! No need to add Handlebars to your project, it's already included.

## Using Handlebars Helpers
# Using Handlebars Helpers

If you only want to use handlebar helpers you can easily do that by doing the following:

```javascript
var helpers = require('@jaredwray/fumanchu').handlebarHelpers;
var {helpers} = require('@jaredwray/fumanchu');
var handlebars = require('handlebars');
helpers({ handlebars: handlebars });
var fn = handlebars.compile('{{add value 5}}');
console.log(fn);
console.log(fn); // 10
```

If using it with es6 you can access `helpers` via destructuring:

```javascript
import fumanchu, {handlebarHelpers} from '@jaredwray/fumanchu';
import {helpers} from '@jaredwray/fumanchu';
import handlebars from 'handlebars';
handlebarHelpers({ handlebars: handlebars });
helpers({ handlebars: handlebars });
const template = handlebars.compile('{{#if (eq foo "bar")}}<p>Foo is bar</p>{{/if}}');
const html = template({foo: 'bar'});
console.log(html);
console.log(html); // <p>Foo is bar</p>
```

Notice that in this scenario you are accessing helpers via `helpers` from `fumanchu` instead of just using handlebars via fumanchu directly.

## Helpers
# Helpers
More than 180 Handlebars helpers in ~20 categories. Helpers can be used with Assemble, Generate, Verb, Ghost, gulp-handlebars, grunt-handlebars, consolidate, or any node.js/Handlebars project.

## Categories
Expand Down Expand Up @@ -96,7 +128,7 @@ Currently **189 helpers** in **20 categories**:
* **[string](#string)** ([code](lib/string.js) | [unit tests](test/string.js))
* **[url](#url)** ([code](lib/url.js) | [unit tests](test/url.js))

## All helpers
# All helpers

### [array helpers](#array)

Expand Down
4 changes: 0 additions & 4 deletions index.d.ts

This file was deleted.

8 changes: 0 additions & 8 deletions index.js

This file was deleted.

29 changes: 29 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as HandlebarsLib from 'handlebars';
import helpersLib from './helpers.js';

/**
* Handlebars library not initiated with helpers
* @type {Handlebars}
*/
export const Handlebars = HandlebarsLib;

/**
* Fumanchu Handlebars instance not initiated with helpers
* @type {Handlebars}
*/
export const handlebars = HandlebarsLib.create();
/**
* Fumanchu Handlebars helpers
*/
export const helpers = helpersLib;

/**
* Create a new Handlebars instance with Fumanchu helpers
* @returns {Promise<Handlebars>}
*/
export async function createHandlebars() {
const handlebars = HandlebarsLib.create();
const helpersFunction = await import('./helpers.js');
helpersFunction.default({ handlebars: handlebars });
return handlebars;
}
23 changes: 12 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@jaredwray/fumanchu",
"description": "Handlebars + Helpers = Fumanchu",
"version": "2.1.0",
"version": "3.0.0",
"homepage": "https://github.com/jaredwray/fumanchu",
"author": "Jared Wray ([email protected])",
"keywords": [
Expand Down Expand Up @@ -88,19 +88,17 @@
},
"license": "MIT",
"files": [
"index.js",
"index.mjs",
"helpers.js",
"lib",
"dist",
"index.d.ts"
"license"
],
"source": "index.js",
"main": "index.js",
"types": "index.d.ts",
"source": "dist/index.js",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"test": "c8 mocha --reporter list",
"test:ci": "c8 --reporter=lcov mocha --reporter list",
"test": "npm run build && c8 mocha --reporter list",
"test:ci": "npm run build && c8 --reporter=lcov mocha --reporter list",
"build": "rimraf ./dist && tsup ./index.ts --format cjs --dts --clean",
"prepare": "npm run build",
"clean": "rimraf ./node_modules ./coverage yarn.lock package-lock.json ./dist ./dist-site",
"website:build": "rimraf ./site/readme.md && npx -y docula build -s ./site -o ./dist-site",
"website:serve": "rimraf ./site/readme.md && npx -y docula serve -s ./site -o ./dist-site"
Expand Down Expand Up @@ -141,11 +139,14 @@
"devDependencies": {
"c8": "^10.1.2",
"chai": "^4.3.10",
"docula": "^0.9.4",
"lodash": "^4.17.21",
"mocha": "^10.7.3",
"rimraf": "^6.0.1",
"template-helpers": "^1.0.1",
"templates": "^1.2.9",
"tsup": "^8.3.5",
"typecript": "^0.0.1-security",
"typescript": "^5.6.3"
}
}
10 changes: 5 additions & 5 deletions site/docula.config.cjs → site/docula.config.mjs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
const path = require('node:path');
const process = require('node:process');
const fs = require('node:fs');
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';

module.exports.options = {
export const options = {
githubPath: 'jaredwray/fumanchu',
siteTitle: 'Fumanchu',
siteDescription: 'Handlebars + Helpers Together',
siteUrl: 'https://fumanchu.org',
};

module.exports.onPrepare = async config => {
export const onPrepare = async config => {
const readmePath = path.join(process.cwd(), './README.md');
const readmeSitePath = path.join(config.sitePath, 'README.md');
const readme = await fs.promises.readFile(readmePath, 'utf8');
Expand Down
17 changes: 12 additions & 5 deletions test/es6.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import handlebars from '../index.js';
import {createHandlebars, helpers, handlebars, Handlebars} from '../dist/index.js';
import {expect} from 'chai';

describe('testing es6 examples', function() {
it('should get the handlebars from an es6 import', function() {
it('should get the handlebars from an es6 import', async function() {
const fumanchu = await createHandlebars();

// Use Fumanchu instead of Handlebars
const source = 'Hello, {{name}}!';
const template = handlebars.compile(source);
const template = fumanchu.compile(source);
// Render the template with a context
const result = template({ name: 'John' });

// Assert the rendered output
expect(result).to.equal('Hello, John!');

//testing the export of handlebarHelpers
const {handlebarHelpers} = handlebars;
expect(handlebarHelpers).to.be.a('function');
expect(helpers).to.be.a('function');

//testing the export of handlebarHelpers
expect(handlebars.compile).to.not.be.undefined;

//test the Handlebars object
expect(Handlebars.create).to.not.be.undefined;
});
});
18 changes: 14 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
var assert = require('assert');
const chai = require('chai');
const expect = chai.expect;
const Fumanchu = require('../index.js');
const {createHandlebars} = require('../dist/index.js');

describe('Fumanchu Template Test', function() {
it('should render name correctly', function() {
it('should render name correctly', async function() {
const Fumanchu = await createHandlebars();

// Use Fumanchu instead of Handlebars
const source = 'Hello, {{name}}!';
const template = Fumanchu.compile(source);
Expand All @@ -15,18 +17,26 @@ describe('Fumanchu Template Test', function() {
expect(result).to.equal('Hello, John!');
});

it('should return the sum of two numbers.', function() {
it('should return the sum of two numbers.', async function() {
const Fumanchu = await createHandlebars();
var fn = Fumanchu.compile('{{add value 5}}');
assert.equal(fn({value: 5}), '10');
});

it('should have the helper class exported', function() {
var helpers = require('../index.js').handlebarHelpers;
var helpers = require('../dist/index.js').helpers;
const HandlebarsLib = require('handlebars');
const handlebars = HandlebarsLib.create();
helpers({ handlebars: handlebars });
var fn = handlebars.compile('{{add value 5}}');
assert.equal(fn({value: 5}), '10');
});

it('should have the handlebars object exported', function() {
var {handlebars, helpers} = require('../dist/index.js');
helpers({ handlebars: handlebars });
var fn = handlebars.compile('{{add value 5}}');
assert.equal(fn({value: 5}), '10');
});
});

22 changes: 22 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ES6", // or your preferred target version
"module": "commonjs", // or your preferred module type
"allowJs": true, // Enable JavaScript files in the project
"checkJs": false, // Set to true if you want type-checking for JS files
"outDir": "./dist", // Specify output directory
"strict": true, // Enable strict type checking options
"esModuleInterop": true, // Required if you are using ES modules
"skipLibCheck": true, // Skipping type checks on declaration files
"declaration": true // Generate corresponding .d.ts file
},
"include": [
"helpers.js",
"src/**/*.js",
"index.ts"
],
"exclude": [
"node_modules",
"test/**/*.js", // Exclude test files or other JS files you don't want to compile
]
}
Loading