Embedded JavaScript templates for node

Overview

EJS

Embedded JavaScript templates.

Build Status


NOTE: Version 2 of EJS makes some breaking changes with this version (notably, removal of the filters feature). Work on v2 is happening here: https://github.com/mde/ejs

File issues for EJS v2 here: https://github.com/mde/ejs/issues


Installation

$ npm install ejs

Features

  • Complies with the Express view system
  • Static caching of intermediate JavaScript
  • Unbuffered code for conditionals etc <% code %>
  • Escapes html by default with <%= code %>
  • Unescaped buffering with <%- code %>
  • Supports tag customization
  • Filter support for designer-friendly templates
  • Includes
  • Client-side support
  • Newline slurping with <% code -%> or <% -%> or <%= code -%> or <%- code -%>

Example

<% if (user) { %>
    <h2><%= user.name %></h2>
<% } %>

Try out a live example now

Usage

ejs.compile(str, options);
// => Function

ejs.render(str, options);
// => str

Options

  • cache Compiled functions are cached, requires filename
  • filename Used by cache to key caches
  • scope Function execution context
  • debug Output generated function body
  • compileDebug When false no debug instrumentation is compiled
  • client Returns standalone compiled function
  • open Open tag, defaulting to "<%"
  • close Closing tag, defaulting to "%>"
    •             All others are template-local variables
      

Includes

Includes are relative to the template with the include statement, for example if you have "./views/users.ejs" and "./views/user/show.ejs" you would use <% include user/show %>. The included file(s) are literally included into the template, no IO is performed after compilation, thus local variables are available to these included templates.

<ul>
  <% users.forEach(function(user){ %>
    <% include user/show %>
  <% }) %>
</ul>

Custom delimiters

Custom delimiters can also be applied globally:

var ejs = require('ejs');
ejs.open = '{{';
ejs.close = '}}';

Which would make the following a valid template:

<h1>{{= title }}</h1>

Filters

EJS conditionally supports the concept of "filters". A "filter chain" is a designer friendly api for manipulating data, without writing JavaScript.

Filters can be applied by supplying the : modifier, so for example if we wish to take the array [{ name: 'tj' }, { name: 'mape' }, { name: 'guillermo' }] and output a list of names we can do this simply with filters:

Template:

<p><%=: users | map:'name' | join %></p>

Output:

<p>Tj, Mape, Guillermo</p>

Render call:

ejs.render(str, {
    users: [
      { name: 'tj' },
      { name: 'mape' },
      { name: 'guillermo' }
    ]
});

Or perhaps capitalize the first user's name for display:

<p><%=: users | first | capitalize %></p>

Filter list

Currently these filters are available:

  • first
  • last
  • capitalize
  • downcase
  • upcase
  • sort
  • sort_by:'prop'
  • size
  • length
  • plus:n
  • minus:n
  • times:n
  • divided_by:n
  • join:'val'
  • truncate:n
  • truncate_words:n
  • replace:pattern,substitution
  • prepend:val
  • append:val
  • map:'prop'
  • reverse
  • get:'prop'

Adding filters

To add a filter simply add a method to the .filters object:

ejs.filters.last = function(obj) {
  return obj[obj.length - 1];
};

Layouts

Currently EJS has no notion of blocks, only compile-time includes, however you may still utilize this feature to implement "layouts" by simply including a header and footer like so:

<% include head %>
<h1>Title</h1>
<p>My page</p>
<% include foot %>

client-side support

include ./ejs.js or ./ejs.min.js and require("ejs").compile(str).

License

(The MIT License)

