Skip to content

TEMPJS is a fast, low code and no dependencies templating langage where you can use javascript inside html!

License

Notifications You must be signed in to change notification settings

yoannchb-pro/tempjs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tempjs

TEMPJS is a fast, low code and no dependencies templating langage where you can use javascript inside html !

Table of content

Demo

See a simplified live editor on the github page

Update

NOTE: Use a version upper or equal to 1.0.6 to prevent XSS injection

See the CHANGELOG file

Why tempjs ?

There are several reasons why you should consider using tempjs:

  1. Lightweight: tempjs is less than 5 kilobytes in size, making it a great choice for projects where size matters.

  2. No dependencies: tempjs has no external dependencies, so you won't have to worry about installing and maintaining additional packages.

  3. Written in TypeScript: tempjs is written in TypeScript, which makes it easy to use in modern projects and ensures that it follows best practices.

  4. Fast: tempjs is optimized for rendering templates quickly, so your users won't experience any delays while waiting for content to load.

  5. Cross-platform: tempjs works on any device and has the same properties and functionalities in both Node.js and the browser, making it a versatile tool for rendering templates in any environment.

  6. Customizable: With tempjs, you can add as many custom delimiters and plugins as you want, allowing you to tailor it to your specific needs and make it work exactly the way you want it to.

By choosing tempjs, you can be confident that you're using a reliable and efficient template engine for your web application.

Installation

$ npm i tempjs-template

Or directly in the browser with

<script src="https://unpkg.com/[email protected]/dist/index.js"></script>

Import

import tempjs from "tempjs-template";

Simple example

NOTE: You can use any javascript syntax into the template just ensure to use = operator if you want to return something (never use return)

In this example we render a list and apply a color on the index

const todos = ["Make a chatbot", "Eat an apple", "Do some sports"];
const data = { todos };
document.body.innerHTML = tempjs.compile(
  `
    {%_# I'm just a comment dont worry _%}
    <ul>
        {%_ let index = 0 _%}
        {% for(const todo of todos){ _%}    
            <li style="color: {%= index%2 === 0 ? "red" : "green" %}">{%= todo %}</li>
            {%_ ++index %}
        {%_ } _%}
    </ul>
    `,
  data
);

Simple example with async

Working with async is pretty simple

await tempjs.compile(
  `
    {%_
        const req = await fetch("https://jsonplaceholder.typicode.com/todos/")
        const todos = await req.json()
    _%}
    <ul>
        {%_ for(const todo of todos){ _%}    
            <li>{%= todo.title %}</li>
        {%_ } _%}
    </ul>
    `,
  {
    /*some data here*/
  },
  { async: true }
);

Usage

API

NOTE: The return type is calculed on the options so it will be automatically set to string or Promise<string>. Below is just a simplified version of the return type.

  • tempjs.compile(template: string, data: Record<string, unknown>, options: Options): string | Promise<string>
  • tempjs.compileFromFile(filePath: string, data: Record<string, unknown>, options: Options): string | Promise<string>
  • tempjs.compileFromFileBrowser(filePath: string, data: Record<string, unknown>, options: Options): Promise<string>
  • tempjs.createFunction(filePath: string, data: Record<string, unknown>, options: Options): () => string | Promise<string>
  • tempjs.debug(filePath: string, data: Record<string, unknown>, options: Options): { template, options, data, generatedFunction, generatedCode, dataListName, dataListValue, pluginsName, pluginsFunctions }

Include other template into the current

Include from nodejs

include(filaname: string, data: Record<string, unknown>, options: Options): string | Promise<string>

{%@ include("header.html", { userName: "Yoann" }) %}

Include from browser

NOTE: Don't forget to set the option "async: true" if the file also have an includeBrowser

includeBrowser(filaname: string, data: Record<string, unknown>, options: Options): Promise<string>

{%@ await includeBrowser("header.html", { userName: "Yoann" }) %}

Other Tags

Remove white spaces

NOTE: It can be combined with custom delimiters (example: {%_# I'm a comment _%})

  • {%_ Remove white spaces before the first delimiter
  • _%} Remove white spaces after the last delimiter
{% if(5 > 0){ _%}
<h1>Five is greater than 0</h1>
{%_ } %}

Should compile as follow: <h1>Five is greater than 0</h1>

Additionals delimiters

Return a value

{% const greeting = "Hello World!" %}
<h1>{%= greeting %}</h1>

Should compile as follow: <h1>Hello World!</h1>

Return a value without escaping HTML

XSS injection warning: Only use this with include/includeBrowser or if you are sure about what you are doing

The html will be executed

{% const greeting = "<h1>Hello World!</h1>" %}
{%@ greeting %}

Should compile as follow: <h1>Hello World!</h1>

Writting comments

{%# You can write some comments here it will not be shown or evaluate
console.log("I ll not show") %}
<h1>I love Tempjs</h1>

Should compile as follow: <h1>I love Tempjs</h1>

Skip js instruction

{%% greeting %}

Should compile as follow: {% greeting %}

Options

type Options = {
  openDelimiter?: string;
  closeDelimiter?: string;
  context?: unknown;
  async?: boolean;
  minimified?: boolean;
  root?: string;
  removeWhitespace?: boolean;
  delimiters?: {
    name: string;
    description: string;
    delimiter: string;
    fn: (content: string, options: Options) => string;
  }[];
  plugins?: { name: string; description: string; fn: Function }[];
};
  • openDelimiter (default: {%) : Open delimiter
  • closeDelimiter (default: %}) : Close delimiter
  • context (default: null) : Context of the function
  • async (default: false) : Make asynchronous requests in the template
  • minimified (default: true) : Make the generated code more readable in debug mode
  • root (default: null): Specifie a root directory for including files
  • removeWhitespace (default: false): Remove all whitespace before and after js instruction
  • delimiters : Create customs delimiters. By default you have:
= return a value
@ return a value without escaping HTML
# create a comment
% Ingnore js instruction and display is as text with delimiters

Examples of implementation:

  • Comment
{
    name: "comment",
    description: "Shortcut to turn some code into a comment",
    delimiter: "#",
    fn: function (content, options) {
      return "/*" + content + "*/";
    },
  }
  • Return value
{
    name: "return",
    description: "Allow user to add variable to the output",
    delimiter: "=",
    fn: function (content, options) {
      return `$__output += escapeHTML(${content})`;
    },
},
  • plugins : Create custom acessibles function into the template. By default you have "include" and "includeBrowser" that allow you to render other template into the current template:
include(filaname: string, data: Record<string, unknown>, options: Options): string | Promise<string>
includeBrowser(filaname: string, data: Record<string, unknown>, options: Options): Promise<string>

//Can be useful to create your own plugins
escapeHTML(obj: unknow): unknow //if the obj is a string HTML will be escaped

Example of implementation:

  {
    name: "truncat",
    description: "Truncat some text",
    fn: function(text: string, size: number){
        return text.trim().substring(0, size);
    },
  },