ericf / express-handlebars

A Handlebars view engine for Express which doesn't suck.
BSD 3-Clause "New" or "Revised" License
2.32k stars 382 forks source link

No such file or directory #195

Open itotallyrock opened 7 years ago

itotallyrock commented 7 years ago

I'm running into the same issue and it involves the differences in operating systems. This is because the application works as intended on windows, but fails on linux with Error: ENOENT: no such file or directory, open '/views/layouts/main.handlebars'

Here is my file structure.

|-- index.js
|-- package.json
|-- public
|   |-- css
|   |   `-- global.css
|   |-- img
|   `-- js
|       `-- main.js
`-- views
    |-- 404.handlebars
    |-- index.handlebars
    |-- layouts
    |   `-- main.handlebars
    `-- partials
        |-- footer.handlebars
        |-- nav.handlebars
        `-- title.handlebars

and here is part of the index.js file

app.set('views', path.join(__dirname, './views'));
app.engine('handlebars', expressHandlebars({
    defaultLayout: 'main'
}));
app.set('view engine', 'handlebars');

While I was making this issue, I ran into another error Error: Failed to lookup view "index" in views directory "/views" Which contains no reference back to express-handlebars but only mentions express in the stack.

I'm assuming this is just a simple mistake on my part but it might be worth documenting for people like me who don't quite understand the subtle differences between linux and windows.

sgnl commented 7 years ago

Try using path.resolve instead of path.join and see if it helps.

kas commented 7 years ago

I am also experiencing this issue. I use app.set('views', __dirname + '/views'); but the ENOENT error says it is trying to access project-name/views/layouts/main.handlebars instead of the expected project-name/src/views/layouts/main.handlebars'.

ndeufemia commented 7 years ago

I ran into the same issue, and could solve it by setting the layoutDir and partialsDir option as follows:

app.engine('.hbs', exphbs({
    extname: '.hbs',
    defaultLayout: 'main',
    partialsDir: path.join(__dirname, 'views/partials'),
    layoutsDir: path.join(__dirname, 'views/layouts')
  }));
app.set('view engine', '.hbs');
app.set('views',path.join(__dirname,'views'))
DmitryMyadzelets commented 6 years ago

How to reproduce this issue:

From this discussion it seems that the bug is due to pure default path resolving in express-handlebars.

This issue is fixed by this PR but not published yet.

erickhora commented 5 years ago

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

johnnyodonnell commented 4 years ago

Is there a way to set the set the default value of layout to false. I'm hoping to avoid updating all of my render functions from something like:

res.render("index");

to

res.render("index", {layout: false});

UziTech commented 4 years ago

defaultLayout: null should work

knoxcard commented 4 years ago

@johnnyodonnell

app.locals.layout = false
ahmedatef1610 commented 4 years ago
const expressHandlebars  = require('express-handlebars');

app.engine('hbs', expressHandlebars({
    defaultLayout: '',
}));

app.set('view engine', 'hbs');
app.set('views', 'views');
pulkit5ingh commented 4 years ago

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

Thanks Its Working...

Alpha4733 commented 4 years ago

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

Thanks Its Working...

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

Thanks Its Working...

but what if we have layout but still showing such problem

muhammadwarisali commented 4 years ago

This solved my issue:

app.engine('hbs',handlebars({ 
    layoutsDir: path.join(__dirname,'views','layouts'), 
    defaultLayout: 'main-layout', 
    extname: 'hbs'
}))
forcetrekker commented 4 years ago

I had a silly mistake as: extName: '.hbs' instead of extname: '.hbs'