Open hgurung opened 6 years ago
There are two ways you could accomplish this:
Helpers come in two forms: inline or block. As you've defined your fileExists
helper, it only works as an inline helper. To change it to a block helper format, you'd need an aditional argument (typically named options
) that gets two special attributes added to it: fn()
and inverse()
. Its a bit easier if you see the code:
fileExists: function(path, file, options) {
var file_exists = fs.existsSync(path + '/' + file);
if (file_exists) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
Then you'd invoke the fileExists
block helper like this:
{{#fileExists 'public/uploads' userData.image }}
<div class="showImg">
<img src="/public/uploads/{{../userData.image}}">
</div>
{{else}}
File does not exist!
{{/fileExists}}
Alternatively, Handlebars allows for subexpressions within a helper. In this case, we already have the if
block helper, so we could keep your existing fileExists
inline helper as is and pass its return value (either true
or false
) as an argument into the {{#if}}
block helper as a sub expression. Sub expressions are called via parens, like so:
{{#if (fileExists 'image.jpg')}}
<div class="showImg">
<img src="/public/uploads/{{../userData.image}}">
</div>
{{else}}
File does not exist!
{{/if}}
I made a quick example app, with my server app.js and my template home.handlebars shown below. Note for testing purposes, the only files that will "exist" in my code are image.jpg
and doc.pdf
.
/* app.js */
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
const hbs = exphbs.create({
defaultLayout: 'main',
// Dummy helpers that work with the filenames 'image.jpg' and 'doc.pdf'
helpers: {
fileExistsInline: function(path) {
return ['image.jpg', 'doc.pdf'].includes(path)
},
fileExistsBlock: function(path, options) {
let file_exists = ['image.jpg', 'doc.pdf'].includes(path);
if (file_exists) {
return options.fn(this);
} else {
return options.inverse(this);
}
},
}
});
// Register `hbs.engine` with the Express app.
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.get('/', function (req, res) {
res.render('home');
});
app.listen(3000, () => {
console.log('Listening on port 3000!');
});
{{! home.handlebars }}
<h1>Using built-in <code>if</code> block helper and sub expression <code>fileExistsInline</code> helper</h1>
<blockquote>
<h2>Image:</h2>
{{#if (fileExistsInline 'image.jpg')}}
<b>Image file here!</b>
{{else}}
<i>No image found!</i>
{{/if}}
</blockquote>
<blockquote>
<h2>Video:</h2>
{{#if (fileExistsInline 'video.mp4')}}
<b>Video here!</b>
{{else}}
<i>No video found!</i>
{{/if}}
</blockquote>
<hr>
<h1>Using custom <code>fileExistsBlock</code> block helper</h1>
<blockquote>
<h2>Image:</h2>
{{#fileExistsBlock 'image.jpg'}}
<b>Image here!</b>
{{else}}
<i>No image found!</i>
{{/fileExistsBlock}}
</blockquote>
<blockquote>
<h2>Video:</h2>
{{#fileExistsBlock 'video.mp4'}}
<b>Video here!</b>
{{else}}
<i>No video found!</i>
{{/fileExistsBlock}}
</blockquote>
Results in the following HTML:
<h1>
Using built-in <code>if</code> block helper and sub expression
<code>fileExistsInline</code> helper
</h1>
<blockquote>
<h2>Image:</h2>
<b>Image file here!</b>
</blockquote>
<blockquote>
<h2>Video:</h2>
<i>No video found!</i>
</blockquote>
<hr />
<h1>Using custom <code>fileExistsBlock</code> block helper</h1>
<blockquote>
<h2>Image:</h2>
<b>Image here!</b>
</blockquote>
<blockquote>
<h2>Video:</h2>
<i>No video found!</i>
</blockquote>
Which looks like this:
This is my helper function.
And i want to use it in views like this
I will also have else condition to put default image if not found.