Jade to HTML > index.html inside directory named after jade file - javascript

I've got a simple gulp task that compiles a .jade file to an .html file:
var gulp = require('gulp'),
jade = require('gulp-jade');
gulp.task('jade', function() {
return gulp.src('src/templates/**/*.jade')
.pipe(jade()) // pip to jade plugin
.pipe(gulp.dest('public')); // tell gulp our output folder
});
Issue
/src/templates/page.jade is compiled to HTML at the destination /public/page.html
How would I get it so it would compile /src/templates/page.jade to /public/page/index.html.
I.e. every new jade file in templates gets compiled to a an html file called index.html inside a directory with the same name as the source jade file?
Examples
/src/templates/about.jade >> /public/about/index.html
/src/templates/contact.jade >> /public/contact/index.html
/src/templates/features.jade >> /public/features/index.html

If you want to include sub-directories you can go with:
.pipe(rename(function(path){
if(path.basename != 'index')
{
var crumbs = path.dirname.split('/')
crumbs.push(path.basename)
path.basename = 'index'
path.extname = '.html'
path.dirname = crumbs.join('/')
}
return path
}))
I've been using this with success on a front-matter solution. Don't forget to include /** before /*.filetype in the gulp.src

I think what you need is gulp-rename plugin. Play around the following code, maybe it will solve your problem.
var gulp = require('gulp'),
jade = require('gulp-jade')
rename = require('gulp-rename');
gulp.task('jade', function() {
return gulp.src('src/templates/**/*.jade')
.pipe(jade())
.pipe(rename(function(path) {
var filename = path.basename;
path.basename = 'index';
path.extname = '.html';
path.dirname = filename;
return path;
}))
.pipe(gulp.dest('public'));
});

I think it's a combination of some gulp trickery and proper usage of Jade itself.
the following works for me, and results with index.html including all other files:
1) Project Structure:
- src
-- templates
--- footer.jade
--- layout.jade
-- index.jade
2) gulpfile:
var gulp = require('gulp'),
jade = require('gulp-jade');
gulp.task('jade', function() {
return gulp.src(['!src/templates/**/*.jade', 'src/index.jade'])
.pipe(jade())
.pipe(gulp.dest('public'));
});
Notice i've changed the src input. first, the source files are passed to gulp as an array. second, i've added an '!' (exclamation mark) before the files you want gulp to ignore.
3) Jade
you can (and should) use include/extend to tell jade how to assemble your page eventually.
for example, this is what my files include:
src/templates/footer.jade
h1
some text
src/templates/layout.jade
doctype html
html
head
block title
title Default title
body
block content
src/index.jade
extends ./templates/layout.jade
block title
title Article Title
block content
h1 My Article
include ./templates/footer.jade
Hope this helps. I'm just learning this too :)

I had to use gulp-rename:
var gulp = require('gulp'),
jade = require('gulp-jade')
rename = require('gulp-rename');
gulp.task('jade', function() {
return gulp.src('src/views/**/*.jade')
.pipe(jade({
pretty: true
}))
.pipe(rename(function(path){
if (path.basename=='index'){
return;
}
path.dirname=path.basename.split('-').join('/');
path.basename="index";
}))
.pipe(gulp.dest('./public/'))
callback();
});

Related

Gulp-minify how to remove duplicate files

Im trying to minify JS files with Gulp, but what is happening is that it copies all the original files im trying to minify to the destination folder /minify whereas I want there to be only the minified files with the extension -min.js.
var gulp = require('gulp');
var minify = require('gulp-minify');
var stripDebug = require('gulp-strip-debug')
var strip = require('gulp-strip-comments')
gulp.task('min-js', function() {
return gulp.src('./**/*.js', '!./node_modules', '!./*-min.js')
.pipe(minify({
ignoreFiles: ['gulpfile.js', './node_modules']
}))
.pipe(stripDebug())
.pipe(gulp.dest('./minify'))
});
gulp.task('watch', function(){
gulp.watch('lib/scripts/*.js', ['min-js']);
});
gulp.task('default', gulp.series('min-js', 'watch'));

Node.js : Path error loading JSON file using express

