From 749f400045b6d2ddce1f7565e4bcd3f9937cad7f Mon Sep 17 00:00:00 2001 From: Jared Wray Date: Thu, 24 Aug 2023 14:52:17 -0700 Subject: [PATCH 1/6] initial pull request with readme and workflows --- .github/ISSUE_TEMPLATE/bug_report.md | 14 + .github/ISSUE_TEMPLATE/feature_request.md | 14 + .github/PULL_REQUEST_TEMPLATE.md | 6 + .github/workflows/codeql.yml | 72 + .github/workflows/tests.yaml | 35 + CODE_OF_CONDUCT.md | 128 + CONTRIBUTING.md | 27 + README.md | 3052 ++++++++++++++++++++- SECURITY.md | 14 + index.js | 10 +- logo.png | Bin 0 -> 5551 bytes package.json | 53 +- test/index.js | 4 +- 13 files changed, 3371 insertions(+), 58 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/tests.yaml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md create mode 100644 logo.png diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..0e4c9d8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,14 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**How To Reproduce (best to provide workable code or tests!)** +Please provide code or unit test example that will reproduce the error. If you can't provide code, please provide a detailed description of how to reproduce the error. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..c444027 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..9503080 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,6 @@ +**Please check if the PR fulfills these requirements** +- [ ] Followed the [Contributing](https://github.com/jaredwray/airhorn/blob/main/CONTRIBUTING.md) guidelines. +- [ ] Tests for the changes have been added (for bug fixes/features) with 100% code coverage. +- [ ] Docs have been added / updated (for bug fixes / features) + +**What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..b62bc31 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,72 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '19 18 * * 1' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..e97f84a --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,35 @@ +name: tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: ['14', '16', '18'] + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Install Dependencies + run: yarn + + - name: Testing + run: yarn test + + - name: Code Coverage + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_KEY }} + files: coverage/coverage-final.json \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..c23fb4c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +me@jaredwray.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c7153cc --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,27 @@ +# Contributing +When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. + +Please note we have a [Code of Conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. + +We release new versions of this project (maintenance/features) on a monthly cadence so please be aware that some items will not get released right away. + +# Pull Request Process +You can contribute changes to this repo by opening a pull request: + +1) After forking this repository to your Git account, make the proposed changes on your forked branch. +2) Run tests and linting locally. + - Make sure to have an `.env` file with `FIREBASE_CERT` and `SENDGRID_API_KEY` values plus the `firebase-cert.json` file and valid cert. + - Run `npm install`. + - Run `npm test`. +3) Commit your changes and push them to your forked repository. +4) Navigate to the main `Fumanchu` repository and select the *Pull Requests* tab. +5) Click the *New pull request* button, then select the option "Compare across forks" +6) Leave the base branch set to main. Set the compare branch to your forked branch, and open the pull request. +7) Once your pull request is created, ensure that all checks have passed and that your branch has no conflicts with the base branch. If there are any issues, resolve these changes in your local repository, and then commit and push them to git. +8) Similarly, respond to any reviewer comments or requests for changes by making edits to your local repository and pushing them to Git. +9) Once the pull request has been reviewed, those with write access to the branch will be able to merge your changes into the `Fumanchu` repository. + +If you need more information on the steps to create a pull request, you can find a detailed walkthrough in the [Github documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) + +# Code of Conduct +Please refer to our [Code of Conduct](https://github.com/jaredwray/fumanchu/blob/main/CODE_OF_CONDUCT.md) readme for how to contribute to this open source project and work within the community. diff --git a/README.md b/README.md index 36aeb32..0a4c003 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3052 @@ +
Fu Manchu
+ # fumanchu -Handlebars with Helpers Together! +Handlebars + Helpers Together + +This is a drop in replacement for [handlebars](https://github.com/handlebars-lang/handlebars.js) + a supported / forked version of [handlebars-helpers](https://github.com/helpers/handlebars-helpers) as it was not being maintained. + +Table of Contents +* [Installation](#installation) +* [Usage Nodejs](#usage-nodejs) +* [Usage Browser](#usage-browser) +* [Helpers](#helpers) +* [How to Contribute](#how-to-contribute) +* [License and Copyright](#license-and-copyright) + +## Installation + +```bash +npm install fumanchu +``` + +## Usage Nodejs + +```javascript +var handlebars = require('fumanchu'); +var template = handlebars.compile('{{#if (eq foo "bar")}}

Foo is bar

