Adding additional content blocks in KeystoneJS with handlebars - node.js

I'm using handlebars with KeystoneJS and am trying to extend the main import in the default template. At the moment it only includes the {{{body}}} tag imported through the view plus the partials that I'm using.
Is there any way to add a couple of other imports (i.e. intro content, page title, additional scripts). In the jade version on the demo site it just imports it as a content block. Is this a limitation of handlebars?

You can do this with handlebars just fine using partials.
Put your partial in the folder indicated below:
Then in your layout ('default.hbs' in this case) reference the partial like you would normally in handlebars.
<div id="header">
{{> navigation this}}
</div>
The '>' means insert partial.
In this case 'navigation' is the
partial name in the partials folder.
'this' is the data context. Its what you want to do with the 'locals.data' object passed into handlebars by keystone. Using 'this' will pass the whole lot through whereas doing something like 'locals.data.navigation' would pass the navigation object through to the partial making it directly accessible in the partial (good for DRY).
Hope that helps. The partials specific documentiation for handlebars is here if you are interested in looking into a few more things you can do with scope etc http://handlebarsjs.com/partials.html

Related

Why res.render() doesn't send local variables to the client without template engine?

I need to access the variable user in my client-side that sent by
res.render('home.html', { user: req.user });
without using template engines like pug or ejs
Is that possible?
HTML is not a templating language, so it can't be used to send variables.
res.render() function compiles your template , inserts locals there, and creates html output out of those two things. The syntax is as follows -
res.render(view [, locals] [, callback])
The view argument is a string that is the file path of the view file to render. For this to work, you need a template or view engine .
In html, you can't dynamically pass/insert data variables. That's the main use case for templating engine. They put runtime/dynamic value in html which is what you are probably looking for.
In short, its better to use any template engine like pug,jade,ejs, etc most of which would have almost similar syntax with html to render dynamic html pages. I don't think there's any method (atleast simple enough) to send variables dynamically from server to client in an html page. Using a template engine would be the best choice in your use case.
For eg. you are passing user from server side and most probably want the passed variable to be rendered on the client side. You can just install an view engine like ejs - npm install ejs, set your view engine in app.js - app.use('view engine','ejs'); , and just add this line in the html page where you want to send the variable to client side like - <p> <%= user %> </p> and that's it. Keep your html file in view folder and this would do it.

Inject meta tag dynamically to HTML with Express

Summary:
I'm currently migrating a website on Apache + PHP stack over to Node + Express, and would like to know what is the best way/best practice (if there is one) for dynamically injecting meta tags under the new stack.
Details:
Under the existing stack, meta tags are injected dynamically by adding PHP codes into the HTML file directly. As rendering is done on server side, the tags are properly interpreted by Facebook/Google+/whatever web crawlers.
Under the new stack, after doing some research, I've come across two options:
Use template engine like Pug (Jade) to render the HTML with locals. (It seems to be an overkill to rewrite the existing HTML with Pug's syntax though? Can Pug deal with HTML, or I've to consider other template engine like EJS? What template engine do you advise me to explore?)
Use DOM manipulation plugin like Cheerio to inject the meta tags first, before rendering begins.
Between these two options, which one will have a better performance or there is no material difference? Are there any other ways that you'd otherwise recommend? Thanks!
EJS would probably be the simplest one for that and very similar to PHP.
You can also take a look at Mustache and Handlebars for other options with minimal changes to your existing HTML.
with EJS: <html><head><%= yourMetaTags %> ...
with Mustache: <html><head>{{ yourMetaTags }} ...
with Handlebars: <html><head>{{ yourMetaTags }} ...
Also doT.js is very fast.
See:
http://www.embeddedjs.com/
https://mustache.github.io/
http://handlebarsjs.com/
http://olado.github.io/doT/
Parsing the HTML and manipulating it with a DOM API just to insert meta tags would be an overkill in my opinion.
On the other hand if all you need is to insert meta tags then you could make a simple regex substitution, using something like yourHTML.replace('<head>', '<head>'+yourMetaTags); but it could potentially get more complex over time when you need more functionality. After all, everyone has made a templating engine at some point in life.

load external html files with handlebars

I would like to create external Handlebars files using the following -
1. header- Contains html codes
2. footer- Contains html codes
3. nav- Contains html codes
4. search - Contains html codes
etc.
Is there a way with handlebars to do this, so that I can include each template if and when needed in a specific page. Not sure how to go about it.
Thanks!
Absolutely! You can use Handlebar partials to do this. Simply register your header, nav, etc files as partials and then you can use this in your main template by doing something like this:
{{> header }}
{{> nav activePage=(activePage) }}
Have you considered using ASP.NET?
If you wanted to add content from other html files, I would highly recommend using
#RenderPage()If you use this, then you could set up a layout such as:
#RenderPage("header.html")
Some random description
#RenderPage("navigationbar.html")
#RenderPage("searchbar.html")
- Insert some content here -
#RenderPage("footer.html")
I'm certain that if you use this kind of layout, you'd get the appearance you would want. Obviously this is just an example, so you'd probably want to add some kind of CSS layout to suit your taste, but this is how I would go about it in ASP.NET.

can you use jade to only render the dynamic part of your html...and not mess with rest of your html

Or can you render partially and render rest later. So lets say when app starts up it renders most of the html. But when user abc wants to see his profile jade renders name to abc and merge it with regular pre rendered html and then you send it etc.
Rendering whole html pages at every request seems like a waste.
Converting all static html to jade seems like a annoyance that can be avoided. Slowly css became LESS and html became JADE?
I am lost on how to use jade I am learning express.
You can use Jade's compileClient function to create a function that will render predefined Jade code on the fly. (See the API reference.)
So, if you create a Jade file with the dynamic HTML, and compile that for the client, you can then call that function at a later time, and insert the resulting HTML string to the DOM.

Componentizing markup with relative js and css

I've been thinking of a way to include components of markup in a modular fashion. For example if I were to include a slider I would have to include the relevant css and JS for it to function correctly. Is there any known method of including these as one component?
<div> {{slider}} </div>
{{slider}} then would import slider.html, slider.css and slider.js but to their respective directories. css/slider.css and js/slider.js
Is this possible given our current array of production tools?

Resources