yunta
v0.2.0
Published
A basic template engine for Node.js
Maintainers
Readme
Yunta
Yunta is a basic template engine for Node.js
Installing
npm install yunta[!TIP] We recommend you downloading the yuntajs extension from the vscode marketplace for syntax hightlighting.
Syntax
Yunta's gol is to be as simple as possible, so we provide you with a clean code based on blade (template engine for PHP).
- Delimiters
{{ property_name }}To read object properties as you would when working with JavaScript, by now only accept: user, user.name, etc. as you can see, Yunta allows reading object properties despide its depth.
[!WARNING] Yunta doesn't allow strings (" or ') inside
{{}}, for now. That's a future feature we'll be including.
- Norms
Norms are keywords followed by |>, that provide extra funtionality to the engine.
Example:
|>if[!IMPORTANT] If you use spaces between
|>and keyword, Yunta will recognize it as Text, so we recommend you avoid doing this.
[!TIP] Make sure you have ligatures enabled in your editor to see the code better.
Usage with Express
// Imports
import path from "node:path"
import express from "express"
import { express as yunta } from "yunta"
const app = express()
// Set views folder:
app.set("views", path.resolve("template_folder_path"))
// Set engine:
app.engine("my", yunta())
// Define route for rendering
app.get("/", (req, res) => {
res.render("file_name")
})[!NOTE] Yunta takes the path set in "views" and use it as the default folder path, if you want to tell Yunta to use a different path, must be use the
createFsLoaderfunction, more about this function below.
Options
You don't need to set options to work with Yunta, however Yunta includes some options that might be useful to you at certain times. Let's take a look see at them:
loaderAs we saw previously, Yunta can works without setting default folder path, but you might want to set you own folder path:
For this you need to import the
createFsLoaderfunction:import createFsLoader from "yunta"and then...
const loader = createFsLoader({ baseDir: "folder_path", ext: ".html" }) // Note: ext is optional app.engine("my", yunta({ loader }))This tells Yunta: "Look at files with extension '.html' inside the folder 'folder_path'".
[!IMPORTANT] loader must be a
function
cacheUseful when you want to use your own cache to manage template storage, Must be
Map <name, { value, expiresAt }>.ttlTells Yunta how long to cache template. Must be an
integergreater than 0.devTells Yunta if you're gonna work on production or not. Must be a
boolean.dev: false = cache on dev: true = cache offwatchUseful when you're working on something and don't want to restart the Node server every time you make changes to a file. Must be a
boolean.watchDebounceSet debounce time for watchers. MUst be an
integergreater than 0.
Featuring
Read object variables
If you need to read object property values, you must:
pass the object to the rendering time:
res.render("file_name", { name: "Hector" })and then, use delimiters to read values
<!-- file_name.html --> <p>Hello "{{ name }}"</p>result:
Hello "Hector"Use conditionals
You can also use conditions:
without consequence:
<!-- file_name.html --> |>if(name) <p>Hello "{{ name }}"</p> |>endifwith consequence:
<!-- file_name.html --> |>if(name) <p>Hello "{{ name }}"</p> |>else <p>Hello Desconocido</p> |>endifInclude files
Yunta allows you to include content from other files:
<!-- file_name.html --> <h1>Hola |>include("other_file.html")</h1> <!-- You can also use include like that: |>include "other_file.html" --><!-- other_file.html --> <p>mundo</p>Result:
Hola mundo
API
You can import the following from yunta:
createFsLoader: It's responsible of reading file content based on a given extension and folder path.
import { createFsLoader } from "yunta" // Use: const loader = createFsLoader(options) /* options: an object with base folder path and files extension example -> createFsLoader({ baseDir: "folder", ext: ".html" }) */engine: It's the engine's core, it tells Yunta what to do; reder, clear cache and watchers, ect. it can receive an options object.
import { engine } from "yunta" // Use: engine.render(options) // options: an object with the options seen previously (dev, cache, etc.)express: Integrate the template engine with Express.
// seen previously import { express as yunta } from "yunta"methods: Useful functions for testing the template engine:
runtime: To work with objects, iterate through object and return a value. This method is not useful on its own.compile: It receives a template and passes it through the Lexer, Parser, Compiler and return a wrapped function that receives the parameters "data" andruntimeand with this execute the internal function returned by the Compiler class.render: To test template structures quickly, it makes it easy the use ofcompilefunction and for this it needs both theruntimeandcompilefunctions.import { runtime } from "yunta" import { compile } from "yunta" import { render } from "yunta" // Sintax: render(input, data) // Use: const data = { name: "Hector" } render(`Hello "{{ name }}"`, data) // Result: Hello "Hector"
errors: Finally, we provide you error classes if you want to do trial-error of a specific structure.
LexerError: For invalid characters.ParserError: For malformed structure.CompilerError: For impossible Logic even if the sintax is fine.CompilerError: For errors during data execution.import { LexerError } from "yunta" import { ParserError } from "yunta" import { CompilerError } from "yunta" import { EngineError } from "yunta" try { // You must import engine function first engine.render(...); } catch (err) { if (err instanceof EngineError) { // manejo específico } }
License
MIT
