I know that expressjs supports many view engines, like: ejs, jade, etc. I saw a list here: http://expressjs-book.com/forums/topic/how-to-use-alternative-non-jade-template-engines-with-express/.
My question is how can I create my own view engine. I've looked in ejs and in other engines' source-code but I didn't really find an expressjs documentation on how to create a new engine, what are the requirements, or a tutorial about it.
Is it possible to create a new custom view engine? Thanks.
Yes, of course. Take a look at this list for templating engines.
Regarding express itself, what you need to do is create a plugin, or even a middleware function - that will attach your render, renderFile and similar methods to the response object.
If you don't use an express engine and try to, say, response.render('index.ejs');, you'll get an error. But if that response object has a render method, you're fine. So it boils down to extending expresses' response object with what you need.
Related
I am building a blogging website with node/express.js and mongodb. Now, I want to view individual blog so I created an endpoint of '/articles/:id' so I can only display that particular blog details.
But the problem is how do I show the blog related information in an html page, how do I send that information to frontend ? Like I can't even do a fetch on the '/articles/:id' endpoint because the id would change depending on the specific blog.
One solution you might say is that to use a templating engine but I build the whole thing up till now without templating engine and also I want to know how to do it without a templating engine.
This is my code for individual article. Here I am fetching the blog data from mongodb database and sending it via res.json
app.get('/articles/:id', (req, res) => {
ArticleModel.findById(req.params.id).then(article => res.json(article));
});
Is it possible to so without any templating engine at first place ?
In my view You have two alternatives :-
-> you can send HTML code using res.send like this.
app.get('/articles/:id', (req, res) => {
const city="Londan";
const country="England";
const temp=24;
res.send("<h1>Hello, The temperature in "+city+","+country+" is "+temp+"</h1>");
});
-> Use a library which replaces template engine or in other words which t can do HTML and DOM manipulation like jsdom, cheerio, plates.(haven't tried this personally) because I have always use template engine because it helps me to separate service side code and client side code.
This answer talks in more details about https://stackoverflow.com/a/10114041/13126651.
But my recommendations would be to use template engine for it will simplify your most of the work, there are lof of great options like ejs and my personal favourite is handlebars.
I'm looking to create a single node.js application that will render multiple different client websites.
We currently run one node.js application per client website, but I think this might be overkill as the serverside logic is exactly the same for all of them, the only difference being the handlebars template.
I'm looking to re-architecture to have a single node.js application which will then render the different client's websites based on some incoming information, will use nginx to add a header or something to the request so the app knows which website to render.
Is it possible to store the handlebars template within a database and then request the template at render time? Rendering a simple single page should be easy enough, but I'm struggling to understand how partials would be rendered?
Looking to achieve something similar to Shopify's Storefront Renderer, not sure if it's possible to do with handlebars or if it's better to use of of the LiquidJs ports for Node to achieve this?
https://shopify.engineering/how-shopify-reduced-storefront-response-times-rewrite
I do this with different countries, same concept as you with different Clients.
You just create the Handlebars layout and put it in your partials folder. No need to put template in your database.
Then your server logic will have eg clientName, and your Handlebars will have IfEqual tags (you'll need an IfEqual helper)
Example:
Server route will give a variable clientName.
Handlebars you have the main view page with only the IfEqual helpers.
{{#ifEqual clientName 'Client Name 1'}}
{{> client/clientName1}}
{{/ifEqual}}
{{#ifEqual clientName 'Client Name 2'}}
{{> client/clientName2}}
{{/ifEqual}}
Your helper function will be
, helpers: {
ifEqual: function(x, y, options) {
return(x == y) ? options.fn(this) : options.inverse(this)
} // {{#ifEqual statusLogin 'unconfirmed'}} {{/ifEqual}}
Search nodejs handlebar helper if you dont know how to set it.
So my partial folder, you can create a folder in it called client, and put all your Handlebars template in there. Search for nodejs handlebars partial folder setup if you dont know how to do it.
The handlebar helper function I found it I think in stack overflow, so you can search for others if you want, but for me it works.
Your partial template files just do as normal Handlebar files.
So the main idea is User loads the page, depending on what Client flag you put it, it loads up that template.
My project was originally set up with Handlebars, but I'm moving to Nunjucks due to it's ability to perform async logic. I've been reading through the docs, but I'm not exactly sure how to do this. If I understand correctly, you cannot use Express' rendering engine and instead have to implement a custom template loader yourself. How would you execute a db call from a custom helper, then render the template with the fetched data?
I would like to return localized Strings for multilanguage business objects in our RestFul API based on node.js, restify and mongoose. I have the requirement to store the translated resources on our translation resource server, but also need to support dynamic creation of those business objects.
I found a solution to easily plugin the i18n process in the POST/PUT calls using a single pre-'save' mongoose middleware on all Schema, when creating or updating my multi-languate business objects - this works because I am able to pass the request context to the obj.save(req, callback) call.
But, I am struggling to plug in the i18n on simple GETs. I thought of and tried different ways where I can plugin the i18n before returning the response, but don't really find a good way. Options I thought of:
translate in a mongoose middleware pre /post ('init'):
Problem: I don't have access to the request context, and therefore
don't know the locale to return, so I cannot translate there.
translate in the toObject() / toJSON {transform: }:
Same issue - i don't have the request context in these hooks.
translate in the handler/controller methods for each ressource.
Problem: Duplication, I have to do it everywhere, I would really prefer a solution I can define on the model/Schema layer
translate in a restify / express middleware towards the end:
Problem: I don't have access to the mongoose schema metainformation anymore, so I don't know which attriutes to translate.
Edit: just found this additional way:
- translate in a custom restify responseFormatter:
This seems to work nicely, in the reponseformatter I have access to everything I need. It kind of seems a little weird from an architechtural point of view, but if nobody has a better idea, I will add this as an answer.
Maybe (hopefully) I am missing something obvious...
thanks for any hints
I have several environment settings that I need to inject into my javascript assets. Thinks like database uri and facebook app id. I'm currently using EJS as my view engine.
Is there a simple way of templating javascript files in NodeJS?
Rather than trying to template your static files, I'd suggest using an initializer script instead.
Simply put a <script> block in your layout, where you call a function in your JS file, which takes the DB uri and the FB app id as its parameters. The function can then store the values someplace where the rest of the scripts know how to access them.
You can easily pass your parameters into the layout (and views) for example by using helpers