I have some filters:
var jade = require('jade');
jade.filters.Posts = function(block) {
return '{block:Posts}'+jade.render(block)+'{/block:Posts}';
};
jade.filters.Audio = function(block) {
return '{block:Audio}'+jade.render(block)+'{/block:Audio}';
};
jade.filters.Video = function(block) {
return '{block:Video}'+jade.render(block)+'{/block:Video}';
};
And have some input
:Posts
Posts
:Audio
| Audio
:Video
| Video
So I have an error:
>> unknown filter ":Audio"
Can I handle or fix this problem?
PS You can look at the code in this repository — I'm using grunt and grunt-contrib-jade plugin, but to force grunt-contrib-jade work with filters you should edit ./node_modules/grunt-contrib-jade/tasks/jade.js to reflect changes from this pull request.
PS2: I found the stumbling block. When I use render()
method inside filter, I invoke it from local jade instance, which is don't know anything about filters, but global jade instance (from Gruntfile.js) have all information about that filters. That's why the main question is: how can I throw global Jade-instance to file with filters?
PS3: I don't know how create fiddle for such case. But you can clone my Hampi repo, implement changes to grunt-contrib-jade from my PR to them, then at start run npm i
. To compile templates run grunt jade
. Pay attention to these line in body.jade and commented section in filters.
PS4. I find the reason and it in different scope. I describe it with details here. Can you solve this issue?
I'm open to additional answers and I will accept fixes in jade core (if it would be required).
We just should bind global jade instance to filters like this:
var jade = require('jade');
if (options.filters) {
// have custom filters
Object.keys(options.filters).forEach(function(filter) {
if (_.isFunction(data)) {
// have custom options
jade.filters[filter] = options.filters[filter].bind({jade: jade, locals: data()});
} else {
// have no custom options
jade.filters[filter] = options.filters[filter].bind({jade: jade });
}
});
}
See implementation here — in this commit
I think you are right at problem place, the problem is in the filter.js
file
location jade/lib/filters.js
var transformers = require('transformers');
module.exports = filter;
function filter(name, str, options) {
if (typeof filter[name] === 'function') {
var res = filter[name](str, options);
} else if (transformers[name]) {
var res = transformers[name].renderSync(str, options);
if (transformers[name].outputFormat === 'js') {
res = '<script type="text/javascript">\n' + res + '</script>';
} else if (transformers[name].outputFormat === 'css') {
res = '<style type="text/css">' + res + '</style>';
} else if (transformers[name].outputFormat === 'xml') {
res = res.replace(/'/g, ''');
}
} else {
throw new Error('unknown filter ":' + name + '"');
}
return res; // returns RES that is not defined in scope of function.
}
filter.exists = function (name, str, options) {
return typeof filter[name] === 'function' || transformers[name];
};
Here I have identified one flaw that you can correct like this,
var transformers = require('transformers');
module.exports = filter;
function filter(name, str, options) {
var res;//defined a variable which is global to the scope of function.
if (typeof filter[name] === 'function') {
res = filter[name](str, options);
} else if (transformers[name]) {
res = transformers[name].renderSync(str, options);
if (transformers[name].outputFormat === 'js') {
res = '<script type="text/javascript">\n' + res + '</script>';
} else if (transformers[name].outputFormat === 'css') {
res = '<style type="text/css">' + res + '</style>';
} else if (transformers[name].outputFormat === 'xml') {
res = res.replace(/'/g, ''');
}
} else {
throw new Error('unknown filter ":' + name + '"');
}
return res;
}
filter.exists = function (name, str, options) {
return typeof filter[name] === 'function' || transformers[name];
};
It may be possible that nesting under some function makes audio function out of scope. Does audio function works alone!?
although there may be other things if the problem not solved, please create a fiddle for your for better understanding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With