{{/if}}'); +var html = template({foo: 'bar'}); +console.log(html); +``` + +Its just that easy! + +## Usage Browser + +```html + + +``` + +## Helpers +More than 130 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 + +Currently **189 helpers** in **20 categories**: + +* **[array](#array)** ([code](lib/array.js) | [unit tests](test/array.js)) +* **[code](#code)** ([code](lib/code.js) | [unit tests](test/code.js)) +* **[collection](#collection)** ([code](lib/collection.js) | [unit tests](test/collection.js)) +* **[comparison](#comparison)** ([code](lib/comparison.js) | [unit tests](test/comparison.js)) +* **[date](#date)** ([code](lib/date.js) | [unit tests](test/date.js)) +* **[fs](#fs)** ([code](lib/fs.js) | [unit tests](test/fs.js)) +* **[html](#html)** ([code](lib/html.js) | [unit tests](test/html.js)) +* **[i18n](#i18n)** ([code](lib/i18n.js) | [unit tests](test/i18n.js)) +* **[inflection](#inflection)** ([code](lib/inflection.js) | [unit tests](test/inflection.js)) +* **[logging](#logging)** ([code](lib/logging.js) | [unit tests](test/logging.js)) +* **[markdown](#markdown)** ([code](lib/markdown.js) | [unit tests](test/markdown.js)) +* **[match](#match)** ([code](lib/match.js) | [unit tests](test/match.js)) +* **[math](#math)** ([code](lib/math.js) | [unit tests](test/math.js)) +* **[misc](#misc)** ([code](lib/misc.js) | [unit tests](test/misc.js)) +* **[number](#number)** ([code](lib/number.js) | [unit tests](test/number.js)) +* **[object](#object)** ([code](lib/object.js) | [unit tests](test/object.js)) +* **[path](#path)** ([code](lib/path.js) | [unit tests](test/path.js)) +* **[regex](#regex)** ([code](lib/regex.js) | [unit tests](test/regex.js)) +* **[string](#string)** ([code](lib/string.js) | [unit tests](test/string.js)) +* **[url](#url)** ([code](lib/url.js) | [unit tests](test/url.js)) + +## All helpers + +### [array helpers](#array) + +Visit the: [code](lib/array.js) | [unit tests](test/array.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+array+helpers)) + +* **[after](#after)** ([code](lib/array.js#L22) | [tests](test/array.js#L13)) +* **[arrayify](#arrayify)** ([code](lib/array.js#L39) | [tests](test/array.js#L29)) +* **[before](#before)** ([code](lib/array.js#L58) | [tests](test/array.js#L36)) +* **[eachIndex](#eachIndex)** ([code](lib/array.js#L77) | [tests](test/array.js#L58)) +* **[filter](#filter)** ([code](lib/array.js#L102) | [tests](test/array.js#L91)) +* **[first](#first)** ([code](lib/array.js#L142) | [tests](test/array.js#L65)) +* **[forEach](#forEach)** ([code](lib/array.js#L184) | [tests](test/array.js#L123)) +* **[inArray](#inArray)** ([code](lib/array.js#L224) | [tests](test/array.js#L160)) +* **[isArray](#isArray)** ([code](lib/array.js#L244) | [tests](test/array.js#L172)) +* **[itemAt](#itemAt)** ([code](lib/array.js#L263) | [tests](test/array.js#L182)) +* **[join](#join)** ([code](lib/array.js#L294) | [tests](test/array.js#L225)) +* **[equalsLength](#equalsLength)** ([code](lib/array.js#L313) | [no tests]) +* **[last](#last)** ([code](lib/array.js#L349) | [tests](test/array.js#L240)) +* **[length](#length)** ([code](lib/array.js#L379) | [tests](test/array.js#L254)) +* **[lengthEqual](#lengthEqual)** ([code](lib/array.js#L395) | [tests](test/array.js#L254)) +* **[map](#map)** ([code](lib/array.js#L414) | [tests](test/array.js#L266)) +* **[pluck](#pluck)** ([code](lib/array.js#L445) | [tests](test/array.js#L300)) +* **[reverse](#reverse)** ([code](lib/array.js#L473) | [no tests]) +* **[some](#some)** ([code](lib/array.js#L504) | [tests](test/array.js#L308)) +* **[sort](#sort)** ([code](lib/array.js#L532) | [tests](test/array.js#L333)) +* **[sortBy](#sortBy)** ([code](lib/array.js#L557) | [tests](test/array.js#L358)) +* **[withAfter](#withAfter)** ([code](lib/array.js#L588) | [tests](test/array.js#L390)) +* **[withBefore](#withBefore)** ([code](lib/array.js#L618) | [tests](test/array.js#L397)) +* **[withFirst](#withFirst)** ([code](lib/array.js#L648) | [tests](test/array.js#L404)) +* **[withGroup](#withGroup)** ([code](lib/array.js#L692) | [tests](test/array.js#L418)) +* **[withLast](#withLast)** ([code](lib/array.js#L727) | [tests](test/array.js#L428)) +* **[withSort](#withSort)** ([code](lib/array.js#L766) | [tests](test/array.js#L442)) +* **[unique](#unique)** ([code](lib/array.js#L816) | [tests](test/array.js#L483)) + +### [code helpers](#code) + +Visit the: [code](lib/code.js) | [unit tests](test/code.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+code+helpers)) + +* **[embed](#embed)** ([code](lib/code.js#L23) | [tests](test/code.js#L10)) +* **[gist](#gist)** ([code](lib/code.js#L45) | [tests](test/code.js#L62)) +* **[jsfiddle](#jsfiddle)** ([code](lib/code.js#L60) | [tests](test/code.js#L69)) + +### [collection helpers](#collection) + +Visit the: [code](lib/collection.js) | [unit tests](test/collection.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+collection+helpers)) + +* **[isEmpty](#isEmpty)** ([code](lib/collection.js#L31) | [tests](test/collection.js#L14)) +* **[iterate](#iterate)** ([code](lib/collection.js#L59) | [tests](test/collection.js#L68)) + +### [comparison helpers](#comparison) + +Visit the: [code](lib/comparison.js) | [unit tests](test/comparison.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+comparison+helpers)) + +* **[and](#and)** ([code](lib/comparison.js#L27) | [tests](test/comparison.js#L10)) +* **[compare](#compare)** ([code](lib/comparison.js#L57) | [tests](test/comparison.js#L41)) +* **[contains](#contains)** ([code](lib/comparison.js#L124) | [tests](test/comparison.js#L167)) +* **[default](#default)** ([code](lib/comparison.js#L143) | [tests](test/comparison.js#L204)) +* **[eq](#eq)** ([code](lib/comparison.js#L165) | [tests](test/comparison.js#L351)) +* **[gt](#gt)** ([code](lib/comparison.js#L188) | [tests](test/comparison.js#L214)) +* **[gte](#gte)** ([code](lib/comparison.js#L212) | [tests](test/comparison.js#L245)) +* **[has](#has)** ([code](lib/comparison.js#L232) | [tests](test/comparison.js#L260)) +* **[isFalsey](#isFalsey)** ([code](lib/comparison.js#L274) | [tests](test/comparison.js#L327)) +* **[isTruthy](#isTruthy)** ([code](lib/comparison.js#L289) | [tests](test/comparison.js#L339)) +* **[ifEven](#ifEven)** ([code](lib/comparison.js#L310) | [tests](test/comparison.js#L368)) +* **[ifNth](#ifNth)** ([code](lib/comparison.js#L327) | [tests](test/comparison.js#L380)) +* **[ifOdd](#ifOdd)** ([code](lib/comparison.js#L350) | [tests](test/comparison.js#L403)) +* **[is](#is)** ([code](lib/comparison.js#L274) | [tests](test/comparison.js#L327)) +* **[isnt](#isnt)** ([code](lib/comparison.js#L389) | [tests](test/comparison.js#L432)) +* **[lt](#lt)** ([code](lib/comparison.js#L411) | [tests](test/comparison.js#L449)) +* **[lte](#lte)** ([code](lib/comparison.js#L435) | [tests](test/comparison.js#L476)) +* **[neither](#neither)** ([code](lib/comparison.js#L456) | [tests](test/comparison.js#L511)) +* **[not](#not)** ([code](lib/comparison.js#L470) | [no tests]) +* **[or](#or)** ([code](lib/comparison.js#L492) | [tests](test/comparison.js#L523)) +* **[unlessEq](#unlessEq)** ([code](lib/comparison.js#L518) | [tests](test/comparison.js#L556)) +* **[unlessGt](#unlessGt)** ([code](lib/comparison.js#L538) | [tests](test/comparison.js#L567)) +* **[unlessLt](#unlessLt)** ([code](lib/comparison.js#L558) | [tests](test/comparison.js#L578)) +* **[unlessGteq](#unlessGteq)** ([code](lib/comparison.js#L578) | [tests](test/comparison.js#L589)) +* **[unlessLteq](#unlessLteq)** ([code](lib/comparison.js#L598) | [tests](test/comparison.js#L604)) + +### [date helpers](#date) + +Visit the: [code](lib/date.js) | [unit tests](test/date.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+date+helpers)) + +* **[year](#year)** ([code](lib/date.js#L15) | [no tests]) +* **[date](#date)** ([code](lib/date.js#Lundefined) | [no tests]) +* **[moment](#moment)** ([code](lib/date.js#L24) | [no tests]) + +### [fs helpers](#fs) + +Visit the: [code](lib/fs.js) | [unit tests](test/fs.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+fs+helpers)) + +* **[fileSize](#fileSize)** ([code](lib/fs.js#L14) | [no tests]) +* **[read](#read)** ([code](lib/fs.js#L29) | [tests](test/fs.js#L16)) +* **[readdir](#readdir)** ([code](lib/fs.js#L42) | [tests](test/fs.js#L23)) + +### [html helpers](#html) + +Visit the: [code](lib/html.js) | [unit tests](test/html.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+html+helpers)) + +* **[attr](#attr)** ([code](lib/html.js#L23) | [tests](test/html.js#L13)) +* **[css](#css)** ([code](lib/html.js#L45) | [tests](test/html.js#L21)) +* **[js](#js)** ([code](lib/html.js#L89) | [tests](test/html.js#L69)) +* **[sanitize](#sanitize)** ([code](lib/html.js#L121) | [tests](test/html.js#L98)) +* **[ul](#ul)** ([code](lib/html.js#L135) | [tests](test/html.js#L108)) +* **[ol](#ol)** ([code](lib/html.js#L154) | [tests](test/html.js#L115)) +* **[thumbnailImage](#thumbnailImage)** ([code](lib/html.js#L176) | [tests](test/html.js#L122)) + +### [i18n helpers](#i18n) + +Visit the: [code](lib/i18n.js) | [unit tests](test/i18n.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+i18n+helpers)) + +* **[i18n](#i18n)** ([code](lib/i18n.js#L18) | [tests](test/i18n.js#L11)) + +### [inflection helpers](#inflection) + +Visit the: [code](lib/inflection.js) | [unit tests](test/inflection.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+inflection+helpers)) + +* **[inflect](#inflect)** ([code](lib/inflection.js#L30) | [tests](test/inflection.js#L9)) +* **[ordinalize](#ordinalize)** ([code](lib/inflection.js#L58) | [tests](test/inflection.js#L22)) + +### [logging helpers](#logging) + +Visit the: [code](lib/logging.js) | [unit tests](test/logging.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+logging+helpers)) + +* **[log](#log)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[ok](#ok)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[success](#success)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[info](#info)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[warning](#warning)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[warn](#warn)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[error](#error)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[danger](#danger)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[bold](#bold)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[_debug](#_debug)** ([code](lib/logging.js#Lundefined) | [no tests]) +* **[_inspect](#_inspect)** ([code](lib/logging.js#Lundefined) | [no tests]) + +### [markdown helpers](#markdown) + +Visit the: [code](lib/markdown.js) | [unit tests](test/markdown.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+markdown+helpers)) + +* **[markdown](#markdown)** ([code](lib/markdown.js#Lundefined) | [tests](test/markdown.js#L10)) +* **[md](#md)** ([code](lib/markdown.js#L55) | [tests](test/markdown.js#L18)) + +### [match helpers](#match) + +Visit the: [code](lib/match.js) | [unit tests](test/match.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+match+helpers)) + +* **[match](#match)** ([code](lib/match.js#L23) | [tests](test/match.js#L13)) +* **[isMatch](#isMatch)** ([code](lib/match.js#L47) | [tests](test/match.js#L61)) +* **[mm](#mm)** ([code](lib/match.js#L56) | [no tests]) + +### [math helpers](#math) + +Visit the: [code](lib/math.js) | [unit tests](test/math.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+math+helpers)) + +* **[abs](#abs)** ([code](lib/math.js#L15) | [no tests]) +* **[add](#add)** ([code](lib/math.js#L31) | [tests](test/math.js#L10)) +* **[avg](#avg)** ([code](lib/math.js#L54) | [no tests]) +* **[ceil](#ceil)** ([code](lib/math.js#L69) | [tests](test/math.js#L29)) +* **[divide](#divide)** ([code](lib/math.js#L84) | [tests](test/math.js#L36)) +* **[floor](#floor)** ([code](lib/math.js#L102) | [tests](test/math.js#L43)) +* **[minus](#minus)** ([code](lib/math.js#L118) | [no tests]) +* **[modulo](#modulo)** ([code](lib/math.js#L137) | [no tests]) +* **[multiply](#multiply)** ([code](lib/math.js#L157) | [tests](test/math.js#L50)) +* **[plus](#plus)** ([code](lib/math.js#L175) | [no tests]) +* **[random](#random)** ([code](lib/math.js#L194) | [tests](test/math.js#L102)) +* **[remainder](#remainder)** ([code](lib/math.js#L212) | [tests](test/math.js#L57)) +* **[round](#round)** ([code](lib/math.js#L224) | [tests](test/math.js#L69)) +* **[subtract](#subtract)** ([code](lib/math.js#L241) | [tests](test/math.js#L76)) +* **[sum](#sum)** ([code](lib/math.js#L263) | [tests](test/math.js#L83)) +* **[times](#times)** ([code](lib/math.js#L286) | [no tests]) + +### [misc helpers](#misc) + +Visit the: [code](lib/misc.js) | [unit tests](test/misc.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+misc+helpers)) + +* **[frame](#frame)** ([code](lib/misc.js#L11) | [no tests]) +* **[option](#option)** ([code](lib/misc.js#L26) | [tests](test/misc.js#L20)) +* **[noop](#noop)** ([code](lib/misc.js#L39) | [tests](test/misc.js#L13)) +* **[typeOf](#typeOf)** ([code](lib/misc.js#L59) | [no tests]) +* **[withHash](#withHash)** ([code](lib/misc.js#L71) | [tests](test/misc.js#L38)) + +### [number helpers](#number) + +Visit the: [code](lib/number.js) | [unit tests](test/number.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+number+helpers)) + +* **[bytes](#bytes)** ([code](lib/number.js#L24) | [tests](test/number.js#L10)) +* **[addCommas](#addCommas)** ([code](lib/number.js#L61) | [tests](test/number.js#L84)) +* **[phoneNumber](#phoneNumber)** ([code](lib/number.js#L74) | [tests](test/number.js#L30)) +* **[toAbbr](#toAbbr)** ([code](lib/number.js#L92) | [tests](test/number.js#L91)) +* **[toExponential](#toExponential)** ([code](lib/number.js#L130) | [tests](test/number.js#L59)) +* **[toFixed](#toFixed)** ([code](lib/number.js#L153) | [tests](test/number.js#L37)) +* **[toFloat](#toFloat)** ([code](lib/number.js#L169) | [tests](test/number.js#L77)) +* **[toInt](#toInt)** ([code](lib/number.js#L179) | [tests](test/number.js#L70)) +* **[toPrecision](#toPrecision)** ([code](lib/number.js#L196) | [tests](test/number.js#L48)) + +### [object helpers](#object) + +Visit the: [code](lib/object.js) | [unit tests](test/object.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+object+helpers)) + +* **[extend](#extend)** ([code](lib/object.js#L18) | [tests](test/object.js#L15)) +* **[forIn](#forIn)** ([code](lib/object.js#L55) | [tests](test/object.js#L33)) +* **[forOwn](#forOwn)** ([code](lib/object.js#L81) | [tests](test/object.js#L50)) +* **[toPath](#toPath)** ([code](lib/object.js#L106) | [tests](test/object.js#L87)) +* **[get](#get)** ([code](lib/object.js#L128) | [tests](test/object.js#L77)) +* **[getObject](#getObject)** ([code](lib/object.js#L149) | [tests](test/object.js#L77)) +* **[hasOwn](#hasOwn)** ([code](lib/object.js#L167) | [tests](test/object.js#L126)) +* **[isObject](#isObject)** ([code](lib/object.js#L183) | [tests](test/object.js#L144)) +* **[JSONparse](#JSONparse)** ([code](lib/object.js#L201) | [tests](test/object.js#L164)) +* **[JSONstringify](#JSONstringify)** ([code](lib/object.js#L218) | [no tests]) +* **[merge](#merge)** ([code](lib/object.js#L235) | [tests](test/object.js#L156)) +* **[parseJSON](#parseJSON)** ([code](lib/object.js#L254) | [no tests]) +* **[pick](#pick)** ([code](lib/object.js#L267) | [tests](test/object.js#L171)) +* **[stringify](#stringify)** ([code](lib/object.js#L290) | [tests](test/object.js#L199)) + +### [path helpers](#path) + +Visit the: [code](lib/path.js) | [unit tests](test/path.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+path+helpers)) + +* **[absolute](#absolute)** ([code](lib/path.js#L20) | [tests](test/path.js#L13)) +* **[dirname](#dirname)** ([code](lib/path.js#L40) | [tests](test/path.js#L25)) +* **[relative](#relative)** ([code](lib/path.js#L59) | [tests](test/path.js#L32)) +* **[basename](#basename)** ([code](lib/path.js#L81) | [tests](test/path.js#L47)) +* **[stem](#stem)** ([code](lib/path.js#L100) | [tests](test/path.js#L58)) +* **[extname](#extname)** ([code](lib/path.js#L119) | [tests](test/path.js#L69)) +* **[resolve](#resolve)** ([code](lib/path.js#L138) | [no tests]) +* **[segments](#segments)** ([code](lib/path.js#L166) | [tests](test/path.js#L80)) + +### [regex helpers](#regex) + +Visit the: [code](lib/regex.js) | [unit tests](test/regex.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+regex+helpers)) + +* **[toRegex](#toRegex)** ([code](lib/regex.js#L19) | [no tests]) +* **[test](#test)** ([code](lib/regex.js#L42) | [no tests]) + +### [string helpers](#string) + +Visit the: [code](lib/string.js) | [unit tests](test/string.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+string+helpers)) + +* **[append](#append)** ([code](lib/string.js#L22) | [no tests]) +* **[camelcase](#camelcase)** ([code](lib/string.js#L41) | [tests](test/string.js#L10)) +* **[capitalize](#capitalize)** ([code](lib/string.js#L60) | [tests](test/string.js#L25)) +* **[capitalizeAll](#capitalizeAll)** ([code](lib/string.js#L77) | [tests](test/string.js#L36)) +* **[center](#center)** ([code](lib/string.js#L95) | [tests](test/string.js#L47)) +* **[chop](#chop)** ([code](lib/string.js#L125) | [tests](test/string.js#L58)) +* **[dashcase](#dashcase)** ([code](lib/string.js#L143) | [tests](test/string.js#L73)) +* **[dotcase](#dotcase)** ([code](lib/string.js#L162) | [tests](test/string.js#L88)) +* **[downcase](#downcase)** ([code](lib/string.js#L182) | [no tests]) +* **[ellipsis](#ellipsis)** ([code](lib/string.js#L202) | [tests](test/string.js#L103)) +* **[hyphenate](#hyphenate)** ([code](lib/string.js#L223) | [tests](test/string.js#L118)) +* **[isString](#isString)** ([code](lib/string.js#L240) | [tests](test/string.js#L129)) +* **[lowercase](#lowercase)** ([code](lib/string.js#L256) | [tests](test/string.js#L151)) +* **[occurrences](#occurrences)** ([code](lib/string.js#L278) | [tests](test/string.js#L162)) +* **[pascalcase](#pascalcase)** ([code](lib/string.js#L303) | [tests](test/string.js#L173)) +* **[pathcase](#pathcase)** ([code](lib/string.js#L323) | [tests](test/string.js#L188)) +* **[plusify](#plusify)** ([code](lib/string.js#L343) | [tests](test/string.js#L203)) +* **[prepend](#prepend)** ([code](lib/string.js#L363) | [no tests]) +* **[raw](#raw)** ([code](lib/string.js#L385) | [no tests]) +* **[remove](#remove)** ([code](lib/string.js#L413) | [no tests]) +* **[removeFirst](#removeFirst)** ([code](lib/string.js#L432) | [no tests]) +* **[replace](#replace)** ([code](lib/string.js#L452) | [tests](test/string.js#L222)) +* **[replaceFirst](#replaceFirst)** ([code](lib/string.js#L473) | [no tests]) +* **[reverse](#reverse)** ([code](lib/string.js#L492) | [tests](test/string.js#L241)) +* **[sentence](#sentence)** ([code](lib/string.js#L509) | [tests](test/string.js#L252)) +* **[snakecase](#snakecase)** ([code](lib/string.js#L528) | [tests](test/string.js#L263)) +* **[split](#split)** ([code](lib/string.js#L547) | [tests](test/string.js#L278)) +* **[startsWith](#startsWith)** ([code](lib/string.js#L572) | [tests](test/string.js#L293)) +* **[titleize](#titleize)** ([code](lib/string.js#L596) | [tests](test/string.js#L312)) +* **[trim](#trim)** ([code](lib/string.js#L623) | [tests](test/string.js#L323)) +* **[trimLeft](#trimLeft)** ([code](lib/string.js#L639) | [no tests]) +* **[trimRight](#trimRight)** ([code](lib/string.js#L657) | [no tests]) +* **[truncate](#truncate)** ([code](lib/string.js#L680) | [tests](test/string.js#L338)) +* **[truncateWords](#truncateWords)** ([code](lib/string.js#L712) | [no tests]) +* **[upcase](#upcase)** ([code](lib/string.js#L742) | [no tests]) +* **[uppercase](#uppercase)** ([code](lib/string.js#L763) | [tests](test/string.js#L362)) + +### [url helpers](#url) + +Visit the: [code](lib/url.js) | [unit tests](test/url.js) | [issues](https://github.com/jonathas/handlebars-helpers/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+url+helpers)) + +* **[encodeURI](#encodeURI)** ([code](lib/url.js#L19) | [tests](test/url.js#L31)) +* **[escape](#escape)** ([code](lib/url.js#L34) | [no tests]) +* **[decodeURI](#decodeURI)** ([code](lib/url.js#L48) | [tests](test/url.js#L38)) +* **[url_encode](#url_encode)** ([code](lib/url.js#L59) | [no tests]) +* **[url_decode](#url_decode)** ([code](lib/url.js#L68) | [no tests]) +* **[urlResolve](#urlResolve)** ([code](lib/url.js#L82) | [tests](test/url.js#L11)) +* **[urlParse](#urlParse)** ([code](lib/url.js#L94) | [tests](test/url.js#L45)) +* **[stripQuerystring](#stripQuerystring)** ([code](lib/url.js#L106) | [tests](test/url.js#L24)) +* **[stripProtocol](#stripProtocol)** ([code](lib/url.js#L126) | [no tests]) + +*** + +## array + +### [{{after}}](lib/array.js#L22) + +Returns all of the items in an array after the specified index. Opposite of [before](#before). + +**Params** + +* `array` **{Array}**: Collection +* `n` **{Number}**: Starting index (number of items to exclude) +* `returns` **{Array}**: Array exluding `n` items. + +**Example** + +```handlebars + +{{after array 1}} + +``` + +### [{{arrayify}}](lib/array.js#L39) + +Cast the given `value` to an array. + +**Params** + +* `value` **{any}** +* `returns` **{Array}** + +**Example** + +```handlebars +{{arrayify "foo"}} + +``` + +### [{{before}}](lib/array.js#L58) + +Return all of the items in the collection before the specified count. Opposite of [after](#after). + +**Params** + +* `array` **{Array}** +* `n` **{Number}** +* `returns` **{Array}**: Array excluding items after the given number. + +**Example** + +```handlebars + +{{before array 2}} + +``` + +### [{{eachIndex}}](lib/array.js#L77) + +**Params** + +* `array` **{Array}** +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{#eachIndex array}} + {{item}} is {{index}} +{{/eachIndex}} +``` + +### [{{filter}}](lib/array.js#L102) + +Block helper that filters the given array and renders the block for values that evaluate to `true`, otherwise the inverse block is returned. + +**Params** + +* `array` **{Array}** +* `value` **{any}** +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{#filter array "foo"}}AAA{{else}}BBB{{/filter}} + +``` + +### [{{first}}](lib/array.js#L142) + +Returns the first item, or first `n` items of an array. + +**Params** + +* `array` **{Array}** +* `n` **{Number}**: Number of items to return, starting at `0`. +* `returns` **{Array}** + +**Example** + +```handlebars +{{first "['a', 'b', 'c', 'd', 'e']" 2}} + +``` + +### [{{forEach}}](lib/array.js#L184) + +Iterates over each item in an array and exposes the current item in the array as context to the inner block. In addition to the current array item, the helper exposes the following variables to the inner block: + +* `index` +* `total` +* `isFirst` +* `isLast` +Also, `@index` is exposed as a private variable, and additional +private variables may be defined as hash arguments. + +**Params** + +* `array` **{Array}** +* `returns` **{String}** + +**Example** + +```handlebars + + +{{#forEach accounts}} + + {{ name }} + {{#unless isLast}}, {{/unless}} +{{/forEach}} +``` + +### [{{inArray}}](lib/array.js#L224) + +Block helper that renders the block if an array has the given `value`. Optionally specify an inverse block to render when the array does not have the given value. + +**Params** + +* `array` **{Array}** +* `value` **{any}** +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{#inArray array "d"}} + foo +{{else}} + bar +{{/inArray}} + +``` + +### [{{isArray}}](lib/array.js#L244) + +Returns true if `value` is an es5 array. + +**Params** + +* `value` **{any}**: The value to test. +* `returns` **{Boolean}** + +**Example** + +```handlebars +{{isArray "abc"}} + + + +{{isArray array}} + +``` + +### [{{itemAt}}](lib/array.js#L263) + +Returns the item from `array` at index `idx`. + +**Params** + +* `array` **{Array}** +* `idx` **{Number}** +* `returns` **{any}** `value` + +**Example** + +```handlebars + +{{itemAt array 1}} + +``` + +### [{{join}}](lib/array.js#L294) + +Join all elements of array into a string, optionally using a given separator. + +**Params** + +* `array` **{Array}** +* `separator` **{String}**: The separator to use. Defaults to `,`. +* `returns` **{String}** + +**Example** + +```handlebars + +{{join array}} + + +{{join array '-'}} + +``` + +### [{{equalsLength}}](lib/array.js#L313) + +Returns true if the the length of the given `value` is equal +to the given `length`. Can be used as a block or inline helper. + +**Params** + +* `value` **{Array|String}** +* `length` **{Number}** +* `options` **{Object}** +* `returns` **{String}** + +### [{{last}}](lib/array.js#L349) + +Returns the last item, or last `n` items of an array or string. Opposite of [first](#first). + +**Params** + +* `value` **{Array|String}**: Array or string. +* `n` **{Number}**: Number of items to return from the end of the array. +* `returns` **{Array}** + +**Example** + +```handlebars + + +{{last value}} + + +{{last value 2}} + + +{{last value 3}} + +``` + +### [{{length}}](lib/array.js#L379) + +Returns the length of the given string or array. + +**Params** + +* `value` **{Array|Object|String}** +* `returns` **{Number}**: The length of the value. + +**Example** + +```handlebars +{{length '["a", "b", "c"]'}} + + + +{{length myArray}} + + + +{{length myObject}} + +``` + +### [{{lengthEqual}}](lib/array.js#L395) + +Alias for [equalsLength](#equalsLength) + +### [{{map}}](lib/array.js#L414) + +Returns a new array, created by calling `function` on each element of the given `array`. For example, + +**Params** + +* `array` **{Array}** +* `fn` **{Function}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{map array double}} + +``` + +### [{{pluck}}](lib/array.js#L445) + +Map over the given object or array or objects and create an array of values from the given `prop`. Dot-notation may be used (as a string) to get nested properties. + +**Params** + +* `collection` **{Array|Object}** +* `prop` **{Function}** +* `returns` **{String}** + +**Example** + +```handlebars +// {{pluck items "data.title"}} + +``` + +### [{{reverse}}](lib/array.js#L473) + +Reverse the elements in an array, or the characters in a string. + +**Params** + +* `value` **{Array|String}** +* `returns` **{Array|String}**: Returns the reversed string or array. + +**Example** + +```handlebars + +{{reverse value}} + + +{{reverse value}} + +``` + +### [{{some}}](lib/array.js#L504) + +Block helper that returns the block if the callback returns true for some value in the given array. + +**Params** + +* `array` **{Array}** +* `iter` **{Function}**: Iteratee +* **{Options}**: Handlebars provided options object +* `returns` **{String}** + +**Example** + +```handlebars + +{{#some array isString}} + Render me if the array has a string. +{{else}} + Render me if it doesn't. +{{/some}} + +``` + +### [{{sort}}](lib/array.js#L532) + +Sort the given `array`. If an array of objects is passed, you may optionally pass a `key` to sort on as the second argument. You may alternatively pass a sorting function as the second argument. + +**Params** + +* `array` **{Array}**: the array to sort. +* `key` **{String|Function}**: The object key to sort by, or sorting function. + +**Example** + +```handlebars + +{{sort array}} + +``` + +### [{{sortBy}}](lib/array.js#L557) + +Sort an `array`. If an array of objects is passed, you may optionally pass a `key` to sort on as the second argument. You may alternatively pass a sorting function as the second argument. + +**Params** + +* `array` **{Array}**: the array to sort. +* `props` **{String|Function}**: One or more properties to sort by, or sorting functions to use. + +**Example** + +```handlebars + +{{sortBy array "a"}} + +``` + +### [{{withAfter}}](lib/array.js#L588) + +Use the items in the array _after_ the specified index as context inside a block. Opposite of [withBefore](#withBefore). + +**Params** + +* `array` **{Array}** +* `idx` **{Number}** +* `options` **{Object}** +* `returns` **{Array}** + +**Example** + +```handlebars + +{{#withAfter array 3}} + {{this}} +{{/withAfter}} + +``` + +### [{{withBefore}}](lib/array.js#L618) + +Use the items in the array _before_ the specified index as context inside a block. Opposite of [withAfter](#withAfter). + +**Params** + +* `array` **{Array}** +* `idx` **{Number}** +* `options` **{Object}** +* `returns` **{Array}** + +**Example** + +```handlebars + +{{#withBefore array 3}} + {{this}} +{{/withBefore}} + +``` + +### [{{withFirst}}](lib/array.js#L648) + +Use the first item in a collection inside a handlebars block expression. Opposite of [withLast](#withLast). + +**Params** + +* `array` **{Array}** +* `idx` **{Number}** +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{#withFirst array}} + {{this}} +{{/withFirst}} + +``` + +### [{{withGroup}}](lib/array.js#L692) + +Block helper that groups array elements by given group `size`. + +**Params** + +* `array` **{Array}**: The array to iterate over +* `size` **{Number}**: The desired length of each array "group" +* `options` **{Object}**: Handlebars options +* `returns` **{String}** + +**Example** + +```handlebars + +{{#withGroup array 4}} + {{#each this}} + {{.}} + {{each}} +
+{{/withGroup}} + + + +``` + +### [{{withLast}}](lib/array.js#L727) + +Use the last item or `n` items in an array as context inside a block. Opposite of [withFirst](#withFirst). + +**Params** + +* `array` **{Array}** +* `idx` **{Number}**: The starting index. +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{#withLast array}} + {{this}} +{{/withLast}} + +``` + +### [{{withSort}}](lib/array.js#L766) + +Block helper that sorts a collection and exposes the sorted collection as context inside the block. + +**Params** + +* `array` **{Array}** +* `prop` **{String}** +* `options` **{Object}**: Specify `reverse="true"` to reverse the array. +* `returns` **{String}** + +**Example** + +```handlebars + +{{#withSort array}}{{this}}{{/withSort}} + +``` + +### [{{unique}}](lib/array.js#L816) + +Block helper that return an array with all duplicate values removed. Best used along with a [each](#each) helper. + +**Params** + +* `array` **{Array}** +* `options` **{Object}** +* `returns` **{Array}** + +**Example** + +```handlebars + +{{#each (unique array)}}{{.}}{{/each}} + +``` + +## code + +### [{{embed}}](lib/code.js#L23) + +Embed code from an external file as preformatted text. + +**Params** + +* `filepath` **{String}**: filepath to the file to embed. +* `language` **{String}**: Optionally specify the language to use for syntax highlighting. +* `returns` **{String}** + +**Example** + +```handlebars +{{embed 'path/to/file.js'}} + +{{embed 'path/to/file.hbs' 'html')}} +``` + +### [{{gist}}](lib/code.js#L45) + +Embed a GitHub Gist using only the id of the Gist + +**Params** + +* `id` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{gist "12345"}} +``` + +### [{{jsfiddle}}](lib/code.js#L60) + +Generate the HTML for a jsFiddle link with the given `params` + +**Params** + +* `params` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars +{{jsfiddle id="0dfk10ks" tabs="true"}} +``` + +## collection + +### [{{isEmpty}}](lib/collection.js#L31) + +Inline, subexpression, or block helper that returns true (or the block) if the given collection is empty, or false (or the inverse block, if supplied) if the colleciton is not empty. + +**Params** + +* `collection` **{Object}** +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{#isEmpty array}}AAA{{else}}BBB{{/isEmpty}} + + + +{{isEmpty array}} + +``` + +### [{{iterate}}](lib/collection.js#L59) + +Block helper that iterates over an array or object. If +an array is given, `.forEach` is called, or if an object +is given, `.forOwn` is called, otherwise the inverse block +is returned. + +**Params** + +* `collection` **{Object|Array}**: The collection to iterate over +* `options` **{Object}** +* `returns` **{String}** + +## comparison + +### [{{and}}](lib/comparison.js#L27) + +Helper that renders the block if **both** of the given values are truthy. If an inverse block is specified it will be rendered when falsy. Works as a block helper, inline helper or subexpression. + +**Params** + +* `a` **{any}** +* `b` **{any}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}** + +**Example** + +```handlebars + +{{#and great magnificent}}A{{else}}B{{/and}} + +``` + +### [{{compare}}](lib/comparison.js#L57) + +Render a block when a comparison of the first and third +arguments returns true. The second argument is +the [arithemetic operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators) to use. You may also +optionally specify an inverse block to render when falsy. + +**Params** + +* `a` **{}** +* `operator` **{}**: The operator to use. Operators must be enclosed in quotes: `">"`, `"="`, `"<="`, and so on. +* `b` **{}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or if specified the inverse block is rendered if falsey. + +### [{{contains}}](lib/comparison.js#L124) + +Block helper that renders the block if `collection` has the given `value`, using strict equality (`===`) for comparison, otherwise the inverse block is rendered (if specified). If a `startIndex` is specified and is negative, it is used as the offset from the end of the collection. + +**Params** + +* `collection` **{Array|Object|String}**: The collection to iterate over. +* `value` **{any}**: The value to check for. +* `[startIndex=0]` **{Number}**: Optionally define the starting index. +* `options` **{Object}**: Handlebars provided options object. + +**Example** + +```handlebars + +{{#contains array "d"}} + This will not be rendered. +{{else}} + This will be rendered. +{{/contains}} +``` + +### [{{default}}](lib/comparison.js#L143) + +Returns the first value that is not undefined, otherwise the "default" value is returned. + +**Params** + +* `value` **{any}** +* `defaultValue` **{any}** +* `returns` **{String}** + +### [{{eq}}](lib/comparison.js#L165) + +Block helper that renders a block if `a` is **equal to** `b`. +If an inverse block is specified it will be rendered when falsy. +You may optionally use the `compare=""` hash argument for the +second value. + +**Params** + +* `a` **{String}** +* `b` **{String}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{gt}}](lib/comparison.js#L188) + +Block helper that renders a block if `a` is **greater than** `b`. + +If an inverse block is specified it will be rendered when falsy. +You may optionally use the `compare=""` hash argument for the +second value. + +**Params** + +* `a` **{String}** +* `b` **{String}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{gte}}](lib/comparison.js#L212) + +Block helper that renders a block if `a` is **greater than or equal to** `b`. + +If an inverse block is specified it will be rendered when falsy. +You may optionally use the `compare=""` hash argument for the +second value. + +**Params** + +* `a` **{String}** +* `b` **{String}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{has}}](lib/comparison.js#L232) + +Block helper that renders a block if `value` has `pattern`. +If an inverse block is specified it will be rendered when falsy. + +**Params** + +* `val` **{any}**: The value to check. +* `pattern` **{any}**: The pattern to check for. +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}** + +### [{{isFalsey}}](lib/comparison.js#L274) + +Returns true if the given `value` is falsey. Uses the [falsey](https://github.com/jonschlinkert/falsey) +library for comparisons. Please see that library for more information +or to report bugs with this helper. + +**Params** + +* `val` **{any}** +* `options` **{Options}** +* `returns` **{Boolean}** + +### [{{isTruthy}}](lib/comparison.js#L289) + +Returns true if the given `value` is truthy. Uses the [falsey](https://github.com/jonschlinkert/falsey) +library for comparisons. Please see that library for more information +or to report bugs with this helper. + +**Params** + +* `val` **{any}** +* `options` **{Options}** +* `returns` **{Boolean}** + +### [{{ifEven}}](lib/comparison.js#L310) + +Return true if the given value is an even number. + +**Params** + +* `number` **{Number}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +**Example** + +```handlebars +{{#ifEven value}} + render A +{{else}} + render B +{{/ifEven}} +``` + +### [{{ifNth}}](lib/comparison.js#L327) + +Conditionally renders a block if the remainder is zero when +`a` operand is divided by `b`. If an inverse block is specified +it will be rendered when the remainder is **not zero**. + +**Params** + +* **{}**: {Number} +* **{}**: {Number} +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{ifOdd}}](lib/comparison.js#L350) + +Block helper that renders a block if `value` is **an odd number**. If an inverse block is specified it will be rendered when falsy. + +**Params** + +* `value` **{Object}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +**Example** + +```handlebars +{{#ifOdd value}} + render A +{{else}} + render B +{{/ifOdd}} +``` + +### [{{is}}](lib/comparison.js#L367) + +Block helper that renders a block if `a` is **equal to** `b`. +If an inverse block is specified it will be rendered when falsy. +Similar to [eq](#eq) but does not do strict equality. + +**Params** + +* `a` **{any}** +* `b` **{any}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}** + +### [{{isnt}}](lib/comparison.js#L389) + +Block helper that renders a block if `a` is **not equal to** `b`. +If an inverse block is specified it will be rendered when falsy. +Similar to [unlessEq](#unlesseq) but does not use strict equality for +comparisons. + +**Params** + +* `a` **{String}** +* `b` **{String}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}** + +### [{{lt}}](lib/comparison.js#L411) + +Block helper that renders a block if `a` is **less than** `b`. + +If an inverse block is specified it will be rendered when falsy. +You may optionally use the `compare=""` hash argument for the +second value. + +**Params** + +* `context` **{Object}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{lte}}](lib/comparison.js#L435) + +Block helper that renders a block if `a` is **less than or equal to** `b`. + +If an inverse block is specified it will be rendered when falsy. +You may optionally use the `compare=""` hash argument for the +second value. + +**Params** + +* `a` **{Sring}** +* `b` **{Sring}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{neither}}](lib/comparison.js#L456) + +Block helper that renders a block if **neither of** the given values +are truthy. If an inverse block is specified it will be rendered +when falsy. + +**Params** + +* `a` **{any}** +* `b` **{any}** +* `options` **{}**: Handlebars options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{not}}](lib/comparison.js#L470) + +Returns true if `val` is falsey. Works as a block or inline helper. + +**Params** + +* `val` **{String}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}** + +### [{{or}}](lib/comparison.js#L492) + +Block helper that renders a block if **any of** the given values is truthy. If an inverse block is specified it will be rendered when falsy. + +**Params** + +* `arguments` **{...any}**: Variable number of arguments +* `options` **{Object}**: Handlebars options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +**Example** + +```handlebars +{{#or a b c}} + If any value is true this will be rendered. +{{/or}} +``` + +### [{{unlessEq}}](lib/comparison.js#L518) + +Block helper that always renders the inverse block **unless `a` is +is equal to `b`**. + +**Params** + +* `a` **{String}** +* `b` **{String}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Inverse block by default, or block if falsey. + +### [{{unlessGt}}](lib/comparison.js#L538) + +Block helper that always renders the inverse block **unless `a` is +is greater than `b`**. + +**Params** + +* `a` **{Object}**: The default value +* `b` **{Object}**: The value to compare +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Inverse block by default, or block if falsey. + +### [{{unlessLt}}](lib/comparison.js#L558) + +Block helper that always renders the inverse block **unless `a` is +is less than `b`**. + +**Params** + +* `a` **{Object}**: The default value +* `b` **{Object}**: The value to compare +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{unlessGteq}}](lib/comparison.js#L578) + +Block helper that always renders the inverse block **unless `a` is +is greater than or equal to `b`**. + +**Params** + +* `a` **{any}** +* `b` **{any}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +### [{{unlessLteq}}](lib/comparison.js#L598) + +Block helper that always renders the inverse block **unless `a` is +is less than or equal to `b`**. + +**Params** + +* `a` **{any}** +* `b` **{any}** +* `options` **{Object}**: Handlebars provided options object +* `returns` **{String}**: Block, or inverse block if specified and falsey. + +## date + +### [{{year}}](lib/date.js#L15) + +Get the current year. + +**Example** + +```handlebars +{{year}} + +``` + +### [{{moment}}](lib/date.js#L24) + +Use [moment](http://momentjs.com) as a helper. See [helper-date](https://github.com/jonathas/helper-date) for more details. + +## fs + +### [{{read}}](lib/fs.js#L29) + +Read a file from the file system. This is useful in composing "include"-style helpers using sub-expressions. + +**Params** + +* `filepath` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{read "a/b/c.js"}} +{{someHelper (read "a/b/c.md")}} +``` + +### [{{readdir}}](lib/fs.js#L42) + +Return an array of files from the given +directory. + +**Params** + +* `directory` **{String}** +* `returns` **{Array}** + +## html + +### [{{attr}}](lib/html.js#L23) + +Stringify attributes on the options `hash`. + +**Params** + +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars + + + +{{css stylesheets}} + + + + +``` + +### [{{js}}](lib/html.js#L89) + +Generate one or more `` tags with paths/urls to javascript or coffeescript files. + +**Params** + +* `context` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars +{{js scripts}} +``` + +### [{{sanitize}}](lib/html.js#L121) + +Strip HTML tags from a string, so that only the text nodes are preserved. + +**Params** + +* `str` **{String}**: The string of HTML to sanitize. +* `returns` **{String}** + +**Example** + +```handlebars +{{sanitize "foo"}} + +``` + +### [{{ul}}](lib/html.js#L135) + +Block helper for creating unordered lists (``) + +**Params** + +* `context` **{Object}** +* `options` **{Object}** +* `returns` **{String}** + +### [{{ol}}](lib/html.js#L154) + +Block helper for creating ordered lists (`
    `) + +**Params** + +* `context` **{Object}** +* `options` **{Object}** +* `returns` **{String}** + +### [{{thumbnailImage}}](lib/html.js#L176) + +Returns a `
    ` with a thumbnail linked to a full picture + +**Params** + +* `context` **{Object}**: Object with values/attributes to add to the generated elements: +* `context.alt` **{String}** +* `context.src` **{String}** +* `context.width` **{Number}** +* `context.height` **{Number}** +* `returns` **{String}**: HTML `
    ` element with image and optional caption/link. + +## i18n + +### [{{i18n}}](lib/i18n.js#L18) + +i18n helper. See [button-i18n](https://github.com/assemble/buttons) +for a working example. + +**Params** + +* `key` **{String}** +* `options` **{Object}** +* `returns` **{String}** + +## inflection + +### [{{inflect}}](lib/inflection.js#L30) + +Returns either the `singular` or `plural` inflection of a word based on the given `count`. + +**Params** + +* `count` **{Number}** +* `singular` **{String}**: The singular form +* `plural` **{String}**: The plural form +* `includeCount` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{inflect 0 "string" "strings"}} + +{{inflect 1 "string" "strings"}} + +{{inflect 1 "string" "strings" true}} + +{{inflect 2 "string" "strings"}} + +{{inflect 2 "string" "strings" true}} + +``` + +### [{{ordinalize}}](lib/inflection.js#L58) + +Returns an ordinalized number as a string. + +**Params** + +* `val` **{String}**: The value to ordinalize. +* `returns` **{String}**: The ordinalized number + +**Example** + +```handlebars +{{ordinalize 1}} + +{{ordinalize 21}} + +{{ordinalize 29}} + +{{ordinalize 22}} + +``` + +## logging + +[logging-helpers](https://github.com/jonathas/logging-helpers). + +## markdown + +### [{{markdown}}](lib/markdown.js#L28) + +Block helper that converts a string of inline markdown to HTML. + +**Params** + +* `context` **{Object}** +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars +{{#markdown}} +# Foo +{{/markdown}} + +``` + +### [{{md}}](lib/markdown.js#L55) + +Read a markdown file from the file system and inject its contents after converting it to HTML. + +**Params** + +* `context` **{Object}** +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars +{{md "foo/bar.md"}} +``` + +## match + +### [{{match}}](lib/match.js#L23) + +Returns an array of strings that match the given glob pattern(s). Options may be passed on the options hash or locals. + +**Params** + +* `files` **{Array|String}** +* `patterns` **{Array|String}**: One or more glob patterns. +* `locals` **{Object}** +* `options` **{Object}** +* `returns` **{Array}**: Array of matches + +**Example** + +```handlebars +{{match (readdir "foo") "*.js"}} +{{match (readdir "foo") (toRegex "\\.js$")}} +``` + +### [{{isMatch}}](lib/match.js#L47) + +Returns true if a filepath contains the given pattern. Options may be passed on the options hash or locals. + +**Params** + +* `filepath` **{String}** +* `pattern` **{String}** +* `options` **{Object}** +* `returns` **{Boolean}** + +**Example** + +```handlebars +{{isMatch "foo.md" "*.md"}} + +``` + +## math + +### [{{abs}}](lib/math.js#L15) + +Return the magnitude of `a`. + +**Params** + +* `a` **{Number}** +* `returns` **{Number}** + +### [{{add}}](lib/math.js#L31) + +Return the sum of `a` plus `b`. + +**Params** + +* `a` **{Number}** +* `b` **{Number}** +* `returns` **{Number}** + +### [{{avg}}](lib/math.js#L54) + +Returns the average of all numbers in the given array. + +**Params** + +* `array` **{Array}**: Array of numbers to add up. +* `returns` **{Number}** + +**Example** + +```handlebars +{{avg "[1, 2, 3, 4, 5]"}} + +``` + +### [{{ceil}}](lib/math.js#L69) + +Get the `Math.ceil()` of the given value. + +**Params** + +* `value` **{Number}** +* `returns` **{Number}** + +### [{{divide}}](lib/math.js#L84) + +Divide `a` by `b` + +**Params** + +* `a` **{Number}**: numerator +* `b` **{Number}**: denominator + +### [{{floor}}](lib/math.js#L102) + +Get the `Math.floor()` of the given value. + +**Params** + +* `value` **{Number}** +* `returns` **{Number}** + +### [{{minus}}](lib/math.js#L118) + +Return the difference of `a` minus `b`. + +**Params** + +* `a` **{Number}** +* `b` **{Number}** + +### [{{modulo}}](lib/math.js#L137) + +Get the remainder of a division operation. + +**Params** + +* `a` **{Number}** +* `b` **{Number}** +* `returns` **{Number}** + +### [{{multiply}}](lib/math.js#L157) + +Return the product of `a` times `b`. + +**Params** + +* `a` **{Number}**: factor +* `b` **{Number}**: multiplier +* `returns` **{Number}** + +### [{{plus}}](lib/math.js#L175) + +Add `a` by `b`. + +**Params** + +* `a` **{Number}**: factor +* `b` **{Number}**: multiplier + +### [{{random}}](lib/math.js#L194) + +Generate a random number between two values + +**Params** + +* `min` **{Number}** +* `max` **{Number}** +* `returns` **{String}** + +### [{{remainder}}](lib/math.js#L212) + +Get the remainder when `a` is divided by `b`. + +**Params** + +* `a` **{Number}**: a +* `b` **{Number}**: b + +### [{{round}}](lib/math.js#L224) + +Round the given number. + +**Params** + +* `number` **{Number}** +* `returns` **{Number}** + +### [{{subtract}}](lib/math.js#L241) + +Return the product of `a` minus `b`. + +**Params** + +* `a` **{Number}** +* `b` **{Number}** +* `returns` **{Number}** + +### [{{sum}}](lib/math.js#L263) + +Returns the sum of all numbers in the given array. + +**Params** + +* `array` **{Array}**: Array of numbers to add up. +* `returns` **{Number}** + +**Example** + +```handlebars +{{sum "[1, 2, 3, 4, 5]"}} + +``` + +### [{{times}}](lib/math.js#L286) + +Multiply number `a` by number `b`. + +**Params** + +* `a` **{Number}**: factor +* `b` **{Number}**: multiplier +* `returns` **{Number}** + +## misc + +### [{{option}}](lib/misc.js#L26) + +Return the given value of `prop` from `this.options`. + +**Params** + +* `prop` **{String}** +* `returns` **{any}** + +**Example** + +```handlebars + +{{option "a.b.c"}} + +``` + +### [{{noop}}](lib/misc.js#L39) + +Block helper that renders the block without taking any arguments. + +**Params** + +* `options` **{Object}** +* `returns` **{String}** + +### [{{typeOf}}](lib/misc.js#L59) + +Get the native type of the given `value` + +**Params** + +* `value` **{any}** +* `returns` **{String}**: Returns the type of value. + +**Example** + +```handlebars +{{typeOf 1}} +//=> 'number' +{{typeOf "1"}} +//=> 'string' +{{typeOf "foo"}} +//=> 'string' +``` + +### [{{withHash}}](lib/misc.js#L71) + +Block helper that builds the context for the block +from the options hash. + +**Params** + +* `options` **{Object}**: Handlebars provided options object. + +## number + +### [{{bytes}}](lib/number.js#L24) + +Format a number to it's equivalent in bytes. If a string is passed, it's length will be formatted and returned. + +**Examples:** + +* `'foo' => 3 B` +* `13661855 => 13.66 MB` +* `825399 => 825.39 kB` +* `1396 => 1.4 kB` + +**Params** + +* `number` **{Number|String}** +* `returns` **{String}** + +### [{{addCommas}}](lib/number.js#L61) + +Add commas to numbers + +**Params** + +* `num` **{Number}** +* `returns` **{Number}** + +### [{{phoneNumber}}](lib/number.js#L74) + +Convert a string or number to a formatted phone number. + +**Params** + +* `num` **{Number|String}**: The phone number to format, e.g. `8005551212` +* `returns` **{Number}**: Formatted phone number: `(800) 555-1212` + +### [{{toAbbr}}](lib/number.js#L92) + +Abbreviate numbers to the given number of `precision`. This is for +general numbers, not size in bytes. + +**Params** + +* `number` **{Number}** +* `precision` **{Number}** +* `returns` **{String}** + +### [{{toExponential}}](lib/number.js#L130) + +Returns a string representing the given number in exponential notation. + +**Params** + +* `number` **{Number}** +* `fractionDigits` **{Number}**: Optional. An integer specifying the number of digits to use after the decimal point. Defaults to as many digits as necessary to specify the number. +* `returns` **{Number}** + +**Example** + +```handlebars +{{toExponential number digits}}; +``` + +### [{{toFixed}}](lib/number.js#L153) + +Formats the given number using fixed-point notation. + +**Params** + +* `number` **{Number}** +* `digits` **{Number}**: (Optional) The number of digits to appear after the decimal point; this may be a value between 0 and 20. If this argument is omitted, it is treated as 0. +* `returns` **{String}**: A string representing the given number using fixed-point notation. + +**Example** + +```handlebars +{{toFixed "1.1234" 2}} +//=> '1.12' +``` + +### [{{toFloat}}](lib/number.js#L169) + +**Params** + +* `number` **{Number}** +* `returns` **{Number}** + +### [{{toInt}}](lib/number.js#L179) + +**Params** + +* `number` **{Number}** +* `returns` **{Number}** + +### [{{toPrecision}}](lib/number.js#L196) + +Returns a string representing the `Number` object to the specified precision. + +**Params** + +* `number` **{Number}** +* `precision` **{Number}**: (Optional) An integer specifying the number of significant digits. If precison is not between 1 and 100 (inclusive), it will be coerced to `0`. +* `returns` **{String}**: A string representing a Number object in fixed-point or exponential notation rounded to precision significant digits. + +**Example** + +```handlebars +{{toPrecision "1.1234" 2}} +//=> '1.1' +``` + +## object + +### [{{extend}}](lib/object.js#L18) + +Extend the context with the properties of other objects. +A shallow merge is performed to avoid mutating the context. + +**Params** + +* `objects` **{Object}**: One or more objects to extend. +* `returns` **{Object}** + +### [{{forIn}}](lib/object.js#L55) + +Block helper that iterates over the properties of +an object, exposing each key and value on the context. + +**Params** + +* `context` **{Object}** +* `options` **{Object}** +* `returns` **{String}** + +### [{{forOwn}}](lib/object.js#L81) + +Block helper that iterates over the **own** properties of +an object, exposing each key and value on the context. + +**Params** + +* `obj` **{Object}**: The object to iterate over. +* `options` **{Object}** +* `returns` **{String}** + +### [{{toPath}}](lib/object.js#L106) + +Take arguments and, if they are string or number, convert them to a dot-delineated object property path. + +**Params** + +* `prop` **{String|Number}**: The property segments to assemble (can be multiple). +* `returns` **{String}** + +### [{{get}}](lib/object.js#L128) + +Use property paths (`a.b.c`) to get a value or nested value from +the context. Works as a regular helper or block helper. + +**Params** + +* `prop` **{String}**: The property to get, optionally using dot notation for nested properties. +* `context` **{Object}**: The context object +* `options` **{Object}**: The handlebars options object, if used as a block helper. +* `returns` **{String}** + +### [{{getObject}}](lib/object.js#L149) + +Use property paths (`a.b.c`) to get an object from +the context. Differs from the `get` helper in that this +helper will return the actual object, including the +given property key. Also, this helper does not work as a +block helper. + +**Params** + +* `prop` **{String}**: The property to get, optionally using dot notation for nested properties. +* `context` **{Object}**: The context object +* `returns` **{String}** + +### [{{hasOwn}}](lib/object.js#L167) + +Return true if `key` is an own, enumerable property of the given `context` object. + +**Params** + +* `key` **{String}** +* `context` **{Object}**: The context object. +* `returns` **{Boolean}** + +**Example** + +```handlebars +{{hasOwn context key}} +``` + +### [{{isObject}}](lib/object.js#L183) + +Return true if `value` is an object. + +**Params** + +* `value` **{String}** +* `returns` **{Boolean}** + +**Example** + +```handlebars +{{isObject "foo"}} +//=> false +``` + +### [{{JSONparse}}](lib/object.js#L201) + +Parses the given string using `JSON.parse`. + +**Params** + +* `string` **{String}**: The string to parse + +**Example** + +```handlebars + +{{JSONparse string}} + +``` + +### [{{JSONstringify}}](lib/object.js#L218) + +Stringify an object using `JSON.stringify`. + +**Params** + +* `obj` **{Object}**: Object to stringify +* `returns` **{String}** + +**Example** + +```handlebars + +{{JSONstringify object}} + +``` + +### [{{merge}}](lib/object.js#L235) + +Deeply merge the properties of the given `objects` with the +context object. + +**Params** + +* `object` **{Object}**: The target object. Pass an empty object to shallow clone. +* `objects` **{Object}** +* `returns` **{Object}** + +### [{{pick}}](lib/object.js#L267) + +Pick properties from the context object. + +**Params** + +* `properties` **{Array|String}**: One or more properties to pick. +* `context` **{Object}** +* `options` **{Object}**: Handlebars options object. +* `returns` **{Object}**: Returns an object with the picked values. If used as a block helper, the values are passed as context to the inner block. If no values are found, the context is passed to the inverse block. + +## path + +### [{{absolute}}](lib/path.js#L20) + +Get the directory path segment from the given `filepath`. + +**Params** + +* `ext` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{absolute "docs/toc.md"}} + +``` + +### [{{dirname}}](lib/path.js#L40) + +Get the directory path segment from the given `filepath`. + +**Params** + +* `ext` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{dirname "docs/toc.md"}} + +``` + +### [{{relative}}](lib/path.js#L59) + +Get the relative filepath from `a` to `b`. + +**Params** + +* `a` **{String}** +* `b` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{relative a b}} +``` + +### [{{basename}}](lib/path.js#L81) + +Get the file extension from the given `filepath`. + +**Params** + +* `ext` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{basename "docs/toc.md"}} + +``` + +### [{{stem}}](lib/path.js#L100) + +Get the "stem" from the given `filepath`. + +**Params** + +* `filepath` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{stem "docs/toc.md"}} + +``` + +### [{{extname}}](lib/path.js#L119) + +Get the file extension from the given `filepath`. + +**Params** + +* `filepath` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{extname "docs/toc.md"}} + +``` + +### [{{resolve}}](lib/path.js#L138) + +Resolve an absolute path from the given `filepath`. + +**Params** + +* `filepath` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{resolve "docs/toc.md"}} + +``` + +### [{{segments}}](lib/path.js#L166) + +Get specific (joined) segments of a file path by passing a range of array indices. + +**Params** + +* `filepath` **{String}**: The file path to split into segments. +* `returns` **{String}**: Returns a single, joined file path. + +**Example** + +```handlebars +{{segments "a/b/c/d" "2" "3"}} + + +{{segments "a/b/c/d" "1" "3"}} + + +{{segments "a/b/c/d" "1" "2"}} + +``` + +## regex + +### [{{toRegex}}](lib/regex.js#L19) + +Convert the given string to a regular expression. + +**Params** + +* `str` **{String}** +* `returns` **{RegExp}** + +**Example** + +```handlebars +{{toRegex "foo"}} + +``` + +### [{{test}}](lib/regex.js#L42) + +Returns true if the given `str` matches the given regex. A regex can be passed on the context, or using the [toRegex](#toregex) helper as a subexpression. + +**Params** + +* `str` **{String}** +* `returns` **{RegExp}** + +**Example** + +```handlebars +{{test "bar" (toRegex "foo")}} + +{{test "foobar" (toRegex "foo")}} + +{{test "foobar" (toRegex "^foo$")}} + +``` + +## string + +### [{{append}}](lib/string.js#L22) + +Append the specified `suffix` to the given string. + +**Params** + +* `str` **{String}** +* `suffix` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{append item.stem ".html"}} + +``` + +### [{{camelcase}}](lib/string.js#L41) + +camelCase the characters in the given `string`. + +**Params** + +* `string` **{String}**: The string to camelcase. +* `returns` **{String}** + +**Example** + +```handlebars +{{camelcase "foo bar baz"}}; + +``` + +### [{{capitalize}}](lib/string.js#L60) + +Capitalize the first word in a sentence. + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{capitalize "foo bar baz"}} + +``` + +### [{{capitalizeAll}}](lib/string.js#L77) + +Capitalize all words in a string. + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{capitalizeAll "foo bar baz"}} + +``` + +### [{{center}}](lib/string.js#L95) + +Center a string using non-breaking spaces + +**Params** + +* `str` **{String}** +* `spaces` **{String}** +* `returns` **{String}** + +### [{{chop}}](lib/string.js#L125) + +Like trim, but removes both extraneous whitespace **and non-word characters** from the beginning and end of a string. + +**Params** + +* `string` **{String}**: The string to chop. +* `returns` **{String}** + +**Example** + +```handlebars +{{chop "_ABC_"}} + + +{{chop "-ABC-"}} + + +{{chop " ABC "}} + +``` + +### [{{dashcase}}](lib/string.js#L143) + +dash-case the characters in `string`. Replaces non-word characters and periods with hyphens. + +**Params** + +* `string` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{dashcase "a-b-c d_e"}} + +``` + +### [{{dotcase}}](lib/string.js#L162) + +dot.case the characters in `string`. + +**Params** + +* `string` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{dotcase "a-b-c d_e"}} + +``` + +### [{{downcase}}](lib/string.js#L182) + +Lowercase all of the characters in the given string. Alias for [lowercase](#lowercase). + +**Params** + +* `string` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{downcase "aBcDeF"}} + +``` + +### [{{ellipsis}}](lib/string.js#L202) + +Truncates a string to the specified `length`, and appends it with an elipsis, `…`. + +**Params** + +* `str` **{String}** +* `length` **{Number}**: The desired length of the returned string. +* `returns` **{String}**: The truncated string. + +**Example** + +```handlebars +{{ellipsis (sanitize "foo bar baz"), 7}} + +{{ellipsis "foo bar baz", 7}} + +``` + +### [{{hyphenate}}](lib/string.js#L223) + +Replace spaces in a string with hyphens. + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{hyphenate "foo bar baz qux"}} + +``` + +### [{{isString}}](lib/string.js#L240) + +Return true if `value` is a string. + +**Params** + +* `value` **{String}** +* `returns` **{Boolean}** + +**Example** + +```handlebars +{{isString "foo"}} + +``` + +### [{{lowercase}}](lib/string.js#L256) + +Lowercase all characters in the given string. + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{lowercase "Foo BAR baZ"}} + +``` + +### [{{occurrences}}](lib/string.js#L278) + +Return the number of occurrences of `substring` within the given `string`. + +**Params** + +* `str` **{String}** +* `substring` **{String}** +* `returns` **{Number}**: Number of occurrences + +**Example** + +```handlebars +{{occurrences "foo bar foo bar baz" "foo"}} + +``` + +### [{{pascalcase}}](lib/string.js#L303) + +PascalCase the characters in `string`. + +**Params** + +* `string` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{pascalcase "foo bar baz"}} + +``` + +### [{{pathcase}}](lib/string.js#L323) + +path/case the characters in `string`. + +**Params** + +* `string` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{pathcase "a-b-c d_e"}} + +``` + +### [{{plusify}}](lib/string.js#L343) + +Replace spaces in the given string with pluses. + +**Params** + +* `str` **{String}**: The input string +* `returns` **{String}**: Input string with spaces replaced by plus signs + +**Example** + +```handlebars +{{plusify "foo bar baz"}} + +``` + +### [{{prepend}}](lib/string.js#L363) + +Prepends the given `string` with the specified `prefix`. + +**Params** + +* `str` **{String}** +* `prefix` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars + +{{prepend val "foo-"}} + +``` + +### [{{raw}}](lib/string.js#L385) + +Render a block without processing mustache templates inside the block. + +**Params** + +* `options` **{Object}** +* `returns` **{String}** + +**Example** + +```handlebars +{{{{#raw}}}} +{{foo}} +{{{{/raw}}}} + +``` + +### [{{remove}}](lib/string.js#L413) + +Remove all occurrences of `substring` from the given `str`. + +**Params** + +* `str` **{String}** +* `substring` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{remove "a b a b a b" "a "}} + +``` + +### [{{removeFirst}}](lib/string.js#L432) + +Remove the first occurrence of `substring` from the given `str`. + +**Params** + +* `str` **{String}** +* `substring` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{remove "a b a b a b" "a"}} + +``` + +### [{{replace}}](lib/string.js#L452) + +Replace all occurrences of substring `a` with substring `b`. + +**Params** + +* `str` **{String}** +* `a` **{String}** +* `b` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{replace "a b a b a b" "a" "z"}} + +``` + +### [{{replaceFirst}}](lib/string.js#L473) + +Replace the first occurrence of substring `a` with substring `b`. + +**Params** + +* `str` **{String}** +* `a` **{String}** +* `b` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{replace "a b a b a b" "a" "z"}} + +``` + +### [{{reverse}}](lib/string.js#L492) + +Reverse a string. + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{reverse "abcde"}} + +``` + +### [{{sentence}}](lib/string.js#L509) + +Sentence case the given string + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{sentence "hello world. goodbye world."}} + +``` + +### [{{snakecase}}](lib/string.js#L528) + +snake_case the characters in the given `string`. + +**Params** + +* `string` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{snakecase "a-b-c d_e"}} + +``` + +### [{{split}}](lib/string.js#L547) + +Split `string` by the given `character`. + +**Params** + +* `string` **{String}**: The string to split. +* `returns` **{String}** `character`: Default is an empty string. + +**Example** + +```handlebars +{{split "a,b,c" ","}} + +``` + +### [{{startsWith}}](lib/string.js#L572) + +Tests whether a string begins with the given prefix. + +**Params** + +* `prefix` **{String}** +* `testString` **{String}** +* `options` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{#startsWith "Goodbye" "Hello, world!"}} + Whoops +{{else}} + Bro, do you even hello world? +{{/startsWith}} +``` + +### [{{titleize}}](lib/string.js#L596) + +Title case the given string. + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{titleize "this is title case"}} + +``` + +### [{{trim}}](lib/string.js#L623) + +Removes extraneous whitespace from the beginning and end of a string. + +**Params** + +* `string` **{String}**: The string to trim. +* `returns` **{String}** + +**Example** + +```handlebars +{{trim " ABC "}} + +``` + +### [{{trimLeft}}](lib/string.js#L639) + +Removes extraneous whitespace from the beginning of a string. + +**Params** + +* `string` **{String}**: The string to trim. +* `returns` **{String}** + +**Example** + +```handlebars +{{trim " ABC "}} + +``` + +### [{{trimRight}}](lib/string.js#L657) + +Removes extraneous whitespace from the end of a string. + +**Params** + +* `string` **{String}**: The string to trim. +* `returns` **{String}** + +**Example** + +```handlebars +{{trimRight " ABC "}} + +``` + +### [{{truncate}}](lib/string.js#L680) + +Truncate a string to the specified `length`. Also see [ellipsis](#ellipsis). + +**Params** + +* `str` **{String}** +* `limit` **{Number}**: The desired length of the returned string. +* `suffix` **{String}**: Optionally supply a string to use as a suffix to denote when the string has been truncated. Otherwise an ellipsis (`…`) will be used. +* `returns` **{String}**: The truncated string. + +**Example** + +```handlebars +truncate("foo bar baz", 7); + +truncate(sanitize("foo bar baz", 7)); + +``` + +### [{{truncateWords}}](lib/string.js#L712) + +Truncate a string to have the specified number of words. Also see [truncate](#truncate). + +**Params** + +* `str` **{String}** +* `limit` **{Number}**: The desired length of the returned string. +* `suffix` **{String}**: Optionally supply a string to use as a suffix to denote when the string has been truncated. +* `returns` **{String}**: The truncated string. + +**Example** + +```handlebars +truncateWords("foo bar baz", 1); + +truncateWords("foo bar baz", 2); + +truncateWords("foo bar baz", 3); + +``` + +### [{{upcase}}](lib/string.js#L742) + +Uppercase all of the characters in the given string. Alias for [uppercase](#uppercase). + +**Params** + +* `string` **{String}** +* `returns` **{String}** + +**Example** + +```handlebars +{{upcase "aBcDeF"}} + +``` + +### [{{uppercase}}](lib/string.js#L763) + +Uppercase all of the characters in the given string. If used as a block helper it will uppercase the entire block. This helper does not support inverse blocks. + +**Params** + +* `str` **{String}**: The string to uppercase +* `options` **{Object}**: Handlebars options object +* `returns` **{String}** + +**Example** + +```handlebars +{{uppercase "aBcDeF"}} + +``` + +## url + +### [{{encodeURI}}](lib/url.js#L19) + +Encodes a Uniform Resource Identifier (URI) component +by replacing each instance of certain characters by +one, two, three, or four escape sequences representing +the UTF-8 encoding of the character. + +**Params** + +* `str` **{String}**: The un-encoded string +* `returns` **{String}**: The endcoded string + +### [{{escape}}](lib/url.js#L34) + +Escape the given string by replacing characters with escape sequences. +Useful for allowing the string to be used in a URL, etc. + +**Params** + +* `str` **{String}** +* `returns` **{String}**: Escaped string. + +### [{{decodeURI}}](lib/url.js#L48) + +Decode a Uniform Resource Identifier (URI) component. + +**Params** + +* `str` **{String}** +* `returns` **{String}** + +### [{{url_encode}}](lib/url.js#L59) + +Alias for [encodeURI](#encodeuri). + +### [{{url_decode}}](lib/url.js#L68) + +Alias for [decodeURI](#decodeuri). + +### [{{urlResolve}}](lib/url.js#L82) + +Take a base URL, and a href URL, and resolve them as a +browser would for an anchor tag. + +**Params** + +* `base` **{String}** +* `href` **{String}** +* `returns` **{String}** + +### [{{urlParse}}](lib/url.js#L94) + +Parses a `url` string into an object. + +**Params** + +* `str` **{String}**: URL string +* `returns` **{String}**: Returns stringified JSON + +### [{{stripQuerystring}}](lib/url.js#L106) + +Strip the query string from the given `url`. + +**Params** + +* `url` **{String}** +* `returns` **{String}**: the url without the queryString + +### [{{stripProtocol}}](lib/url.js#L126) + +Strip protocol from a `url`. Useful for displaying media that may have an 'http' protocol on secure connections. + +**Params** + +* `str` **{String}** +* `returns` **{String}**: the url with http protocol stripped + +**Example** + +```handlebars + +{{stripProtocol url}} + +``` + +*** + +## Utils + +The following utils are exposed on `.utils`. + +### [{{changecase}}](lib/utils/index.js#L54) + +Change casing on the given `string`, optionally passing a delimiter to use between words in the returned string. + +**Params** + +* `string` **{String}**: The string to change. +* `returns` **{String}** + +**Example** + +```handlebars +utils.changecase('fooBarBaz'); +//=> 'foo bar baz' + +utils.changecase('fooBarBaz' '-'); +//=> 'foo-bar-baz' +``` + +### [{{random}}](lib/utils/index.js#L80) + +Generate a random number + +**Params** + +* `min` **{Number}** +* `max` **{Number}** +* `returns` **{Number}** + +*** + +## How to Contribute +Now that you've set up your workspace, you're ready to contribute changes to the `fumanchu` repository you can refer to the [CONTRIBUTING](CONTRIBUTING.md) guide. If you have any questions please feel free to ask by creating an issue and label it `question`. + +## License and Copyright +[MIT](LICENSE) and codebase after 2023 will be copyright of Jared Wray. + +This is a fork of [handlebars-helpers]() which is licensed under MIT. Initial copyright of handlebars-helpers: `2013-2015, 2017, Jon Schlinkert, Brian Woodward`. Thank you so much for your effort and building this! We have also continued to list all contributors in `package.json` to ensure that they are recognized. \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..b6cc070 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 1.x.x | :white_check_mark: | + + +## Reporting a Vulnerability + +To report a security vulnerability, please send an email to me@jaredwray.com. Once the issue has been validated, we will open a [Github Security Advisory](https://docs.github.com/en/code-security/repository-security-advisories/about-github-security-advisories-for-repositories), if necessary. + +Once the security advisory has been opened, contributors can collaborate on a private fork to fix the vulnerability. When the issue has been resolved, we will alert users of the past vulnerability by publishing the security advisory. diff --git a/index.js b/index.js index 2875485..686bc23 100644 --- a/index.js +++ b/index.js @@ -1,11 +1,7 @@ const HandlebarsLib = require('handlebars'); const helpers = require('./helpers.js'); -const Handlebars = HandlebarsLib.create(); +const handlebars = HandlebarsLib.create(); +helpers({ handlebars: handlebars }); -function Fumanchu() { - helpers({ handlebars: Handlebars }); - return Handlebars; -} - -module.exports = Fumanchu; +module.exports = handlebars; diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1349c7abd79d12afd1afb24b51898cf00fda4992 GIT binary patch literal 5551 zcmeHLYc!PoyM7#sq!jh$Or)VgnoyWQ2qWpGlxWInC_|ha5U^ z*aXi1_Z~cgP!NQUAS?ty5kPo6f~O#OI)Y~*coYj#@Cb#1Q0NGSg-}o|mySp16ogJk z=q!YeVx=rR!lEE7I>KThEEJd!6px@31f?S=3qb(@H&6o?6hk(O^}!wr9#6;PS$I5( zwFN|>;3;%Gg@vb}m^PiNujC?*PWSrj~rj%Ts(EEF_CDITTZQ92%F;Zf)c zs(}ndgG!JEF=!0jKn+|_jADi`3=f?`VNob3<`3EeqSGmK7KM&tc0mOMS#%1EMPZ@f z9z;Pd1*KC^76k=+Fb|Lk)i4h54bQBvT z_=C29SS&gVg}H)VPysAW0CYh*3>w_RC}AET6RKexpa~3vLr@K5AQ~z` z7U+P+zzx(WwjwMW!hqpHVPh~z@CR)Hu}~CS;PU!070VmN_PM+yOw{t+vGp#G64SUm z9cqRui1M2o8y*fIkLGw7 z4d`qzIa1L)Be_Aqe*x9!7C#ClvUjTzaA&8)6Lpx5l>UoFo%cLBPW{4?pBFuC) z|NpQ5<{TdH=UB~`^b8ME$^+X8y^5;z`G%faN_lW_PvvNJarW%(Kk~?y5Xl<^LPn3eWp8Arx*9&&5+VDo5u~+CJ`Sd15V(Fob zZHr5Myer2qw-lRInK;bM)VO6f?qXJpEGElw)=gd+ar6|;U2<#WW$KTvn|cxSNlG%l z)LlA|{H=C=fHCHrvokotBaWpJr1toUmm|BchQQ3@mm0t5lHlCcHHz2I*s^%~t=REs z`yiXE@2GKNj1HNl zTcBlM^7N3Z;+2oL4*2t&Ewi)evudT4kH@M%(0E~Ec(rLn*ORiN()o3#=EBRPZ8LE! zj#*AxW?Tm;x8Ma?DS#uR-OH{m$o@5vMsy9Y6soG?*@dIjTh8t!%^%5C7}zPo2k!B^diUhgY)J~z=X)$OTJ&Zg;2L>ATEo;3rsrnS{ zqzXNCD$wkbvCByN)RFg7AFX%g#w|!Q`Z@%Hx^!=Ga%(R+sfnrnvOrx!To)JT#ZcP~ zwNWp{vQN&G{7SK(tIlgE-DljUMlPjAy6}qlW*O7%$^z%_pUPgCm~*`plWP*EmhYD- zFLFlTPG38Nfv!KEY*W_o+0Q4n!|0;VT&3bHLwAAIFe;x^)$+o5m&$RJ}V$?M~!zenMnuT41}ec!gWHhn;IgCCzRswQ9Dl=xGoC-J;q zm!9?oDyRBTpGwDqe^wmDm)XMpb5J#SZfo~w@BOvf^PGp=y%%u48N{E@10#cJxw1H~ z6qj#t)9J*#i4(WvShiN zq;*dRG5T&fIR{)Q=R48Tq&eRqkNkz)4*@DoWnZ%&fVo!Yd9k&4Qt8YjY zUrzX?Z}~bmL&nVysp?#`|tk>QB?J3BNohHGQ0}D4#F1NU+j@E}2kvH1_B315j%P*;cP4Z*{B7;1Hg+Vda;6*E{l^=*!#W9* zmOa)w_tr%*)>9SkYed!9ij%Bpq?4oa7MsimhwH7rN3v6w?tb-o8@k;*ad&;Dz7a=d zwDjczH*u@i457h{Yd5(OD$hgSlu(TK&1-RP-25p{GF{2Ov35KN+uuC`Jgy= zCBj0UBDghvFa(Fs5wYO#iTeQ1m?-+DS8v2z6p}8`kFhJB(IKYzCB30 z)O09m9sdofuDbq?32c6`~wDc`aoCS3kl{eX(d5JT=4{H zgfVTIWdAO9sGr+(`%%uyv$#s{W?fhB?wBf5sjjQHf0>(VSg(sv^OSnl!LUgva`?u{ zwc~v5IeVufkUjCX_%MgCW^d<@QbodvqZaAC6OH>dUI$_Afi2-cCfhqrlp= zK^}KiCX~I|yNv99%yGY+^HVkgvbq3T=}qppJ)*z!t{b>36LjKuU84=3A{IFjQ?ss0V^v6RqZo6OF=9Qs>PP&a06@tz{*m7RH!1Xmu)BGz6SkaFA z8_Z~G>!RhAovtvx@`ehADcBw(B~I4E6LSw%HKr7 zsti`)mxm#kwzKvyZAg$WO&$dg`wTuDrn%H?SVqUDW;w~v@XCfT zn&)$eTC!_n)yrM)6E4@yX^~asI!r)E=CvXX`d}Bv}DlO;CK31MTY` zsb4XM^2hgh#(M3jd~&97E0j5&Wf)+W<*7lj(nogrm;DOaP#!ZG`$5!$b0YiI=4IF* z@f3mw-Hf!LzgVJkK>?F`R^y5%T)VAPwW?F>^4tGp_G>}r_ecjU)TsH=f!6R~tWgO% zeL6q>=ovSGX}OGi;v8&POzQ5wWD5}Z{Il?JUye)@bx1VaVE4FtMVG~xdzE4)NC}<& zo*@dcbfc}%o6n`wNuAI=pKt*9bz})+vh3Paws`xT!7^LxhyT4 zQ|g3@Z0TKK`unjld1@V*R(hdPab@V;a6M;fhCthP#YE^3X@M(<O6Ye5X!O%XcCr^jeh*q5_ zJ~BJozGWHKNu?0RQ+m5+WL`lRoOE%Z{-9E&ohbv>c+KG6YA?1_wxB|~I6v>6`$q`_ zTPq6%_E^JCFE=FgxpgzNS9T_mgn4-uBHM-j6LsGvrI(s}9~O-PP9%mnWB!oZBA*Q1 zqutu#?{MerzME|UVFQmv#wGMQllNaHnF;frt8?34C>FvVE;5$X5Ug9z*xRpMsU;$L z8b}1XZ3|`2rIE7<;k&^;AGv%zV#+D%z?;F1+Vkmg5xN548HE_=fuvN7r;&TqH<&}A z(t}&7E3UJtcb!+Iz(Pq5ruIU5%%cqsN$?H+=YUS9^(U1|oiAZqfK{~ZT?Vfe=L1dQ z3ha|##jBL`F#ef52A)%&GM^uzxsrBR1B*})usAS}-mY8D{Er~>Z!=i0vO$))|h(Y#^|CM#W% zs5=PgrgSf?a*vlBwcc)S_I3i6cfBj&nomZ^gKfRAo}uW75^k%dj5ieR>Sp&abG^O? zzzdz+pYcO&(a)yA9y|$`_)$4`$_8XKB>4K(WVHP&6u*c^NtgIt;*{nM%4js~87gJY zTQpe8j79IQ-`t?ub5dtpoOYc{e0Vi?5XhtVMr?kgN(lcSfb-d(e`UoxHp(yh*fe-J zy;dH2#{8NT0{og9t{Z-Jvwh9b6mH5cp{3TrwJu2^ch$(EsTx9i8JTY129-2S))9ZQ zv!&U6TPkk|h7IO9Xr4DyFIit_;S?)hs_w)Gd6O@3`eW$|y1>Eia^#A|> literal 0 HcmV?d00001 diff --git a/package.json b/package.json index 8f46368..fb3c0e2 100644 --- a/package.json +++ b/package.json @@ -140,52 +140,9 @@ "util", "utility" ], - "verb": { - "run": true, - "toc": true, - "tasks": [ - "readme" - ], - "layout": "default", - "copyright": { - "start": "2013" - }, - "plugins": [ - "gulp-format-md" - ], - "related": { - "highlight": "template-helpers", - "list": [ - "assemble", - "template-helpers", - "utils" - ] - }, - "reflinks": [ - "falsey", - "helper-date", - "moment" - ], - "helpers": [ - "helper-changelog", - "helper-coverage" - ], - "lint": { - "reflinks": true - } - }, - "lintDeps": { - "devDependencies": { - "files": { - "patterns": [ - "test/integration/*.js", - "test/support/*.js", - "test/utils/*.js" - ] - } - } - }, - "auto-changelog": { - "output": "./CHANGELOG.md" - } + "browserslist": [ + "last 1 version", + "> 1%", + "not dead" + ] } diff --git a/test/index.js b/test/index.js index 8d196a9..acafae3 100644 --- a/test/index.js +++ b/test/index.js @@ -7,7 +7,7 @@ describe('Fumanchu Template Test', function() { it('should render name correctly', function() { // Use Fumanchu instead of Handlebars const source = 'Hello, {{name}}!'; - const template = Fumanchu().compile(source); + const template = Fumanchu.compile(source); // Render the template with a context const result = template({ name: 'John' }); @@ -16,7 +16,7 @@ describe('Fumanchu Template Test', function() { }); it('should return the sum of two numbers.', function() { - var fn = Fumanchu().compile('{{add value 5}}'); + var fn = Fumanchu.compile('{{add value 5}}'); assert.equal(fn({value: 5}), '10'); }); }); From aa01829316820b0263bb81a79eb658e3239359a9 Mon Sep 17 00:00:00 2001 From: Jared Wray Date: Thu, 24 Aug 2023 15:00:35 -0700 Subject: [PATCH 2/6] updating tests --- .github/workflows/tests.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e97f84a..b4accb8 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,5 +31,4 @@ jobs: - name: Code Coverage uses: codecov/codecov-action@v3 with: - token: ${{ secrets.CODECOV_KEY }} - files: coverage/coverage-final.json \ No newline at end of file + token: ${{ secrets.CODECOV_KEY }} \ No newline at end of file From bb21bca2891f5556ea398087867b5636c272af1a Mon Sep 17 00:00:00 2001 From: Jared Wray Date: Thu, 24 Aug 2023 15:00:41 -0700 Subject: [PATCH 3/6] updating readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 0a4c003..03ea951 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ # fumanchu Handlebars + Helpers Together +[![tests](https://github.com/jaredwray/fumanchu/actions/workflows/tests.yaml/badge.svg)](https://github.com/jaredwray/fumanchu/actions/workflows/tests.yaml) + + This is a drop in replacement for [handlebars](https://github.com/handlebars-lang/handlebars.js) + a supported / forked version of [handlebars-helpers](https://github.com/helpers/handlebars-helpers) as it was not being maintained. Table of Contents From a66ae0b96b6a05461ac5a9b99afff6d6d037a0c2 Mon Sep 17 00:00:00 2001 From: Jared Wray Date: Thu, 24 Aug 2023 15:04:49 -0700 Subject: [PATCH 4/6] updating package and tests --- .github/workflows/tests.yaml | 2 +- package.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b4accb8..12587e4 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: ['14', '16', '18'] + node-version: ['12','14', '16', '18'] steps: - uses: actions/checkout@v3 diff --git a/package.json b/package.json index fb3c0e2..26f9f76 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "helpers-for-handlebars", - "description": "More than 130 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.", - "version": "0.10.11", - "homepage": "https://github.com/jonathas/handlebars-helpers", - "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "name": "fumanchu", + "description": "Handlebars + Helpers = Fumanchu", + "version": "1.0.0", + "homepage": "https://github.com/jaredwray/fumanchu", + "author": "Jared Wray (me@jaredwray.com)", "contributors": [ "Adrián Mugnolo (https://github.com/xymbol)", "Aleš Kotnik (www.draagle.com)", From fbf9fe5f05a8a11eedad61c1061c9ccffc77d3b6 Mon Sep 17 00:00:00 2001 From: Jared Wray Date: Thu, 24 Aug 2023 15:06:36 -0700 Subject: [PATCH 5/6] supporting 14 and up --- .github/workflows/tests.yaml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 12587e4..b4accb8 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: ['12','14', '16', '18'] + node-version: ['14', '16', '18'] steps: - uses: actions/checkout@v3 diff --git a/package.json b/package.json index 26f9f76..12ba0e4 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "main": "index.js", "types": "index.d.ts", "engines": { - "node": ">=12" + "node": ">=14" }, "scripts": { "test": "c8 mocha --reporter list", From 9a87d37248632da27ed88b4278a21b21bd4aaeca Mon Sep 17 00:00:00 2001 From: Jared Wray Date: Thu, 24 Aug 2023 15:10:59 -0700 Subject: [PATCH 6/6] updating readme --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 03ea951..83ca695 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,10 @@ Handlebars + Helpers Together [![tests](https://github.com/jaredwray/fumanchu/actions/workflows/tests.yaml/badge.svg)](https://github.com/jaredwray/fumanchu/actions/workflows/tests.yaml) - +[![codecov](https://codecov.io/gh/jaredwray/fumanchu/graph/badge.svg?token=gtYw78huva)](https://codecov.io/gh/jaredwray/fumanchu) +[![npm version](https://img.shields.io/npm/v/fumanchu.svg)](https://npmjs.com/package/fumanchu) +[![GitHub license](https://img.shields.io/github/license/jaredwray/fumanchu)](https://github.com/jaredwray/fumanchu/blob/master/LICENSE) +[![npm](https://img.shields.io/npm/dm/fumanchu)](https://npmjs.com/package/fumanchu) This is a drop in replacement for [handlebars](https://github.com/handlebars-lang/handlebars.js) + a supported / forked version of [handlebars-helpers](https://github.com/helpers/handlebars-helpers) as it was not being maintained.