Skip to content

Commit

Permalink
Merge pull request #64 from jaredwray/moving-to-async-createHandlebar…
Browse files Browse the repository at this point in the history
…s-function-to-do-dynamic-import

moving to async createHandlebars function to do dynamic import
  • Loading branch information
jaredwray authored Oct 28, 2024
2 parents 19be5f5 + a3e11ee commit 47be57f
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 52 deletions.
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 (me@jaredwray.com)",
"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
]
}

0 comments on commit 47be57f

Please sign in to comment.