-
Creare web-site simplu
Folosire modul Node.js URL
O parte importanta a unei pagini web este adresa URL.
Modulul URL imparte o adresa web in parti care pot fi citite.
Acest modul poate fi folosit pentru a crea un script Node.js care afiseaza continut html in functie de adresa URL.
Pentru a include modulul URL, foloseste metoda
require():
const url = require('url');
Acum sa analizam o adresa URL, folosind metoda
url.parse(). Va returna un obiect in care proprietatile sunt partile din adresa URL:
var url = require('url');
var adr = 'http://localhost:8080/index?id=890&ctg=nodejs';
var p = url.parse(adr, true);
console.log(p.host); //returns localhost:8080
console.log(p.pathname); //returns /index
console.log(p.search); //returns ?id=890&ctg=nodejs
var q = p.query; //contains an object: {id:890, ctg:'nodejs'}
console.log(q.id); //returns 890
Impartire sirul URL.search
Poti folosi proprietatea
query a metodei url.parse() pentru a imparti sirul cu valori din adresa URL in parti ce pot fi citite. Astfel, se poate afisa continut diferit in functie de datele din proprietatea query.
Exemplu, imparte sirul cu valori din URL in parti ce pot fi citite si afiseaza obiectul rezultat intr-un sir JSON in pagina.
//include http and url modules
const http = require('http');
const url = require('url');
//create the server
const server = http.createServer((req, res)=> {
res.writeHead(200, {'Content-Type':'text/html; charset=utf-8'}); //adds header to display html content with utf-8
//parse the url, get object with {name:value} from url query
var sq = url.parse(req.url, true).query;
var src_data ='<h4>'+JSON.stringify(sq)+'</h4>';
src_data +='id = '+sq.id+'<br>nm = '+sq.nm;
res.write(src_data, 'utf-8');
res.end();
});
server.listen(8080, ()=> {
console.log('Server running at //localhost:8080/');
});
Salveaza codul de mai sus intr-un fisier numit "demo_url_query.js" si initiaza fisierul cu node in interfata command line.
Acceseaza in browser adresa:
//localhost:8080/?id=1&nm=admin
Va produce acest rezultat:
{"id":"1","nm":"admin"}
id = 1
nm = admin
Creare web-site simplu
Acum stim cum sa analizam adresa URL si cum sa facem Node.js sa lucreze ca un server. In tutorialele precedente am invatat cum sa folosim modulul fs pentru a citi continutul unui fisier.
Sa combinam ceea ce am invatat
pentru a crea un simplu WebSite Node.js cu categorii si pagini care sa afiseze paginile solicitate de client.
• Pentru acest proiect poti crea fisierele cu codul prezentat in aceasta pagina sau ..:
- Dati click pe acest link pentru a descarca tot scriptul:
Download Node.js Simple WebSite.
• Pentru a vedea un Demo, click pe:
Demo Node.js Simple WebSite.
1. Creare fisier template html
Mai intai creaza un director numit "
site1", in acelasi director ca si node.js.
In directorul "site1/" creaza un fisier numit "
tpl_index.htm", cu un template pentru documentul html si un design responsiv; care il vom folosi pentru a afisa continutul paginilor html.
-
Aici este codul pentru fisierul "tpl_index.htm":
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{${title}}</title>
<meta name="description" content="{${description}}"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body, html {
position:relative;
background:#f2f3fe;
margin:0;
padding:0;
text-align:center;
font-size:1em;
font-family:"Calibri",sans-serif;
}
header {
background:#fafaff;
border:1px solid #888;
}
h1 {
margin:1px auto 8px auto;
}
#menu_top{
position:relative;
margin:3px auto;
padding:0;
font-size:16px;
font-weight:700;
}
#menu_top a{
margin:1px 2px;
background-color:#8f9fde;
padding:1px 4px;
text-decoration:none;
color:#fff;
box-shadow:.15em .13em .25em #6789da inset;
-webkit-box-shadow:.15em .13em .25em #6789da inset;
border-radius:.5em;
background-image:-ms-linear-gradient(top, #0818be, #b0c0fb);
background-image:-moz-linear-gradient(top, #0818be, #b0c0fb 95%);
background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #0818be), color-stop(0.9, #b0c0fb));
background-image:-o-linear-gradient(top, #0818be, #b0c0fb);
background:linear-gradient(top, #0818be, #b0c0fb);
}
#menu_top a:hover{
background:#fbfb01;
text-decoration:underline;
color:#0408fe;
box-shadow:.15em .13em .25em #a0a0da;
-webkit-box-shadow:.15em .13em .25em #a0a0da;
}
/* Side Menu */
#menu_side {
position:absolute;
top:100px;
left:1px;
width:200px;
padding:2px 1px 8px 0;
text-align:center;
}
#menu_side h4 {
margin:-.7em .8em .1em .7em;
background-color:#eaebfe;
padding:1px;
box-shadow:.15em .13em .25em #6789da inset;
border-radius:.5em;
background:linear-gradient(top, #dddefe, #eeeffe);
text-align:center;
}
#menu_side ul {
position:relative;
margin:0;
padding:0;
background:#f9f9eb;
border-radius:.6em;
list-style-type:none;
font-size:17px;
text-align:left;
}
#menu_side a {
display:block;
padding:2px 0 1px 4px;
color:#0000c0;
}
#menu_side > ul > li:hover, #menu_side > ul > li a:hover {
background:#3434fe;
color:#ffffff;
text-decoration:none;
}
#content {
background:#fefefe;
position:relative;
margin:25px 2px 5px 215px;
}
/* mobile dev. */
@media screen and (max-width: 650px){
@keyframes slide_top {
0% { margin-top:100px; }
100% { margin-top:0; }
}
header {
margin:1px 1px 3px 28px;
}
#menu_top {
font-size:14px;
line-height:150%;
margin:0 25px 1px 23px;
}
#menu_top a {
margin:2px 1px 2px 2px;
padding:0 2px;
font-weight:700;
}
#menu_top a:hover {
background:yellow;
color:#0408fe;
}
/* Side Menu */
#menu_side {
left:0;
top:35px;
background:#bedacf;
padding:3px;
border-radius:5px;
z-index:8888;
width:auto;
}
#menu_side h4 {
background-color:transparent;
box-shadow:none;
background:none;
font-size:18px;
line-height:85%;
width:20px;
margin:0;
padding:0;
}
#menu_side ul {
background:none;
display:none;
}
#menu_side ul li {
margin:2px auto;
background:#e0e0fb;
padding-left:1px;
}
#menu_side:hover h4 { display:none;}
#menu_side:hover ul {
display:block;
animation-name: slide_top;
animation-duration: 1s;
animation-timing-function: ease-in-out;
animation-delay: 0s;
animation-fill-mode: forwards;
}
#content {
margin:15px 1px 3px 28px;
}
}
</style>
</head>
<body>
<header>
<h1>{${title}}</h1>
<nav id="menu_top">{${menu_header}}</nav>
</header>
<section id="content">{${content}}</section>
<nav id="menu_side">
<h4>M E N U</h4>
{${menu_side}}
</nav>
</body>
</html>
2. Directorul pentru fisierele cu continutul paginilor
In directorul "site1/" creaza un alt director numit "
content". In acest director vom adauga fisiere ".htm" cu continutul fiecarei pagini a website-ului.
De asemenea, in directorul "content/" vom crea un fisier ".json" numit "
pages.json" care contine un obiect JSON cu date pentru categorii si paginile acestora.
Prima categorie "/" este pentru pagina index (home) si alte pagini in aceasta categorie.
-
Aici este codul pentru fisierul "pages.json", cu 3 categorii principale si 5 pagini:
{
"/":{
"title":"Title home page",
"description":"Description home page",
"link_txt":"Home",
"pages":{
"contact":{
"title":"Contact page",
"description":"Description for contact page",
"link_txt":"Contact"
}
}
},
"ctg-1":{
"title":"Title category one",
"description":"Description category one",
"link_txt":"Ctg-One",
"pages":{
"page-1":{
"title":"Title page one",
"description":"Description page one",
"link_txt":"Page One"
},
"page-2":{
"title":"Title page two",
"description":"Description page two",
"link_txt":"Page Two"
}
}
},
"ctg-2":{
"title":"Title category two",
"description":"Description category two",
"link_txt":"Ctg-Two",
"pages":{
"pg-one":{
"title":"Title page one in category 2",
"description":"Description page one in category 2",
"link_txt":"Page 1"
},
"pg-two":{
"title":"Title page two in category 2",
"description":"Description page two in category 2",
"link_txt":"Page 2"
}
}
}
}
- Acest obiect contine Titlu, Descriere si text pentru link ('link_txt') pentru fiecare dintre categorii si pagini. Aceste date vor fi adaugate in template cand o pagina este accesata in browser.
Continutul principal pentru fiecare pagina este stocat in fisiere separate (in directorul "content/"), avand acelasi nume ca si numele adaugat in "pages.json", si extensia ".htm".
- De exemplu: pentru pagina 'index' cream un fisier numit "index.htm" cu continutul html care vream sa il afisam in corpul paginii. Pentru continutul paginii categoriei "ctg-1" cream un fisier numit "ctg-1.htm". Si asa facem pentru continutul fiecarui categorie si pagini, ca in aceasta imagine:
3. Scriptul JS pentru continutul paginii
Acum vom crea un modul numit "
setpage.js" in directorul "site1/", cu o clasa Javacript care va crea continutul html pentru pagina solicitata; Cu datele adaugate in directorul "content/".
Acest modul va fi inclus cu require() in fisierul main.js.
-
Aici este codul pentru fisierul "setpage.js":
//set the page content according to data from url
class setpage {
//set propertie
constructor(){
this.pages ={} //for categories and pages data stored in pages.json
this.tpl ='' //store string with html template from tpl_index.htm
//values for template
this.tpl_val ={
title:'',
description:'',
menu_header:'',
menu_side:'',
content:''
}
this.ctg ='/'; //current category
this.pg =''; //current page
this.err =[]; //store errors
//gets pages data from pages.json
fs.readFile(path.resolve(__dirname, 'content/pages.json'), 'utf8', (err, data)=>{
if(err) this.err.push(err);
else {
this.pages = JSON.parse(data);
if(this.pages) this.menuHeader(this.pages);
}
});
//gets template from tpl_index.htm
fs.readFile(path.resolve(__dirname, 'tpl_index.htm'), 'utf8', (err, data)=>{
if(err) this.err.push(err);
else this.tpl = data;
});
}
//set $menu_header with links for categories; Receives $ctgs = object with all categories
menuHeader(ctgs){
for(var prop in ctgs){
var href = (prop =='/') ?'' :prop+'/';
this.tpl_val.menu_header +='<a href="/'+href+'" title="'+ctgs[prop].title+'">'+ctgs[prop].link_txt+'</a>';
}
}
//set $menu_side with links of pages in current category - $pgs
menuSide(pgs){
var menu_side ='';
for(var prop in pgs){
var href = (this.ctg =='/') ?prop :this.ctg+'/'+prop;
menu_side +='<li><a href="/'+href+'.htm" title="'+pgs[prop].title+'">'+pgs[prop].link_txt+'</a></li>';
}
if(menu_side !='') this.tpl_val.menu_side ='<ul>'+menu_side+'</ul>';
}
//sets $pg $ctg with data from url; receives the request
setPgCtg(req){
var cp = url.parse(req.url, false, true).pathname.split('/'); //[categories, page]
this.pg = cp.pop().replace('.htm', '');
this.ctg = cp.join('');
if(this.ctg =='') this.ctg ='/';
}
//adds page data (title, description, content) in $tpl_val
pageData(){
//set name for file content
if(this.pg !='') var file =this.pg; //page in category
else if(this.ctg !='/' && this.pg =='') var file = this.ctg; //category
else var file ='index';
// sets title and description
if(this.pages[this.ctg]){
if(this.pg ==''){ //category
this.tpl_val.title = this.pages[this.ctg].title;
this.tpl_val.description = this.pages[this.ctg].description;
}
else if(this.pages[this.ctg].pages[this.pg]){ //page
this.tpl_val.title = this.pages[this.ctg].pages[this.pg].title;
this.tpl_val.description = this.pages[this.ctg].pages[this.pg].description;
}
}
this.tpl_val.content = fs.readFileSync(path.resolve(__dirname, 'content/'+file+'.htm'), 'utf8');
}
//call methods that sets data for current category and template; receives client request from server
set page(req){
this.setPgCtg(req);
if(this.pages[this.ctg] && this.pages[this.ctg].pages) this.menuSide(this.pages[this.ctg].pages);
this.pageData();
}
//return html page document
get page(){
//adds errors before content
if(this.err.length >0) this.tpl_val.content ='<div id="err">'+this.err.join('<br>')+'</div>'+this.tpl_val.content;
//parse $tpl_val to add data in $tpl; a={${str}}, b=str
var tpl_val = this.tpl_val;
var re = this.tpl.replace(/\{\$\{([^\}]+)\}\}/ig, function(a,b){ return tpl_val[b] ? tpl_val[b] :a; });
return re;
}
}
//assign object of setpage class to module.exports
module.exports = new setpage();
4. Fisierul main.js pentru serverul Node.js
Apoi, cream un fisier "
main.js" in directorul "site1/"; acesta va fi serverul Node.js:
//include needed modules
const http = require('http');
global.fs = require('fs');
global.path = require('path');
global.url = require('url');
const setpage = require('./setpage');
//create the server
const server = http.createServer((req, res)=>{
res.writeHead(200, {'Content-Type':'text/html; charset=utf-8'}); //adds header to display html content with utf-8
//call method that sets page data for current request
setpage.page = req;
//get and write html page content
var page = setpage.page;
res.write(page, 'utf-8');
res.end();
});
server.listen(8080, ()=> {
console.log('Server running at //localhost:8080/');
});
- Dupa ce toate fisierele au fost create in directorul "site1/", initiaza fisierul "
site1/main.js" in interfata command line pentru a porni serverul Node.js:
node site1/main.js
Acceseaza website-ul in browser:
http://localhost:8080/
• Pentru Demo click pe:
Demo Node.js Simple WebSite.
• Pentru a descarca toate fisierele acestui proiect, click pe:
Download Node.js Simple WebSite.