Reputation: 1923
I'm working on a small documentation website and the content is stored in files. For instance I have two files chapter1.jade
and chapter2.jade
in a module1/
directory.
I'd like to read the module1/
directory and dynamically include all the chapterX.jade
files in it.
I tried to have do directory = fs.readDirSync('module1/')
and then in my view:
each item in directory
include item
But jade include doesn't support dynamic values (even `include #{item}) doesn't work. Do you have any idea how I could implement this ?
EDIT: I'd like to generate some code under the each
loop (anchor for easy linking) so the solution would preferabily be in the view. I could obviously manually add the anchor in the included files but it is not ideal.
Thanks
Upvotes: 0
Views: 2959
Reputation: 171
in addition to kalemas answer you can also write your includes to a file which is included in jade.
in this example I write my includes to include_all.jade. This file is included in a jade file.
If it does not work, check the path ;-)
e.g. in your app.js
var includes = "path/to/include1\n";
includes += "path/to/include2";
...
incPath = "path/to/include_all.jade";
fs.open(incPath,'w',function(err,fd){
if(err){
throw 'error open file: ' + incPath +" "+ err;
}
var buffer = new Buffer(includes);
fs.write(fd,buffer,0,buffer.length,null,function(err){
if (err)
throw 'error writing file: ' +err;
fs.close(fd,function(){
console.log('file written ' + incPath);
});
});
});
in your jade file
include path/to/include_all.jade
Upvotes: 0
Reputation: 1923
Here is the short version of what I've done to make it work. It uses the jade Public API.
var directory = __dirname+'/views/bla/'
, files
, renderedHTML = '';
if( !fs.existsSync(directory) ) {
// directory doesn't exist, in my case I want a 404
return res.status(404).send('404 Not found');
}
// get files in the directory
files = fs.readdirSync(directory);
files.forEach(function(file) {
var template = jade.compile(fs.readFileSync(directory+file, 'utf8'));
// some templating
renderedHTML += '<section><a id="'+file+'" name="'+file+'" class="anchor"> </a>'+template()+'</section>';
});
// render the actual view and pass it the pre rendered views
res.render('view', {
title: 'View',
files: files,
html: renderedHTML
})
And the view just renders the html variable unescaped:
div(class="component-doc-wrap")
!{html}
Upvotes: 1
Reputation: 14003
As @user1737909 say, that's not possible using just jade.
The best way to do this (tho) is building a little Express Dynamic (view) Helpers
DEPECATED IN EXPRESS 3.XX
Check these: Jade - way to add dynamic includes
Upvotes: 0