how to include handlebars templates that are also used in express - node.js

I have an express application that uses handlebars as view template engine.
I have a page that is written as a handlebars template. The problem is that part of this page must be rendered by the server, and other parts must be rendered on the client.
<body>
<div>my page with handlebars {{me}}</div>
<script id="each-template" type="text/x-handlebars-template" src="/partials/model1.js">
sample template {{friend}}
</script>
</body>
The problem is that the page gets to the client fully rendered (including the template within ).
<body>
<div>my page with handlebars Patricio</div>
<script id="each-template" type="text/x-handlebars-template" src="/partials/model1.js">
sample template
</script>
</body>
But it should be:
<body>
<div>my page with handlebars Patricio</div>
<script id="each-template" type="text/x-handlebars-template" src="/partials/model1.js">
sample template {{friend}}
</script>
How can get this result?

The fastest and best way to get this done is using pre-compiled handlebars templates:
http://handlebarsjs.com/precompilation.html
and then consuming then using the runtime
http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars.runtime-v2.0.0.js
In this way, there's no markup to be scanned and both, client and server, can use the same pre-compiled template

Related

Hide other code in the app.js in the login page of a vue app

I'm creating an app using laravel + vue. Vue loads all the javascript codes in the app.js even in the login page in which the user is not yet authenticated. I don't want to expose all the js codes just yet until user is logged in. Is there any way that I can only show the necessary codes for the login page and not expose all the js code of the app? I'm doing this to also limit the size of app.js being downloaded for the login page to improve page loading time too.
If you're using Laravel mix, you can add a new entry point for your login script.
mix.js('resources/assets/app/js/app.js', 'public/app/js')
.js('resources/assets/app/js/login.js, 'public/app/js);
So, you can add a #yield statement in your base layout to place scripts declared in the page view.
base.blade.php
<html>
<head>
<title>App Name - #yield('title')</title>
</head>
<body>
#section('sidebar')
This is the master sidebar.
#show
<div class="container">
#yield('content')
</div>
#yield('scripts')
</body>
</html>
login.blade.php
#extends('layouts.base')
#section('title', 'Page Title')
#section('content')
<p>This is my body content.</p>
#stop
#section('scripts')
<script src="{{ mix('app/js/login.js') }}"></script>
#stop
Edited
For a SPA you can have another bundled entry point to just define the Login component:
Vue.component('login-form', {
... component code here
})
You can use vue-plugin-load-script to load the login.js script in the beforeEach method from Vue router. So the component will be available before render the login page.
router.beforeEach(async (to, from, next) => {
if (to === 'login'){
await Vue.loadScript('login entry point url here')
}
next();
});
Also, you can do it inside the page using the beforeMount hook. Here an example using a fake promise and entry point.
https://jsfiddle.net/7oj2sxun/3/
If you're using Vue CLI, it already supports lazy loading with dynamic imports.
Here a detailed article:
https://blog.logrocket.com/lazy-loading-in-vue-js/

EJS style template tokens in create react app

I'm making a new section on a website using create-react-app, previously I've been using node/express/ejs to render pages.
I have a server side API which returns blocks of html for the website header and footer which i inject into the pages:
<div id="header-container">
<%- header %>
</div>
Is it possible with create react app?

Why would I need template engines like Jade or EJS on the backend?

