How can I have my index.htm file include other html files - javascript

using node.
Here is how I serve one from my server:
app.get('/', function(req, res) {
res.sendfile('./views/index.html');
});
With in this index.html file I have two files I need served:
head.htm and body.htm.
In PHP I would just use includes. How is this done in Node?

There's many solutions to the situation here... it comes down to personal preference on which tool you gravitate towards.
One such tool that I have used is EJS. You can read all about it here:
https://code.google.com/archive/p/embeddedjavascript/wikis/Templates.wiki
Edit: An example of such would be having a header and footer template, with an index.ejs page that includes them. (Although you can use include these files at any point in the index page that gets rendered).
Index.ejs (ejs is just the extension used, it's the same as html with rendering tags inside of it):
<% include templates/header %>
<h1> Index page!</h1>
<% include templates/footer %>
Header.ejs:
<html>
<head>
</head>
<body>
Footer.ejs:
</body>
</html>
Inside routes configuration:
app.get("/", function(req, res){
res.render("index");
}
There's obviously configuration requirements that you will need to do, I'm also assuming you're using express, which EJS works pretty easily with.

Pick a template library, any template library. I've had success with nunjucks.
Then you can do something like:
var nunjucks = require("nunjunks");
var app = express();
nunjucks.configure('views', {
autoescape: true,
express: app
});
app.get('/', function(req, res) {
res.render('index.html');
});
and in index.html:
{% include "item.html" %}

It would help if you mentioned the templating engine you are using. By default, it should be Pug(or Jade) (if you used the express generator I think).
For Jade:
app.js:
var express = require('express');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// define routes
app.get('/', function(req, res) {
res.render('index.html');
});
Now, by default the views folder will be used to serve files. A good practice is to create a master layout that defines the general structure of your HTML files, and then add the specific contents in the extended files.
master.pug:
doctype html
html
head
title
block title // title block
link(rel='stylesheet', href='/stylesheets/default.css') //some default styles
block styles // block for more styles
body
include header.pug //include header file
block content // block to insert contents
script(type='text/javascript',src='/javascripts/faculty-index.js') // default scripts
block scripts // block to insert scripts
include footer.pug // include footer file
Block defines a space where you can enter your content once you extend the file. Include basically just includes the code from the file in that space. Now you're index.pug can be something like this
index.pug
extends master.pug // extend the base template
block title
| Index Page // adds the content in the title block
block styles
link(rel='stylesheet', href='/stylesheets/index.css') // specific styles for index
block content
h1 This is the index // adds the index content which goes in the body tag where content is defined
Here the index file uses everything from the master file, and adds its own content in title, body and styles.
Look at the pug documentation for more
Similar behavior can be replicated with any templating engine. Another one I've used is Handlebars which I like more because its syntax feels more like writing html. But, you'll have to set it up first.

Related

Html redirection using Nodejs

I'm trying to link my back Node js api with my html pages .
for almost cases everything works well but I got confused at some point
What is the efficient way to follow in redirecting a html page because I usually use node js to do that like this which it seems to me wrong ? I think
res.sendfile('event.html')
but I saw in different page this statement which allows to jump from page to another
<div class="ui-block-title">
<h6 class="title">Events</h6>
Create New
</div>
could it possible to light on how to link the href part with node js backend ?
Best Regards,
Use Express.js a nodejs framework
Install & Include Express.js framework in your project
express = require("express"),
app.set("view engine", "ejs"); //setting all files view as .ejs
app.use(express.static("public"));
Now create a .ejs file and wrap it around html because at backend normal html can't be rendered
To wrap Do <%= > around each content object where you want to display some content
object
HomePage.ejs
<h1>HomePage!</h1>
Now call your html file using :-
app.get("/", function (req, res) { // no need to add .ejs as we had set all at ejs
res.render("HomePage");
});
// Output:
// HomePage!
probably you've got different routes in your node server, if you want to redirect to specific route you can just res.redirect('target') so if you're using express it would look sth like
const app = express()
app.get('/', (res, req, next) => {
res.render('index')
}))
app.get('/some-route' , (res, req, next) => {
res.redirect('/')
}))
app.listen(3000)
here if you go to main page the index page will be rendered, but it you go to foo.com/some-route you will be redirected to main page
thats in principle how redirection works with Node. Hope that this answers your question.

using common layout for all the pages in pug

