- 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:
content dir of simple website with Node.js

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.

Un Test simplu in fiecare zi

HTML
CSS
JavaScript
PHP-MySQL
Engleza
Spaniola
Care tag se foloseste in <table> pentru a crea celula de tip "header"?
<thead> <th> <td>
<table><tr>
  <th>Title 1</th>
  <th>Title 2</th>
</tr></table>
Ce proprietate CSS seteaza distanta dintre randuri?
line-height word-spacing margin
.some_class {
  line-height: 150%;
}
Care functie deschide o noua fereastra.
alert() confirm() open()
document.getElementById("id_button").onclick = function(){
  window.open("http://coursesweb.net/");
}
Indicati functia PHP care returneaza un array cu numele fisierelor si directoarelor dintr-un director.
mkdir() scandir() readdir()
$ar_dir = scandir("dir_name");
var_export($ar_dir);
Care din urmatoarele forme a verbului "sleep" (a dormi) se foloseste pentru viitor?
sleeping slept will sleep
He will sleep there.
- El va dormi acolo.
Care din urmatoarele forme a verbului "dormir" (a dormi) se foloseste pentru viitor?
dormido dormirá durmiendo
Él dormirá allí.
- El va dormi acolo.
Creare web-site simplu cu Node.js

Last accessed pages

  1. Limba spaniola curs online incepatori si avansati (461)
  2. Data si Timp - Obiect Date (2)
  3. Incarcare imagini pe server si afisare cu Ajax (6)
  4. Curs si Tutoriale Ajax (66)
  5. Bubbles3 (3489)

Popular pages this month

  1. Bubbles3 (3489)
  2. Gramatica limbii engleze - Prezentare Generala (2797)
  3. Prezentul simplu si continuu - Present Tense Simple and Continuous (2526)
  4. Butterfly Kyodai (2204)
  5. Zuma Deluxe (2083)