RandomEtc / ejs-locals

Express 3.x layout, partial and block template functions for the EJS template engine.
298 stars 63 forks source link

Custom ejs filters don't work #7

Closed net147 closed 12 years ago

net147 commented 12 years ago

In JS file: var ejs = require('ejs');

ejs.filters.escape = function(str) { return escape(String(str)); }

In EJS template: <%=: text | escape %>

Error: Object # has no method 'escape'

RandomEtc commented 12 years ago

Thanks for this bug report - I'll take a look.

RandomEtc commented 12 years ago

Sorry but I couldn't recreate this error. I added a test for custom filters in 0.2.3. Please take a look and re-open this issue if you still have trouble.

net147 commented 12 years ago

I found the problem. The custom filter was being added to node_modules/ejs but npm installed another copy of ejs in node_modules/ejs-locals/node_modules/ejs. So I removed the duplicate ejs module in the ejs-locals folder and it worked.

RandomEtc commented 12 years ago

Good to know - glad to hear you figured it out. I've run into similar module dependency/ordering issues before, not sure how it can be avoided without making people install ejs explicitly for themselves before installing ejs-locals.

Maybe ejs-locals could expose ejs in its exports?

net147 commented 12 years ago

Well the thing is, I already had ejs installed before I installed ejs-locals...

RandomEtc commented 12 years ago

Hmm. Was it an earlier version than ejs-locals specifies? I could certainly be more liberal if that was the case.

net147 commented 12 years ago

I just did npm install ejs; npm install ejs-locals. ejs is 0.8.2 ejs-locals is 0.2.3 ejs-locals/ejs is 0.7.2

RandomEtc commented 12 years ago

Published 0.2.4 which allows ejs 0.x and should avoid this issue in future. Thanks for the extra details!

konsumer commented 10 years ago

I am having the same issue, with these versions:

  • ejs: 1.0.0
  • ejs-locals: 1.0.2

with this code:

var ejs = require('ejs'),
    ejsLocals = require('ejs-locals'),
    path = require('path');

module.exports = function(app){
    // Use EJS-locals for server-side templates
    app.engine('ejs', ejsLocals);
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'ejs');

    // here is how you add custom EJS filters
    ejs.filters.basename = function(file, ext) {
        return path.basename(file, ext);
    };
};

Deleting node_modules/ejs-locals/node_modules/ejs fixed it. Maybe a > operator would work better?

Alternately, exposing your ejs would also work, so I could do this:

var ejsLocals = require('ejs-locals'),
    ejs = ejsLocals.ejs,
    path = require('path');

module.exports = function(app){
    // Use EJS-locals for server-side templates
    app.engine('ejs', ejsLocals);
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'ejs');

    // here is how you add custom EJS filters
    ejs.filters.basename = function(file, ext) {
        return path.basename(file, ext);
    };
};