I am trying out pug with express
views/layout.pug
doctype html
html
head
title= title
link(rel="shortcut icon", href="favicon.ico", type="image/x-icon")
link(rel='stylesheet', href='/assets/application.css')
link(rel='stylesheet', href="assets/libs/bootstrap/dist/css/bootstrap.min.css")
body
script(src="assets/libs/jquery/dist/jquery.min.js")
script(src='assets/libs/bootstrap/dist/js/bootstrap.min.js')
script(src="assets/application.js")
block content
This is the router for User page.
routes/user.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('user/index');
});
module.exports = router;
I have my view for user/index page. I extends the layout from the views. User index page using the layout. layout.pug is present in views folder.
If I add a layout.pug inside views/user it works. But how to use the views/layout.pug
/views/user/index.pug
extends layout
block content
h1
| User index
i get the following error. it is looking for layout in view/user folder. How to make it to use view/layout.pug.
Error: ENOENT: no such file or directory, open 'C:\my_projects\myexpressapp\views\user\layout.pug'
at C:\my_projects\myexpressapp\views\user\index.pug line 1
at Error (native)
at Object.fs.openSync (fs.js:640:18)
at Object.fs.readFileSync (fs.js:508:33)
at Function.read (C:\my_projects\myexpressapp\node_modules\pug-load\index.js:69:13)
at Object.read (C:\my_projects\myexpressapp\node_modules\pug\lib\index.js:147:25)
at C:\my_projects\myexpressapp\node_modules\pug-load\index.js:24:25
at walkAST (C:\my_projects\myexpressapp\node_modules\pug-walk\index.js:23:18)
at C:\my_projects\myexpressapp\node_modules\pug-walk\index.js:104:20
at Array.reduce (native)
at walkAndMergeNodes (C:\my_projects\myexpressapp\node_modules\pug-walk\index.js:103:18)
In your app.js file, check whether you have defined the views properly.
View engine should be set to pug and views folder should be set properly as described below in app.js
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));
You have to set the baseDirectory variable.
I'm not familiar with Express, I found the answer How do you set jade basedir option in an express app? (the "basedir" option is required to use "extends" with "absolute" paths)

Passing an include file into a Handlebars layout

I'm using Node.js, Express 4, and the Handlebars templating processor. Some of the page views that I'm rendering with Handlebars have several kBytes of static inline SVG code. Is there a simple clean way to put the SVG code into a separate file to be included in the Handlebars layout template? Ideally this include file would have a .svg extension, but .hbs would be acceptable.
yesterday I was solving the the same problem. And I finished with loading svg file into string and then pass it to the handlebars template.
var svgTemplate = fs.readFileSync('./public/app/build/images/spriteAll.svg', 'utf8');
var express = require('express'),
router = express.Router();
router.get('/', function (req, res) {
res.render('main', {
svgTemplate: svgTemplate
});
});
//where main.hbs contains:
...
<body class="ng-cloak">
<div class="inline-svg">
{{{svgTemplate}}}
</div>
....
</body>
You can make a static assets folder (e.g. /public) in your project, and include it with Express: app.use(express.static('public')); Put your .svg file in there.
Then in your handlebars file simply add the SVG as you would in a normal HTML project, like <img src="your.svg">
You could try out handlebars-partial-file to include a file's contents as a Handlebars partial.

Send a index.html file when server is created

