איך יוצרים אתר פשוט עם express.js
אומנם קל להגדיר אבל לא פשוט בהתחלה להבין מה להגדיר...
בואו נקים אתר שמאפשר לנהל בצורה בסיסית רשימת משימות לביצוע. אפשר
יהיה לראות את המשימות, להוסיף משימות ולסמן משימות שבוצעו.
קישור לקוד בשלמותו כקובץ זיפ
קישור לקוד בשלמותו כקובץ זיפ
סוגי הקבצים בתיקייה
כדי לכתוב קוד ל nodejs שמממש את האתר הזה אז כדאי לדעת שלאתר כזה יש קבצים לצד ה client וקבצים לצד ה server. כולם יושבים בתתי תיקיות בתוך התיקייה הראשית שנותנים ל nodejs. זה קצת מקשה על ההבנה איזה קבצים מגיעים לאן ...
קבצים עבור צד ה client כוללים דפי HTML סטטיים, קבצי JS של ספריות כמו jQuery ו bootstrap (לעיצוב), קבצי עיצוב (CSS) וקבצי JS של האפליקציה עצמה שרלבנטים לצד ה client.
קבצים עבור צד ה server כוללים קוד JS ל nodejs, ספריות של nodejs, קבצים נתונים לפלאג-ים השונים שנשתמש בהם עבור express ואולי עוד דברים.
מה האתר מספק?
אנחנו רוצים לכתוב קוד ל nodejs כך שכאשר הוא ירוץ, יהיה לנו שרת ווב שמבצע את הדברים הבאים:
- כאשר פונים ל '/' אז יחזור דף HTML שיש בו כותרת "Home Page"
- כאשר פונים ל 'tasks/' אז מקבים בחזרה דף HTML ובו:
- רשימת המשימות שהוכנסו עד כה. על כל משימה שבוצעה יהיה קו (זה הדבר שיסמן שהיא בוצעה). כל משימה שלא בוצעה תהיה קישור שכאשר לוחצים עליו, המשימה תסומן שבוצעה.
- שדה קלט + checkbox שיאפשר להכניס משימה חדשה (ולסמן האם בוצעה כבר). הטופס הזה ישתמש ב REST request שמתואר בנקודה הבאה.
- כאשר שולחים פקודת POST לכתובת 'taskCompleted/' (פקודת REST) אז צריך לשלוח יחד עם הפקודה json ובו שדה title ושדה completed.
בנייה בשלבים
את האתר נבנה בשלבים:
- שלב ראשון: נריץ את nodejs ברמה הכי בסיסית כדי לראות שהוא עובד כשרת ווב תקין.
- שלב שני: נכניס את מנגנון ה route של express. המנגנון הזה מאפשר לנו להגדיר די בפשטות איזה קוד להריץ עבור כל שורת URL.
- שלב שלישי: נכניס את מנגנון ה view של express. המנגנון הזה מאפשר לנו להשתמש בתבניות HTML כדי להחזיר דף HTML ל client. נשתמש בפורמט jade כדי להגדיר את ה HTML template. זה הרבה יותר נוח מאפשר לבנות HTML בצורה פשטנית.
- שלב רביעי: נכניס שתי ספריות JS שימושיות - jquery ו bootstrap.
- נוסיף התייחסות לטופס (form) שמאפשר להוסיף משימה חדשה.
שלב ראשון – הרמת אתר שיש לו דף ראשי אחד
app.js
======
var express = require('express');
var path = require('path');
var app = express();
app.use('/', function (req, res, next) {
res.send('Site
homepage');
});
app.js הוא הקובץ הראשי של התוכנית ואותו נריץ ע"י node.
פקודת ה use אומרת ל express להריץ את הפונקציה על כל בקשה שה URL בה הוא ‘/’. הפונקציה יכולה לבצע
משהו ואז או להחזיר תשובה לבקשה ע"י res.send או לקרוא לעוד פונקציות
טיפול שאולי מוגדרות ע"י קריאה ל next().
עכשיו (לאחר הרצת node), נקבל את ההודעה Site homepage כאשר נגלוש לאתר.
שלב שני – הכנסת מנגנון route מקצועי
אפליקציית express מכילה בדר"כ הרבה
דפים ואז יש הרבה routes (ניתוב לפונקציות שונות
ע"פ מה שרשום ב URL). Express מספק
מנגנון מרשים יותר לטפל בניתובים כאלה – router.
tasksRoutes.js
==============
var express = require('express');
var bodyParser = require('body-parser'); //
parse json body
var cookieParser = require('cookie-parser');
// parse cookies
var router = express.Router();
// URL is relative to route base URL
// GET request (to handle POST request,
write router.post)
router.get('/', function(req, res, next) {
res.send('Tasks
main page');
//
can return JSON response
//res.render('index',
{ title: 'Express' });
});
module.exports = router;
app.js
======
var express = require('express');
var path = require('path');
var tasksRoutes = require('./routes/tasksRoutes');
var app = express();
app.use('/', function (req, res, next) {
res.send('Site
homepage');
});
app.use('/tasks', tasksRoutes);
את כל פונקציות הטיפול נרשום מעכשיו ב tasksRoutes. זו תהיה חלוקה מודולרית
של הקוד.
ה router נותן לנו גישה נוחה
לחלקים פרמטריים מה URL:
router.get(‘/task/:name/:id?’, function
(req,res,next) {
var
name = req.params.name;
var
id = req.params.id;
var user =
req.query.user;
…
}
כאן, express, בונה לבד את האובייקט req.params ושם בו את הפרמטרים משורת ה URL. הוא גם בונה את req.query ורושם שם את ה query parameters. סימן השאלה ליד id אומר כי השדה הזה הוא
אופציונלי.
שלב שלישי – שימוש ב views כדי להחזיר HTML בצורה יותר משוכללת
כאשר המשתמש מבקש דפים שונים אז רוצים להחזיר HTML. אפשר להחזיר ע"י res.send אבל זה מאוד מייגע לבנות HTML בצורה כזו.
לשם כך, express נותן מנגנון של HTML templates שבעזרתם בונים את התשובה. המנגנון הזה נקרא views.
כאשר משתמשים במנגנון הזה, אפשר להגדיר views שונים שלכל אחד יש שם. כל
view מגדיר בצורה כלשהו פיסת HTML שאפשר לדחוף לתוכה מידע. כאשר השרת רוצה להחזיר HTML אז יכול להגיד שהוא מחזיר view בשם מסויים ע"י res.render(view name).
כדי להשתמש במנגנון כזה, צריך להגיד ל express את סוג השיטה לתאור ה HTML ואיפה יושבים הקבצים של ה views השונים:
app.js
======
app.set('views', path.join(__dirname,
'views'));
app.set('view engine', 'jade');
השיטה השכיחה ב express לתאר view היא jade. בשיטה זו, במקום HTML רושמים את התגים ללא סימני ‘<’ או '>'.
layout.jade
===========
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
index.jade
==========
extends layout
block content
h1=
title
p
Welcome to #{title}
error.jade
==========
extends layout
block content
h1=
message
h2=
error.status
pre
#{error.stack}
כמה דברים לדעת על פורמט Jade:
-
אפשר לשים תגית block בקובץ. זה אומר שאפשר למלא את הבלוק מקובץ Jade אחר.
-
בקובץ האחר רושמים
שהוא מרחיב את הקובץ המקורי ע"י extends
ועכשיו
כאשר רוצים להחזיר HTML אפשר להשתמש ב HTML template:
tasks.jade
==========
extends layout
block content
ul.list-group
each
task in tasks
li.list-item
li.list-group-item
if
task.completed
s(id=task.id
|| inx , data-completed=’true’) = task.title
else
a(id=task.id
|| inx , data-completed=’false’) = task.title
tasksRoute.js
=============
var router = require(‘express’).Router();
router.get(‘/’, function(req, res) {
res.render(‘tasks’);
});
module.exports=router;
שלב רביעי – נשתמש ב jquery ו bootstrap
כדי שהיישום יראה יותר ויהיה יותר קל, נשתמש ב jquery ו bootstrap:
tasks.jade
==========
html
head
title
This is a Simple Todo List
link(rel="stylesheet",href="/bower_components/bootstrap/dist/css/bootstrap.min.css")
link(rel="stylesheet",href="/bower_components/bootstrap/dist/css/bootstrap-theme.min.css")
script(src="/bower_components/jquery/dist/jquery.min.js")
body
div.container
div.page-Header
h1
Express ToDo List
block
content
כדי שהשרת יביא את הקבצים הסטטיים האלה ל client צריך להגיד ל express איפה הקבצים הסטטיים:
app.js
======
app.use(express.statuc(path.join(__dirname,’public’));
זה אומר ל express לחפש קבצים סטטיים
בתיקיית public.
שלב חמישי – הוספת טופס להוספת משימות
נוסיף טופס בעזרתו מוסיפים משימות.
נשים את הטופס ב tasks.jade
tasks.jade
==========
extends layout
block content
ul.list-group
each
task,inx in tasks
li.list-group-item
if
task.completed
s(id=task._id
|| inx, data-completed='true')= task.title
else
a(id=task._id
|| inx,data-completed='false')= task.title
div
form.form-inline(method="post")
div.form-group
input.form-control(placeholder="Task
title",type="text",name="title",required="")
div.form-group.checkbox
label
input(type="checkbox",
value="true",name="completed")
|Completed?
|Completed?
button.btn.btn-default(type="submit") Submit
script(src="/javascripts/tasks.js")
ועכשיו נטפל במידע שמגיע מהטופס
tasks.js
=========
router.post("/",function(req,res){
service.addTask(req.body.title,req.body.completed
? true : false)
res.render("tasks",{tasks:service.getTasks()});
})
Comments