Copyright (c) 2009-2010 TJ Holowaychuk <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • Add support of extend and block in EJS

    Add support of extend and block in EJS

    @visionmedia, fyi: Add features of extend and block, which could support (1) multilayer inheritance, fully support layout in EJS. (2) Also could work with include. The examples and test has also been add!

    opened by ictliujie 29
  • How to break line within <%= here is a string %>

    How to break line within <%= here is a string %>

    If I receive from my client a string with "Hello\nHow are you?"...

    Then:

    1. If I do the job to replace \n by <\br> then the string that appears on the browser is:

    Hello<\br>How are you?

    1. If I don't replace anything, then (of course :) the string in the browser is:

    Hello\nHow are you?

    So my question is: How you guys handle the line breaking without going to go for too complex code in .ejs placeholders?

    Thanks,

    Sebastien

    PS: <\br> is not the right html tag for break line, I write it like this to keep it displayed in this editor

    opened by sebthiriet 23
  • Variables within HTML comments

    Variables within HTML comments

    I'm running Node.js 0.10.5 and keep experiencing FATAL ERROR: JS Allocation failed - process out of memory when attempting to render a template.

    Update: Originally this was assumed to be an error with Node.js 0.10.0 and above, but if you read below, you'll see the error is related to variables being used within HTML comments.

    opened by jbrooksuk 21
  • Using

    Using "if" to check variable before usage results in Error, Undefined

    From the example in the README

    <% if (user) { %>
        <h2><%= user.name %></h2>
    <% } %>
    

    This code, in all situations, always results in an error if you don't pass the data to the file. I am trying to use it as, let's say, a report about whether your password was valid - if it wasn't I would render the file with

    res.render('login', { msg: "Error: your password has too many characters." });
    

    But if the user were going to the login page and it hadn't yet been posted, I would just use:

    res.render('login');
    

    I could fix this by explicitly sending a msg = null to all routes, but I think that is silly.

    Any advice on how to properly handle this? My guess is that what I am doing is somehow unconventional in node/ejs.

    Thanks a bunch,

    • Keith
    opened by netpoetica 11
  • Extra new lines added

    Extra new lines added

    I have a template:

    A list of famous people:
    <% names.forEach(function (name) { %>
    name: <%= name %>
    <% } %>
    

    Which generates:

    A list of famous people:
    
    name: Alexander
    
    name: Bruce
    
    name: Ceasar
    
    name: David
    

    Could the new lines be removed?

    opened by ghost 11
  • feature request - include/require ability

    feature request - include/require ability

    one feature i miss from jsp/php is the ability to include/require additional files and have them inserted into the current file... not sure what would be a good syntax, but wanted to throw that out there

    opened by wavded 11
  • Add `options.it` for render speed performance

    Add `options.it` for render speed performance

    If set 'ejs.it = true;', ejs will get 100% render speed up. There is the only change is: must use 'it.var_name' to access template locals data;

    I also add options.it to benchmark.js, there is my results:

    $ node benchmark.js 
    
    rendering 50000 times
    took 303ms
    options.it true: rendering 50000 times
    took 121ms
    
    opened by fengmk2 9
  • Escaping differences between express and client versions.

    Escaping differences between express and client versions.

    I'm having troubles reusing my express templates on the client. Specifically, I can't figure out how to render partials in a way that works for both express and the client. I think the major issue is that express auto-escapes everything with <%= and doesn't for <%-. The regular verion just seems to only support <% and doesn't escape anything.

    I prefer how express does it, but it would really be beneficial to reuse the server side express templates on the client. Is it possible to make the express EJS implementation work client side or is there a way to render partials that is consistent on both he client and server?

    opened by mhemesath 8
  • Issue rendering a javascript template

    Issue rendering a javascript template

    When trying to render a javascript template that uses ejs for certain reasons I get this error:

    deps/express/lib/express/view.js:246
                throw err;
                ^
    SyntaxError: Unexpected identifier
        at Object.Function (unknown source)
        at deps/express/support/ejs/lib/ejs.js:89:12
        at Object.render (deps/express/support/ejs/lib/ejs.js:119:14)
        at ServerResponse.render (deps/express/lib/express/view.js:262:26)
        at /Users/seth/projects/buntin/pilot/src/pilot/node/server.js:36:25
        at /Users/seth/projects/buntin/pilot/src/pilot/node/lib/pilot.js:30:13
        at [object Object].<anonymous> (/Users/seth/projects/buntin/pilot/src/pilot/node/deps/node-mongodb-native/lib/mongodb/collection.js:373:35)
        at [object Object].emit (events:32:26)
        at [object Object].<anonymous> (/Users/seth/projects/buntin/pilot/src/pilot/node/deps/node-mongodb-native/lib/mongodb/db.js:77:12)
        at [object Object].emit (events:25:26)
    
    opened by sethtrain 8
  • recursive function in ejs

    recursive function in ejs

    Can I define a recursive function and call it in ejs page? The following is my code:

    <% function createTree(ret){ %>
          <% if(ret.comments){ %>
            <% var i = -1, len = ret.comments.length %>
            <% while(++i < len){ %>
              <% if(ret.comments[i].comments) { %>
              <% console.log(ret.comments[i]); %>
              <div class="media" id="<%= ret.comments[i]._id %>">
                <a class="pull-left">
                  <img class="media-object" src="<%= ret.comments[i].gravatar %>">
                </a>
                <div class="media-body">
                  <h4 class="media-heading text-muted "><a href="<%= ret.comments[i].site %>" rel="nofollow"><%= ret.comments[i].name %></a>at<%= ret.comments[i].create_time %>say:</h4>
                  <div class="comment"><%= ret.comments[i].comment %></div>
                  <% createTree(ret.comments[i]); %>
                </div>
                <div class="btn btn-info btn-xs reply">reply</div>
              </div>
              <% } else { %>
              <% console.log(ret.comments[i]); %>
              <div class="media" id="<%= ret.comments[i]._id %>">
                <a class="pull-left">
                  <img class="media-object" src="<%= ret.comments[i].gravatar %>">
                </a>
                <div class="media-body">
                  <h4 class="media-heading text-muted "><a href="<%= ret.comments[i].site %>" rel="nofollow"><%= ret.comments[i].name %></a>at<%= ret.comments[i].create_time %>say:</h4>
                  <div class="comment"><%= ret.comments[i].comment %></div>
                </div>
                <div class="btn btn-info btn-xs reply">reply</div>
              </div>
              <% } %>
            <% } %>
          <% } %>
        <% } %>
    
    opened by brucewar 7
  • Add a new filter that replaces falsy values with a default value

    Add a new filter that replaces falsy values with a default value

    Include a filter that checks if a value if falsy and, in that case, replaces it with a default one (passed as an optional argument, empty string by default).

    This is useful to make your intention clear (instead of <%= value || "my value" %>) and to combine it with other filters (e.g. <%=: value | default | capitalize %>).

    It includes some tests.

    opened by palmerabollo 7
  • after i login from login form, it will get an error <%- body> is not defined. if i removed <%- body> it will not get an error. please help

    after i login from login form, it will get an error <%- body> is not defined. if i removed <%- body> it will not get an error. please help

    after i login from login form, it will get an error <%- body> is not defined. if i removed <%- body> it will not get an error but index.ejs doesnt render to layout.ejs... i have:

    LOGIN FOLDER views folder index.ejs layout.ejs faves folder animals.ejs foods.ejs

    app folder routes.js server.js

    `//server.js var createError = require('http-errors'); var express = require('express'); var session = require('express-session'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var morgan = require('morgan'); var app = express();

    var path = require('path'); //var expressLayouts = require('express-ejs-layouts'); var expressLayouts=require("express-ejs-layouts");

    //var ejsLayouts = require('express-ejs-layouts');

    var ejs = require('ejs');

    //*********************************** */ app.use(express.static('public')); app.use('/stylesheets', express.static(__dirname + 'public/stylesheets')); app.use('/animations', express.static(__dirname + 'public/animations')); app.use('/img', express.static(__dirname + 'public/img'))

    //app.set('view options', { layout:'layout.ejs' }); //app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser());

    var passport = require('passport'); var flash = require('connect-flash'); const { request } = require('http'); const { response } = require('express');

    require('./config/passport')(passport);

    app.use(morgan('dev')); app.use(cookieParser()); app.use(bodyParser.urlencoded({ extended: true }));

    app.use(session({ secret: 'justasecret', resave:true, saveUninitialized: true }));

    app.use(passport.initialize()); app.use(passport.session()); app.use(flash());

    require('./app/routes.js')(app, passport);

    ////no preload //app.set('views', './views'); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.set('view options', { layout:'layout.ejs' }); //app.use('/',router); app.use(expressLayouts); //app.use(ejsLayouts); app.set("layout extractScripts", true)

    app.get('/layout', isLoggedIn, function(_req, res, _next) { res.render('layout', {layout: 'layout.ejs', }); //user:req.user}); });

    function isLoggedIn(req, res, next){ if(req.isAuthenticated()) return next();

    res.redirect('/'); }

    app.get('/foods', function(req, res) { res.render('faves/foods', {title: 'Favorite Foods', foods: ['coconut', 'avocado']}); });

    app.get('/animals', function(req, res) { res.render('faves/animals', {title: 'Favorite Animals', animals: ['sand crab', 'corny joke dog']}) });

    app.listen(3000, () => { console.log('Server is running at port 3000')

    }); module.exports = app;`

    `//routes.js ///setting first run***** var express = require('express'); var app = express(); var expressLayouts=require("express-ejs-layouts");

    app.set('view engine', 'ejs');

    app.use(expressLayouts);

    module.exports = function(app, passport) { app.get('/', function(req, res){ res.render('login.ejs', {message:req.flash('loginMessage')}); });

    app.post('/login', passport.authenticate('local-login', { successRedirect: '/layout', failureRedirect: '/', ////// this one been troubleshooting FM failureFlash: true }), function(req, res){ if(req.body.remember){ req.session.cookie.maxAge = 1000 * 60 * 3; }else{ req.session.cookie.expires = false; } res.redirect('layout.ejs'); });`

    `//layout.ejs

    `
      wow
      <%- body %>
    
    
    </div>
    <body>
    
    </body>
    </html>`
    

    `index.ejs

    This is the home page!

    `
    opened by soCasi 0
  • Help! I am Using Vs code and it doesn't recognize ejs tags.

    Help! I am Using Vs code and it doesn't recognize ejs tags.

    I am Using Vs code it doesn't recognize ejs tags when they are inside an html tag like the input tag below :

    <input type="checkbox" name="checkbox" value="<%=item._id%>" onChange="this.form.submit()"> Before changing the default value property from on to <%=item._id%> it would actually print on, Now it does nothing ! and in the code itself i can see that it doesn't recognize it because the color doesn't change as usual.

    Any suggestion is appreciated.

    opened by fatajomustapha10 1
  • PUT method

    PUT method

    PUT method is not working in my form

    I am having a form that hits an API with a PUT method but it doesnot work unless I change the method to POST.

    <form action="/api/settings" method="POST">
    {html form fields}
    </form>
    
    opened by fahdjamy 0
  • Passing data from one page to another using redirect.

    Passing data from one page to another using redirect.

    Can't pass data from one page to another

    • I want to be able to remain on the same page using with the same URL and but submit and data to a different API endpoint and when it is success full the page should re-render with updated information but now changing the URL.

    Desired Behaviors:

    I am on the page with URL http://localhost:3010/settings and I am making a POST request to back-end API URL http://localhost:3010/api/settings. When I use res.render my page's URL changes to http://localhost:3010/api/settings which I don't want, I want to stay on the same page but have updated data for my page with URL http://localhost:3010/settings

    opened by fahdjamy 0
  • need return if it is true else do another in ejs

    need return if it is true else do another in ejs

    <% for (const result of data) { %> <% if(result.disable === true){ %> <% return %> <% }else{ %> # <%= result.Fullname %> <%= result.PhoneNumber %>


    update

    <% } %> <% } %>

    opened by Hamse-Muse 0
Owner
TJ Holowaychuk
TJ Holowaychuk
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
node.js script to scrape all top meme templates from https://imgflip.com/memetemplates

imgflip-scraper node.js script to scrape all top meme templates from https://imgflip.com/memetemplates Acknowledgements imgflip Run Locally Clone the

Abhishek Bhathela 3 Nov 12, 2022
Open Source and Embedded Nano Faucet

NanoDrop Open Source, Transparent and Embedded Nano Faucet Visit: https://nanodrop.io This project was created to help bring Nano to the masses. Fauce

Anarkrypto 30 Dec 26, 2022
🚀🚀 A Shopify embedded app starter template, with updated dependencies, session storage, app context and examples for basic functionalities.

Shopify Node App Starter This is a starter template for embedded shopify apps based on the shopify cli node app. Contributions to create the perfect s

Carsten Lebek 143 Jan 8, 2023
A lightweight extension to automatically detect and provide verbose warnings for embedded iframe elements in order to protect against Browser-In-The-Browser (BITB) attacks.

Enhanced iFrame Protection - Browser Extension Enhanced iFrame Protection (EIP) is a lightweight extension to automatically detect and provide verbose

odacavo 16 Dec 24, 2022
This plugin can be embedded in PHP application to give the web application specific routes/href

Routes Plugin PHP This plugin can be embedded in PHP application to give the web application specific routes/href location and for entering specific/l

Ifechukwudeni Oweh 7 Jul 17, 2022
🚀🚀 A Shopify App template for serverless, non-embedded Apps.

?? Free Shopify x Next.js App Template for serverless non-embedded Apps Everything to build your next non-embedded Shopify App and Marketing pages in

Carsten Lebek 77 Dec 30, 2022
A Mail client embedded in Visual Studio Code.

VSCode Mail Client A Mail client embedded in Visual Studio Code Features Support IMAP and SMTP protocol. Gmail.com vendor test pass. 126.com vendor te

buhe 14 Nov 8, 2022
A handler to create embedded pages with buttons for pagination.

➝ Whats that • A handler to create embedded pages with buttons for pagination. ➝ Requirements • ["Handler"] pages.js • [Example command] embed.js ➝ Us

null 8 Oct 30, 2022
An obsidian plugin for uploading local images embedded in markdown to remote store and export markdown for publishing to static site.

Obsidian Publish This plugin cloud upload all local images embedded in markdown to specified remote image store (support imgur only, currently) and ex

Addo.Zhang 7 Dec 13, 2022
A compilation of Google Tag Manager (GTM) adapters written for measuring interactions with embedded content.

Google Tag Manager (GTM) Custom HTML Adapters for Measuring Embedded Content Interactions This repository contains adapters for sending interaction da

Derek Cavaliero 7 Oct 3, 2022
Tempo is an easy, intuitive JavaScript rendering engine that enables you to craft data templates in pure HTML.

Tempo 2.0 Tempo is an easy, intuitive JavaScript rendering engine that enables you to craft data templates in pure HTML. Why use Tempo? Clear separati

Twigkit 707 Jan 3, 2023
Collection of customizable Anki flashcard templates with modern and clean themes.

Anki Templates Collection of customizable Anki flashcard templates with modern and clean themes. About Features Themes Instructions Add-on support Com

Pranav Deshai 101 Dec 29, 2022
Kustomizegoat - Vulnerable Kustomize Kubernetes templates for training and education

KustomizeGoat - Vulnerable by design Kustomize deployment Demonstrating secure a

Bridgecrew 38 Nov 1, 2022
Visual Studio Code extension for formatting and linting Django/Jinja HTML templates using djLint

Visual Studio Code extension for formatting and linting Django/Jinja HTML templates using djLint

Almaz 25 Dec 15, 2022
⚡️ A collection of open-source solution templates to integrate within Buildable Flows.

Buildable ⚡️ Buildable is an instant backend tool that makes a software developer’s day more delightful. We’re helping engineers breeze through featur

Buildable 161 Dec 15, 2022
Quickly create an anchor program from templates and setup anchor dev environment.

Create Anchor App Quickly create an anchor program from templates and setup anchor dev environment. Example Installation npm i -g @create-anchor-app/c

null 24 Nov 28, 2022
This repo contains the templates used in my automated obsidian weekly review video and also an accompanying vault with the folder structure expected and plugins

This repo contains the templates used in my automated obsidian weekly review video and also an accompanying vault with the folder structure expected and plugins (periodic note settings etc)

Pamela Wang 53 Dec 21, 2022