Express - Async Templating - node.js

I'm using Express-Handlebars for my templating engine and I'd like to make an asynchronous call from within my templates like the following example:
{{{cmsLoader 'search-{$searchTerm}' searchTerm=query.input defaultId='search-default'}}}
This would query the db for a chunk of html by a specific id (i.e. 'search-video-games'), if the key exists, it adds the html. If the key doesn't exist, it looks for the defaultId (i.e. 'search-default') and adds it instead. If the defaultId is not specified or doesn't exist, nothing is added.
Most of the backend functionality is in place. My problem is the doing async processing inside of a helper. Is there a way to wait for the results of an async call from an hbs-helper before finalizing the render?
NOTE:
I realize I can make these calls from inside the controller and feed the data to the view, but there are tons of templates most with multiple CMS blocks and since these will be changing regularly, accounting for them ahead of time would be difficult to maintain.

Handlebars is not an asynchronous templating engine so that is not possible. You would need to switch to an asynchronous templating engine for Node.js such as Marko. Marko allows you to asynchronously fetch additional data even after rendering has begun.

Related

Dash Multiple Page Application With Callbacks

I created a couple dash applications and now I think I'd like to connect them with a menu that takes you between the pages.
So i used this example: https://github.com/plotly/dash-sample-apps/tree/master/apps/dash-financial-report to begin however, each page in my application has specific callbacks associated and those callbacks need a dash app defined to work. How can I make this example work with callbacks with pages that have callback calls inside them? (i.e. I'd like to keep the header portion as on every page as I move through).
https://dash-gallery.plotly.host/dash-financial-report/overview

Node.js & Express: template engine for plain html code

Using Node.js and express in a MEAN environment, I am looking for a simple and straightforward template engine, meeting these requirements:
does not dictate me to only use its own weird syntax but allows me to keep writing webpages using pure/plain html and js
supports conditional includes
works with express
operates on server-side (Node.js/Express)
executes freakin' fast ;)
Basically I just want to slice my webpage into several modules (e. g. header, footer, ...) and include those now and then based on simple conditions. I don't want to entirely (re-)rebuild all webpages using a proprietary template language but rather prepare a few html modules that I concatenate at runtime (comparable to PHP where I just use the include instruction to paste prepared html code).
I had a look at http://garann.github.io/template-chooser/ and https://github.com/nodejs/node-v0.x-archive/wiki/modules#templating but the sites seem outdated and according to them, there ain't no template engine available fully meeting my requirements!?
Suggestions anyone?
I think ejs is more natural for what you are looking for https://scotch.io/tutorials/use-ejs-to-template-your-node-application, but jade can work also. The example in the link uses partials, which you dont need to use if ur just rendering a single page

Sails.js - Get async data from an EJS file

Are there a good way to get async data from an EJS file?
Sails.js only have async methods to get data from a database.
I have a collection of Pages with their associated content Values. In some cases I want to get a specific Value from another Page (e.g.: in a related page module, a navigation module...). And I need to do that server side, to keep the front-end part SEO friendly.
The easier way should be to retrieve all the Pages and Values inside the controller, and then expose a function to my EJS to get the specific data I need. But I really don't want to retrieve each time all the data from a collection.
I'm working on a CMS so I would avoid creating a new controller/view for each specific cases that I will have.
EDIT:
It seems there is no good way to do that, so I reworked my controller to make it a bit more intelligent. It solve my problem for now.
Assuming I understand you correctly....
data is sent to the view by passing an object into the view funciton
return res.view({data: "important data"});
I'm guessing that you want to call a method for some specific data mid-render. Because having all the data ready on the res.view() call is too slow. As far as I know this is not possible. That would almost certainly be "blocking" code.
Best option I could recommend is to grab specific data using ajax on the client after page load. One of the best features of using sails :)

In Require.js text plugin template, how should I provide javascript methods?

I'm using Require.js and the text plugin. I'm trying to create a template that has something like this:
<%= somefunction(displayvalue) %>
I need the somefunction(...) to be available to multiple templates. How is the best way to wrap the function to use in multiple places? I was thinking of making it a module, but I don't know how to pass it to a template.
After you compile a template, you find yourself with a function to call, and you pass in some arguments. So just pass your function as argument:
var tpl = _.template( tplString );
tpl({ someFunction: function( val ) { /* do something */ } });
Although, I think you're probably better if you only pass value inside your template data. Template are actually way easier to debug and maintain if they're almost logic less. So, instead, I'd go like this:
tpl({ someValue: someFunction( aValue ) });
In other javascript templating engine (like Handlebars), you can actually register helpers functions who'll be mostly available globally to execute action on your template data. If you really need to use the same function inside multiple templates, I'd think about switching template engine. Underscore provide a micro-templating engine, and as so, is somehow limited around helpers functions - although being able to contain way too much logic...
In my opinion, underscore template works well for small project and should be use carefully. Keep them as simple as possible: if/else, printing data, and that should be it. If you need more, go for a more complete template engine.
But even there, all logic you do inside a template is hard to debug.
So! Keep it simple.

Multilanguage express app

I wonder what would be the best way to implement multiple versions / languages of the same content in the same layout in express.
Should I just do this?
app.get("/", function(req, res) {
res.render(language + "/index");
});
Or is there a smarter / better way?
I would suggest to keep only one template, as if you use one template per language it will get out of hand very quickly, let alone duplicate much content (and the small amount of "logic" you would put in a template too). Many applications use a tool called gettext to do the internationalization thing. There is a node.js library for it at https://github.com/DanielBaulig/node-gettext
Alternatively there is also i18n-node. It appears to have a bit more integration with express js.
The i18n-node is the simplest and greatest module that you should use. You can use directly in Javascript code or with Jade/Handlebar templates with express js.
Why should you use i18n?
Auto detection of locale from the browser by header, cookie or query parameter depending on your setup.
It comes with examples as well.
It automatically generates a en.json by default inside ./locales/. This acts as a master file for you to start building new translations.
Supports Singular and plural forms
Support for parameters: __('Hello %s', 'Marcus') returns Hallo Marcus
i thought that we can define json objects in lang folder like , en.js , fr.js and this json files contains key value pairs than render to template according to user's language setting , lang settings can be into database.
And we can save this fr.js or anything else into res.locals for calling every template .
Is this suitable?

Resources