I have a set of folders and files made this way:
viz
|_ app.js // node application
|_ public
|_ css
|_ bubblemap.css
|_ images
|_ nuts
|_ nuts0.json
|_ script
|_ bubblemap.js
|_ views
|_ bubblemap.hbs
bubblemap.hbs:
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>Bubblemap</title>
<script src='https://d3js.org/d3.v5.js' charset='utf-8'></script>
<link href='/css/bubblemap.css' rel='stylesheet'/>
</head>
<body>
</body>
<script>
var viewData = {};
viewData.dataHome = JSON.parse('{{json dataHome }}'.replace(/"/g, '"').replace(/</, ''));
viewData.dataWork = JSON.parse('{{json dataWork}}'.replace(/"/g, '"').replace(/</, ''));
</script>
<script src='/script/bubblemap.js' rel='script'/><{{!}}/script>
</html>
bubblemap.js:
(function() {
var files = ['../nuts/nuts0.json', '../nuts/nuts2.json'];
var promises = [];
promises.push(d3.json(files[0]));
promises.push(d3.json(files[1]));
Promise.all(promises)
.then(makeBubblemap)
.catch(function(err) {
console.log('Error loading files!');
throw err;
});
function makeBubblemap(data) {
var nuts0 = data[0];
var nuts2 = data[1];
var home = viewData.dataHome;
var work = viewData.dataWork;
}
)
And this is the node app file.
viz/app.js:
// import...
var app = express();
const webapp_options = {'port': 3000};
initialize();
async function initialize() {
await postgreSQLlib.connect();
app.set('views', '' + __dirname + '/views');
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'hbs');
app.engine('hbs', hbs.__express);
hbs.registerHelper('json', function(context) {
return JSON.stringify(context);
});
app.get('/bubblemap', bubblemap);
app.listen(webapp_options.port, function() {
console.log('Ready & listening on http://localhost:' + webapp_options.port + '/');
});
}
async function bubblemap(req, res) {
// download data from db
var dataWork = await postgreSQLlib.getTableHome();
var dataHome = await postgreSQLlib.getTableWork();
// create and fill object to pass to view
var viewData = {};
viewData.dataWork = dataWork;
viewData.dataHome = dataHome;
// pass data to view
res.render('bubblemap', viewData);
}
I get this error:
Error loading files!
Error: 404 Not Found
That is, the nuts0 and nuts2 files are not picked up correctly.
I think it's a path problem but it seems right to me.
I try: ../nuts/nuts0.json, ./nuts/nuts0.json, nuts/nuts0.json but nothing works.
The problem here is that the resource probably couldn't be loaded due to the webapp not serving it...
This can be proved by trying to access to the url of the json file.
Then it depends how you want to serve the JSON :
Filesystem
·Serve Static : /public/file.json
In this example you would have the files in a public accesible folder, and they would be served as static content from the filesystem.
app.use(express.static('public'))
Make a folder called public and store the jsons inside, they will be accesible under the webapp's root localhost:3000/nuts0.json
Learn more on serving static files in express
·Send File : /private/file.json
In this example you still have a JSON as a file in the filesystem, but not in a web accessible (public) folder (like the example above).
Instead here you are serving it as a resource in a router path (GET Request) and you could even apply pre-serving checks (if request has required cookies,parameters,...)
app.get("/jsonFiles/nut0.json",(req,res)=>{
res.sendFile(__dirname+"/private/nuts0.json")
})
More on express : sendFile
Dynamicly Generated upon GET request
In this example you have no file in your filesystem, but you build it in real-time upon a request (from database, memory, ...)
You can also apply pre-serving checks on this one (does the user have the required permissions,cookie,request parameters, etc..)
global.example_counter = 0; //in memory (global) variable
app.get("/jsonFiles/a-virtual-path-for-the-json",(req,res)=>{
example_request_counter++
res.json({"total requests":example_request_counter})
})
"jsonFiles" doesn't need to exists, that is the path for the webapp's router at the end what is served is what is in the res.send / res.json
global.inMemoryDB = { //in memory (global) variable
"nuts0":{"data":"the universe is in fact a multiverse"},
"nuts1":{"data":"tesla was bright"},
"nuts2":{"data":"sugar kills..."},
};
//router path
app.get("/jsonFiles/:j",(req,res)=>{
if(inMemoryDB[req.params.j]){res.json(inMemoryDB[req.params.j])}
else{res.json({"error":"non-existing virtual file requested"}
)}
// http://localhost:3000/jsonFiles/nuts0 will serve you the inMemory json
Learn more on req.params (Express API Doc)
Personally, mainly for production, I would use NGINX as reverse proxy to your node.js apps & serve the static content with it instead.

How can I prefix a file name with it's parent directory using Gulp?

I am using the following hierarchy for a project:
src/img/de-de/file1.jpg, file2.gif....
src/img/en-gb/file1.jpg...
src/img/it-it/etc
There are global images inside of the img folder, and localised files in each of the mentioned sub-directories.
I am using the gulp-rename plugin to add a custom prefix (GulpTest_) to file names. However, I also want to add the sub-directory folder name to any localised files that are stored inside.
Example:
src/img/de-de/file1.jpg would be renamed GulpTest_de-de_file1.jpg
I am currently using the following code to source each of the files in the sub-directories and add the GulpTest prefix:
// Image Rename Task
gulp.src('.src/img/*/*')
.pipe(rename({prefix: "GulpTest"}))
.pipe(gulp.dest("./dst/" + )
How can I amend my task so that it it concatenates 'prefix + sub-directory + file.jpg'?
Thanks
.pipe(rename(function (path) {
console.log('path', path);
if (path.extname) {
if (path.dirname === '.') {
path.dirname = '';
}
path.basename = 'GulpTest_' + path.dirname + '_' + path.basename;
path.dirname = '';
console.log('path-new', path);
}
}))
.pipe(gulp.dest('dst/'));

Rename Files Using Gulp w/ Specific Pattern

I have a Gulp task that needs to copy the contents from one directory to another and rename each file with a specific pattern. Basically, if I have main.css, I need it to create a copy of the main.css and name it main_main_bk.css (don't ask - it's a convention that I need to abide by). To be clear, I need to add a _ followed by the name of the file currently being processed followed by _bk. How can I read what the name of the current file is in Gulp?
var gulp = require('gulp');
var rename = require('gulp-rename');
gulp.task('copit', function() {
gulp.src('asset/css/*.css')
.pipe(rename({suffix: '_' + ??? + '_bk'}))
.pipe(gulp.dest('asset/test'));
});
So,
asset/css/main.css -> asset/test/main_main_bk.css
asset/css/style.css -> asset/test/style_style_bk.css
Etc.
You can use basename and rename it via function
var gulp = require('gulp');
var rename = require('gulp-rename');
gulp.task('copit', function() {
gulp.src('asset/css/*.css')
.pipe(rename(function (path) {
path.basename += "_" + path.basename + "_bk";
}))
.pipe(gulp.dest('asset/test'));
});

Grunt: how do I write a list of js files to a template for prod/dev environments

I would like to know how I can define a list of js files in one place (preferably within gruntfile.js or external json file) and have it written to a template (alternating between dev and prod environments).
JS file list definition
var jsFiles = [
'js/one.js',
'js/two.js'
];
Template (this is how I would like it to work)
if(isProd) {
print('<script type="text/javascript" src="js/combined.js"></script>\n');
} else {
for(var i = 0, len = jsFiles.length; i < len; i++) {
print('<script type="text/javascript" src="' + jsFiles[i] + '"></script>\n');
}
}
Template Result (development)
<script src="js/one.js" type="text/javascript"></script>
<script src="js/two.js" type="text/javascript"></script>
Template Result (production)
<script src="js/combined.js" type="text/javascript"></script>
You can use the config module to define a list of resources for both development and production environments: same property, but defined in different files, config/development.js and config/production.js.
The config module will automatically load the correct file for the current environment:
// config/development.js
module.exports = {
jsFiles : [ 'js/one.js', 'js/two.js' ]
};
// config/production.js
module.exports = {
jsFiles : [ 'js/combined.js' ]
};
If you are using Express with a rendering engine, you can pass the list of files to each template:
// assuming `app` is an Express app
var config = require('config');
app.locals.jsFiles = config.jsFiles;
You can also use these lists from your Gruntfile.js, although you need to require them (since you probably need to use both);
var development = require('config/development');
var production = require('config/production');
...

Categories

Resources