Search code examples
javascriptexpresshandlebars.jsexpress-handlebars

Express Handlebars getting first letter of every string


Some discord servers don't have icons, and discord renders the icons as the first char of each word in the guilds name. I am trying to do that in handlebars with express. I did the following, but it errored.

<h1>Welcome, {{username}}!</h1>
<ul>
<h2>Your guilds</h2>
{{#each guilds as |key value|}}
    <li>
        {{#if key.icon}}
        <img src="https://cdn.discordapp.com/icons/{{key.id}}/{{key.icon}}?size=64" alt="profile"> </p>{{key.name}}</p>
            {{else}}
            <div>
                <h3>{{ key.name.match(/\b\w/g).join('') }}</h3>
                <p>{{key.name}}</p>
            </div>
        {{/if}}
    </li>
{{/each}}
</ul>

Error

Error: Parse error on line 10:
...    <h3>{{ key.name.match(/\b\w/g).join(
-----------------------^
Expecting 'ID', got 'INVALID'

Solution

  • In Handlebars, you can work with custom helpers functions that handle javascript logic outside the templates. You should make two changes in your project to achieve that:

    1. create a file with custom helpers, normally inside helpers folder in your project:

    ./helpers/hbs.js

    function getFirstLetter(name) {
      return name.match(/\b\w/g).join("");
    }
    
    module.exports = { getFirstLetter };
    
    1. Modify handlebars middleware configuration in the app.js to use custom helpers created by you:

    ./app.js

    /**
     * Import Handlebars
     */
    const exphbs = require("express-handlebars");
    /**
     * Import Custom Helpers
     */
    const hbs = require("./helpers/hbs");
    /**
     * Template Engine
     */
    app.engine(
      ".hbs",
      exphbs({
        ... all configuration here...
        helpers: hbs, // add custom helpers.
      })
    );
    
    

    Now you can use custom helper inside your template like this:

    <h1>Welcome, {{username}}!</h1>
    <ul>
    <h2>Your guilds</h2>
    {{#each guilds as |key value|}}
        <li>
            {{#if key.icon}}
            <img src="https://cdn.discordapp.com/icons/{{key.id}}/{{key.icon}}?size=64" alt="profile"> </p>{{key.name}}</p>
                {{else}}
                <div>
                    <h3>{{getFirstLetter key.name}}</h3>
                    <p>{{key.name}}</p>
                </div>
            {{/if}}
        </li>
    {{/each}}
    </ul>