@pota/twig-server
v1.5.1
Published
A Node.js server to render twig templates, supporting the muban-template
Downloads
7
Readme
@pota/twig-server
A Node.js server to render twig templates, supporting the muban-template. It allows you to easily start this package on your server without installing any dependencies (besides node and npm).
You can extend the Twig Environment to add custom filters and functions.
Usage
Running the server directly:
npx @pota/twig-server
Or using the API:
npm i -D @pota/twig-server
import path from 'path';
import { URL } from 'url';
import { createServer } from '@pota/twig-server';
createServer({
mountPath: '/template',
host: 'localhost',
port: '9003',
useUnixSocket: false,
socketPath: path.resolve(new URL('.', import.meta.url).pathname, './twig-socket'),
templateDir: [
path.resolve(new URL('.', import.meta.url).pathname, '../templates'),
{
admin: path.resolve(new URL('.', import.meta.url).pathname, '../admin-templates'),
},
],
extensionPath: path.resolve(new URL('.', import.meta.url).pathname, './twig-extensions.cjs'),
cors: true,
});
Or using the middleware on an existing server:
import express from 'express';
import { createTwigMiddleWare } from '@pota/twig-server';
const app = express();
// add default middleware
app.use('/component-templates/', createTwigMiddleware());
// or with options
app.use(
'/component-templates/',
createTwigMiddleware('/templates', {
extensionPath: path.resolve(new URL('.', import.meta.url).pathname, './twig-extensions.cjs'),
}),
);
app.listen(9002, 'localhost', () => {
console.info(`http://localhost:9002/component-templates/`);
});
Options
Server options:
mountPath?: string [/component-templates]
- On what path the template endpoint should be mounted. All configured template endpoints will be prefixed by this path.useUnixSocket?: boolean [false]
- Whether to use a unix socket to start the server instead of the defaulthost:port
.socketPath?: string [./socket]
- Where to create the unix socket.host?: string [localhost]
- What port to use.port?: number [9003]
- What host to use.cors?: boolean [false]
- Whether to enable cors for the created server, so it accepts requests from other origins.
Middleware options:
templateDir?: string [./templates]
- Folder where the twig template files can be found, can pass multiple, it tries them in order. Passingname=path
as an argument configures it as Twig namespace for your template includes.extensionPath?: string
- A path to a file that exports anaddExtensions
function to enhance the Twig Environment.// the 2nd parameters exposes the 'twing' import, // so you don't have to import it yourself, and the same instance is shared export function addExtensions(env, { TwingFunction, TwingFilter }) { env.addFunction(new TwingFunction(...)); env.addFilter(new TwingFilter(...)); }
More information can be found in the Twing docs.
CLI usage
Usage: twig-server [options]
Server options:
-m, --mount-path On what path the template endpoint should be mounted. Anything after this path will count as the co
mponent path/id [string] [default: "/component-templates"]
-h, --host The host that will be used to run the server, passed to `app.listen`[string] [default: "localhost"]
-p, --port The port that will be used to run the server, passed to `app.listen` [number] [default: 9003]
-u, --unix-socket Whether to use a unix socket to start the server instead of the default `host:port`. [boolean]
-s, --socket-path Where to create the unix socket. Only needed when `unix-socket` is true. [string]
-c, --cors Whether to enable cors for the created server, so it accepts requests from other origins. [boolean]
Middleware options:
-d, --template-dir Folder where the twig template files can be found, can pass multiple, it tries them in order. Pa
ssing name=path as an argument configures it as Twig namespace for your template includes.
[array] [default: "./templates"]
-e, --extension-path A path to a file that exports an `addExtensions` function to enhance the Twig Environment.
[string]
Options:
--help Show help [boolean]
Examples:
twig-server Start a server on default host and port.
twig-server -h localhost -p 9002 Start a server on a specific host and port
twig-server -u -s ./twig-socket Start a server connected to the socket at that location
twig-server -m component-template Make all template routes available on the "component-template/" path.
twig-server -d ./templates Specify a folder where the template files are located.
twig-server -e ./twig-extensions.cjs Provide a file to enhance the Twig Environment.
twig-server -c Enable cors when starting the server.
Template Rendering
To render a twig template, the server needs to know two things;
- what template to render
- what data to pass to the template
All this information should exist in the request, and there are multiple ways to pass this. Currently we're not support all thinkable use cases, but can expand if the currently supported options give issues.
Template ID
It expects the component filename and folder name to be the same.
The templateId atoms/button
will be resolved to /templates/atoms/button/button.twig
.
This server supports three methods of getting the template id. In all examples component-templates
is the mountPath
option.
1. path from there request url
# request
GET /component-templates/atoms/button
# will load from disk
/templates/atoms/button/button.twig
2. the "templateId" in the query string
# request
GET /component-templates?templateId=atoms/button
# will load from disk
/templates/atoms/button/button.twig
3. the "templateId" in the json body
# request
POST /component-templates
{
"templateId": "atoms/button"
}
# will load from disk
/templates/atoms/button/button.twig
Template Data
This server supports three methods of pulling data from there request, and using that to render the template:
- from individual query parameters
- from the
templateData
query parameter as a encoded JSON string - from the
templateData
JSON body in aPOST
request
The benefit of the latter options is that it supports actual booleans and numbers, and makes nesting
arrays
and objects
easier.
1. Individual query parameters
# example
/component-templates/atoms/button?copy=Hello+World&ref=cta&active=true
Will use parameters
{
"copy": "Hello World",
"ref": "cta",
"active": "true"
}
Note that the
active
boolean
is actually astring
, since everything is a string in the URL.
2. templateData query parameter as JSON
To have more control over the structure and the types of your template data, a nicer way to pass
this is to use JSON. The server checks for the templateData
query parameter, and if that's a
string, it parses the JSON, and uses that to render the template.
# example
/component-templates?templateId=atoms/button&templateData={"copy":"Hello World","ref":"cta","active":true}
Will use parameters
{
"copy": "Hello World",
"ref": "cta",
"active": true
}
3. templateData json body in a POST request
Especially when the data is too much to comfortably put in the URL, it's better to use the POST
.
POST /component-templates
{
"templateId": "atoms/button",
"templateData": {
"copy": "Hello World",
"ref": "cta",
"active": true
}
}
Will use parameters
{
"copy": "Hello World",
"ref": "cta",
"active": true
}