I am familiar with Angularjs(1.x) and use templates in directives.
Currently I am learning nodejs and as a part of the course template engines are mentioned. What are the advantages of using them on the backend?
Currently I can't see any use.
If you have data (say from a database) that needs to be rendered to HTML, you can use a template engine to take the data and a template and render it to HTML (which subsequently gets served to the client).
If your frontend app does the same, using XHR calls or something similar to retrieve the data from the server, it's generally not useful to render to HTML server side (instead, the data gets sent as JSON to the client).
So it depends on how your app (both frontend and backend) is structured if it makes sense or not to use a templating engine.
There's also hybrid solutions where the initial HTML is rendered server side, and then the client side "takes over". This is something that, for instance, React supports. The big idea there is that you can use the same components both on the server and on the client, and that when a page is opened, the user will get to see a fully rendered initial page (instead of the client side having to retrieve the data from the backend first and then rendering the page).
You actually dont need them, but they have a lot of features that makes your pages more dynamic..
For example you can render just HTML using this code
app.get('/',function(req,res){
res.sendFile(path.join(__dirname+'/index.html'));
//__dirname : It will resolve to your project folder.
});
But with engines you can send data to template.
http://expressjs.com/en/api.html#res.render
// pass a variable to the view
res.render('somePage', {
title: 'Awesome title',
userFriends: friendsList,
name: 'loggedUserName'
});
And now on front-end templates(EJS in this case) will populate html with data that you send in. So html became dynamic and you can make each page looks different for each user.
<ul>
<% for(var i=0; i<userFriends.length; i++) {%>
<li><%= userFriends[i] %></li>
<% } %>
</ul>
With just HTML you will need to make a lot of unnecessary AJAX calls to get and add data into html which is bad idea.
Hope this helps.
A view engine allows you to render HTML with options. For example, using squirrelly, I can create a file that looks like this:
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
{(userIsSignedIn){<!-- if the user is signed in, display username and description-->
<p>{{username}} is {{description}}</p>
}}
{(!userIsSignedIn){<!--if user isn't signed in, ask them to sign in-->
<p>Sign in to view this page</p>
}}
</body>
</html>
So I could listen, for example, to a dynamic user profile URL with Express and then return dynamic content.
It's almost 2020, Template literals are literally meant to replace template engines.
https://medium.com/#PaulBrowne83/do-we-really-need-template-engines-anymore-214eb6bc112e

Serving HTML to build a simple SPA using Node.js/Express

I want to build a website as a Single Page Application.
For what I understand a SPA sends a single entry point to the application in the form of an HTML file.
So I would like to use Node and Express to serve the main page and to then serve HTML for the content between the header and footer that gets updated using AJAX calls when a user navigates the site.
I know how to create a restful API to serve data as JSON but not much on how to deal with the HTML parts of the SPA that are changing.
The question: how could this serving of HTML parts be implemented on the server using Node and Express (and eventually a template engine like handlebars, if it helps)?
And does it actually make sense? (A header and a footer are not much data to reload after all.)
You can definitely do this with node.js. First you set up an HTML template engine, for instance Swig, (but you can use others) and you configure the standard options to render html pages:
var swig = require('swig');
app.set('view engine', 'html');
app.set('view options', {
layout: false
});
app.engine('html', swig.renderFile);
app.set('view cache', false);
// To disable Swig's cache, do the following:
swig.setDefaults({ cache: false });
app.use(express.static(__dirname + '/public'));
Second you set up an endpoint which serves your main HTML page.
app.get('/',function(req, res) {
res.render('index');
};
Then you can create node.js endpoints which will get your data:
app.get('/users', function(req, res) {
// Do database stuff here
res.status(200).send(results);
}
Then you set up your HTML file:
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="stylesheets/bootstrap.min.css" rel="stylesheet">
<title>fast MEAN</title>
</head>
<body ng-controller="MainController">
<div class="col-md-12" style="background-color: #006699">
</div>
{% raw %}
{{helloWorld}}
<ng-view></ng-view>
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="app.js"></script>
{% endraw %}
</body>
</html>
Where everything outside of {% raw %} and {% endraw %} will be rendered with data using the node/swig template data, and everything inside those tags can be rendered with whatever framework you are using inside (jquery, angular, react) etc.
An example of this simple single page application is on my github, there's one version for angular and one for react. Hope that helps.
https://github.com/coguy450/fastMEAN

Render HTML on Node.js Express (Include HTML code in another HTML file)

I'm using a Node.js Server with Express-Framework installed and have a problem combining two different html-files.
I have a basic template.html file with a <div id="content"> in it. Now I want to include content.html within this div before sending the data to the client.
How can this be done?
I like to use EJS because it's the most straight-forward templating language, but the same idea applies for jade or whatever you might use. To enable this in express after running npm install ejs:
app.engine('.ejs', require('ejs').__express);
When you send your response, run:
res.render('content.html.ejs');
Spit your template.html into views/header.html.ejs and views/footer.html.ejs, and include them in views/content.html.ejs like this:
<% include header.ejs %>
Content Here
<% include footer.ejs %>

Resources