npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

text-js-render

v1.0.0

Published

Template rendering with JavaScript flavour.

Downloads

3

Readme

Text Js

license-badge coverage-badge version-badge downloads-badge

Text Js is a weird template language allowing you to put JavaScript code inside any kind of text template. Generating HTML, XML, CSV or even JSON (as useless as it my sound) becomes an easy task with Text Js !

Installation

npm install text-js-render

Usage

As a node module:

const { TextJs } = require("text-js-render");

const template = "<h1>{{text}}</h1>";
const context = { text: "My text" };
const result = new TextJs(template).render(context);

As an esm module:

import { TextJs } from "text-js-render";

const template = "<h1>{{text}}</h1>";
const context = { text: "My text" };
const result = new TextJs(template).render(context);

In the browser:

const { TextJs } = await import(
  "https://unpkg.com/text-js-render@^1.0.0/module/index.js?module"
);

const template = "<h1>{{text}}</h1>";
const context = { text: "My text" };
const result = new TextJs(template).render(context);

Remark: for browser, a minified version is also available at https://unpkg.com/text-js-render@^1.0.0/module/index.min.js?module

Basic example

import { TextJs } from "text-js-render";

// Specify a context
const context = {
  articles: [
    {
      title: "Text Js is amazing !",
      description:
        "Why rendering templates using Function is amazing and more.",
      author: {
        name: "Nathan Prijot",
        email: "[email protected]",
      },
      date: "01-04-23",
    },
  ],
};

// Specify a template
const template = `
{% foreach article in articles %}
    <h3>{{ article.title }}</h3>
    <p>{{ article.description }}</p>
    {% if article.author || article.date %}
        <p>
            {% if article.author %}
                {{ article.author.name }}
                {{ article.author.email ? " (" + article.author.email + ")" : "" }}
            {% endif %}
            {% if article.date %}
                {{ new Date(article.date).toLocaleDateString() }}
            {% endif %}
         </p>
    {% endif %}
{% endforeach %}
`;

// Render your context with the template
// The result is trimmed since we are making HTML
const result = new TextJs(template, { trimResult: true }).render(context);
// Will return "<h3>Text Js is amazing !</h3><p>Why rendering templates using Function is amazing and more.</p><p>Nathan Prijot([email protected])<span>04/01/2023</span></p>"

Inline JavaScript

Inline JavaScript gives you access to the context you passed when rendering. Multiple variations are supported:

Single line output

All the properties in your context are directly available in inline JavaScript. If no return or ; are present in the code, the result of the JavaScript will be directly dumped into the result. You also have direct access to the context itself.

const context = { text: "Hello !" };

const template = `{{ text }}{{ context.text }}{{ return context.text; }}`;

const result = new TextJs(template).render(context);
// Will return "Hello !Hello !Hello !"

Multiple line output

Inline JavaScript can also uses multiple lines. In that case you need to return the value that will be dumped yourself.

const context = { text: "Hello !" };

const template = `
{{ 
  const myText = text + "!!"; 
  return myText;
}}
    `;

const result = new TextJs(template, { trimResult: true }).render(context);
// Will return "Hello !!!"

Inline computation

With a ; and no return. Inline JavaScript does not dump any value. But you can uses these code snippets to change or add properties to the context. However, as this example shows, be aware that the context is scoped for each block and that direct property access have limitations.

const template = `
{{ context.value = 1; }}
{% foreach item in [0, 1, 2, 3] %}
  {{ context.value += 1; }}
{% endforeach %}
{{ value += 1; }}
{{ context.value += 1; }}
{{ value }}
    `;

const result = new TextJs(template, { trimResult: true }).render();
// Will return "2"
// The context in the foreach is scoped to the foreach itself.
// The ability to directly access the context property is a syntax sugar but of course affecting that property will not affect the actual context value.

Available statements

List of available statements:

if, elseif, else, endif

Allows conditioning. The format is the following: if {JavaScript} and elseif {JavaScript}.

new TextJs(`
    {% if foobar === "foo" %}
      Foo
    {% elseif foobar === "bar" %}
      Bar
    {% else %}
      Else
    {% endif %}
  `).render({ foobar: "foo" }, { trimResult: true });
// Will return "Foo"

foreach, endforeach

Allows the iteration of all the items in an array. The format is the following: foreach {itemName}[, {indexName}] in {JavaScript}. You can put any valid JavaScript that returns an array after the in. The indexName is optional. By default the name of the current index will be index.

new TextJs(`
    {% foreach item, index in array %}
      {{index + 1}}. {{ item }}
    {% endforeach %}
  `).render({ array: ["foo", "bar"] }, { trimResult: true });
// Will return "1. foo2. bar"

switch, case, default, endswitch

Allows to switch on a property. The case value allows dynamic values. The format is the following: switch {JavaScript} and case {JavaScript}.

Static cases values example:

new TextJs(`
    {% switch foobar %}
      {% case "foo" %}
        Foo
      {% case "bar" %}
        Bar
      {% default %}
        Default
    {% endswitch %}
  `).render({ foobar: "foo" }, { trimResult: true });
// Will return "Foo"

Dynamic cases values example:

new TextJs(`
    {% switch foobar %}
      {% case fooCase %}
        Foo
      {% case barCase %}
        Bar
    {% endswitch %}
  `).render(
  { foobar: "bar", fooCase: "foo", barCase: "bar" },
  { trimResult: true }
);
// Will return "Bar"

Option

Trim result

By default, Text Js will not remove any of the white-spaces from the template. The trimResult option will remove all the lines returns and all the white-spaces at the start and end of each line:

new TextJs(
  `
    {{text}}   {{text}}
  `,
  { trimResult: true }
).render({
  text: "Hello",
});
// Will return "Hello   hello"

If you still need lines returns or white-spaces, you can insert them with a JavaScript snippet:

new TextJs(`Text{{"\\n"}}Text`).render();
// Will return "Text\nText" (where "\n" is an actual line return in the string)

Custom delimiters

By default, Text Js uses {% and %} for statements. It also uses {{ and }} for inline JavaScript. This can be easily changed via the options provided by the constructor:

const customDelimitersOptions: ITextJsOptions = {
  delimiters: {
    jsStartDelimiter: "?%",
    jsEndDelimiter: "%?",
    statementStartDelimiter: "??",
    statementEndDelimiter: "??",
  },
};

const customDelimitersTemplate =
  "??foreach item in array???%item%???endforeach??";

new TextJs(customDelimitersTemplate, customDelimitersOptions).render({
  array: ["He", "ll", "o !"],
});
// Will return "Hello !"

Custom keywords

You can also change the keyword used for each statement:

const customStatementsOptions: ITextJsOptions = {
  statements: {
    if: "IF",
    elseIf: "ELSEIF",
    else: "ELSE",
    endIf: "ENDIF",
    forEach: "FOREACH",
    endForEach: "ENDFOREACH",
    switch: "SWITCH",
    case: "CASE",
    default: "DEFAULT",
    endSwitch: "ENDSWITCH",
  },
};

const customStatementsTemplate =
  "{%IF bool%}Hello !{%ELSEIF otherBool%}Goodbye !{%ELSE%}Hi !{%ENDIF%}{%FOREACH item in array%}{{item}}{%ENDFOREACH%}{%SWITCH hello%}{%CASE 1%}Hello !{%DEFAULT%}Goodbye !{%ENDSWITCH%}";

new TextJs(customStatementsTemplate, customStatementsOptions).render({
  bool: null,
  otherBool: false,
  array: ["Hel", "lo !"],
  hello: 1,
});
// Will return "Hi !Hello !Hello !"

License

MIT