I want a file like index.html to be loaded when the server is created. When I execute the server.js using node, I send a response as text like this res.end("text"). But I want the index.html to load.
I tried to load it using sendFile() in app.get('/getFile') but when I type in the address bar, I get the text for all the urls..even for localhost:3000/getFile.
This is my server.js:
(function(){
var http = require("http");
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var path = require('path');
// app.use(express.static(__dirname));
app.use(bodyParser.json());
app.use(express.static(__dirname+'/views'));
var server = http.createServer(function(request, response) {
response.end("text");
});
server.listen('3000');
console.log("Server is listening");
app.get('/getFile',function(request,response){
// response.end('shi');
response.sendFile(path.join('/index.html'));
})
})();
Change the following in your code:
var server = http.createServer(function(request, response) {
response.end("text");
});
to this:
var server = http.createServer(app);
Now, you can serve your static index.html file with this code:
app.get('/', function(req, res, next){
// Serve the index.html file in the root directory of the website.
res.sendFile(path.join('/index.html'));
});
I hope this helps. If you have any questions, let me know.
EDITED
I just made a folder and wrote the following code and I have checked that this is working.
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/indexz.html');
});
app.listen(1339);
console.log('Open this link http://localhost:1337');
Steps
1 Copy the code given above in a new folder and name it whatever you want, name the file server.js
2 go to your cmd and propagate to location of your code and now npm install express
3 now type node server on console
4 open the link that is there on the console.
Note : Make sure there is folder name public and there is a file named
indexz.html in there.
Edited
Regarding proper client side files arrangement
You will have to keep all your files in public folder, first of all and attach them accordingly in your html document.
Example
<!-- Owl Carousel Assets -->
<link href="css/owl.carousel.css" rel="stylesheet">
<link href="css/owl.theme.css" rel="stylesheet">
<script src="js/jquery.min.js"></script>
<script src="angular.js"></script>
<script src="controller.js"></script>
and then within public folder you'll have folders named js and css and in root of the public folder your html files.
Looks your issue is with all the static assets.
In application server like express you have 3 different kind of elements to serve:
static content: this is all html, client side js, css, images and so on
server side templates or views, are documents you assemble with some sort of templating library like handlebars or jade to produce html
api that provide data in xml or more common json format
Your issue is how to serve a static part.
You should add to the static folder of your express app the folder where you build your angular app.
Not just the index.html you need the client side .js, .css and all images the page require.
UPDATE:
Here you could find the express documentation about static content.
UPDATE:
When you add a static folder to the express middleware, you should be able to access your file directly.
For example, if you have 2 files: $project/static/main.js and $project/static/js/my-lib.js, you should use the following urls:
http://127.0.0.1:3000/main.js
http://127.0.0.1:3000/js/my-lib.js
Considering you're executing the node http server on localhost on port 3000.
If you provide a specific path to access the static content, then you have to rewrite your url so.
If you use a line like:
app.use('/staticFolder', express.static('staticFolder'));
Than the urls to the mentioned files will be:
http://127.0.0.1:3000/staticFolder/main.js
http://127.0.0.1:3000/staticFolder/js/my-lib.js
Also pay attention to the path you provide to express.
You should give a proper path, and it's always safer to use absolute paths:
app.use(express.static(__dirname + 'staticFolder'));
or
app.use('/staticFolder', express.static(__dirname + 'staticFolder'));

How to easily pass a variable with Node.js to the view

I'm trying to learn the basics of Node.js and I can't seem to be able to simply send a variable from app.js to index.html without using Jade or other template engine.
This is my app.js
var express = require("express");
var app = express();
app.get('/', function(req, res){
//I'd like to send this as a variable instead
res.send("some text");
});
app.listen(8080);
This is my index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
//I want to alert my variable here please
alert(variableFromAppjs);
</script>
</head>
<body>
<p>Hello</p>
</body>
</html>
Is there a way to do it simply like that?
The reason you can't just "send" the variable from your app.js to index.html is because they're two separate programs. index.html is run ONLY on the client machine through the browser, and app.js is run ONLY on the server.
In order for index.html to receive data from app.js, you'll need to to use XMLHttpRequest to make a request to your Node app.
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
You can then receive the data asynchronously and save it to whatever variable you want.
You will need to make sure you're using a server-side templating engine (express comes with jade support).
Use npm to install jade to your express app. and then tell express where the templates are, and, in the get route definition you must instruct express what view to use:
var express = require("express");
var app = express();
// Tell express where your templates are
app.set("views", __dirname + "/views");
// Tell express templates are jade files
app.set("view engine", "jade");
app.get("/", function(req, res) {
res.render("home", {
title: "Home Page",
body: "This is just a test..."
});
});
app.listen(8080);
when all this is setup create views/layout.jade and a views/home.jade
Home.jade will look like this:
extends layout
block content
h1= title
p A tag name followed by the equals (=) sign is like php echo
p= body
ul
li This is a hardcoded list
li With two elements
Layout.jade will look like this:
html
head
meta(charset="utf-8")
title= title
link(rel="stylesheet", href="/css/main.css")
meta(name="viewport", content="width=device-width")
body
block content
div.page-content.text-center
h1 Default content
p anything I put here will be overridden by the home.jade content block Which means that any jade view that doesn't provide a `block content` part will render this text instead.
If you create another route for example:
app.get("/default", function(req, res) {
res.render("test", {title: "Default route", body: "Whatever"});
});
an then its corresponding template views/test.jade
extends layout
p I'm not providing a `block content` so this text won't be rendered
blockquote(class="my-class", id="my-id") In jade, the very first word of a line is the tag to be used by the line, to provide attributes to a tag you use comma-separated HTML attributes in between parenthesis right next to the tag name.
And visit your route at http://localhost:8080/default You will see the default text be rendered.
I hope this is of help.

Categories