What can node.js do? I still don't know where he is, and I have no chance to get in touch with that kind of project. Just because like, spare time to do a website and backstage. A deep understanding of the truth is that if you like a technology you can play with, but if you use the project you have to spend some time to solve a lot of problems.
 
Technology to use:
 
Express + Jade
 
SQLite + sequelize
 
Redis
 
1. About Jade
 
Support include. For example, the include./includes/header header is a partial view, similar to the ASP.net user control.
 
Support extends. For example: extends. /layout use master page layout.
 
The For loop is also so simple.
 
The 
 code is as follows: 
 each item in userlist (UserList server to the front-end variable) 
 TR 
 TD #{item.username} 
 TD #{item.telephone} 
 TD #{item.email} 
 
More like append:
 
The 
 code is as follows: 
 extends. /admin_layout 
 Append head 
Link (rel= ' stylesheet ', href= '/stylesheets/font-awesome.css ') 
 script (src= '/javascripts/bootstrap.js ') 
 script (src= '/javascripts/bootstrap-wysiwyg.js ') 
 script (src= '/javascripts/jquery.hotkeys.js ') 
 Block Content 
 
Append will put the steps and styles in the back of the master page head.
 
2.sequelize to implement the ORM framework. Support SQLite MySQL MongoDB
 
To define a model (article):
 
The 
 code is as follows: 
 var Article = sequelize.define (' Article ', { 
 title:{ 
 Type:Sequelize.STRING, 
 validate:{} 
   }, 
 content:{type:sequelize.string,validate:{}}, 
 icon:{type:sequelize.string,validate:{}}, 
 iconname:{type:sequelize.string}, 
sequencing:{type:sequelize.string,validate:{}} 
 },{ 
 classmethods:{ 
//Article Classification 
 getcountall:function (objfun) { 
}//end Getcountall 
}//end classmethods 
 }); 
 Article.belongsto (Category); 
 
Article.belongsto (Category); Each article has a category.
 
I wrote the pagination-related approach to the initialization sequelize. This method (Pageoffset, Pagelimit) will be available for each model definition.
 
The 
 code is as follows: 
 var sequelize = new Sequelize (' database ', ' username ', ' password ', { 
//sqlite! now! 
 dialect: ' SQLite ', 
//The storage engine for SQLite 
//-Default ': Memory: ' 
 Storage:config.sqlitePath, 
 define:{ 
 classmethods:{ 
Pageoffset:function (pagenum) { 
 if (isNaN (pagenum) | | Pagenum < 1) { 
 pagenum = 1; 
         } 
 return (pageNum-1) * This.pagelimit (); 
       }, 
 pagelimit:function () { 
 return 10; Show 10 
 per page
       }, 
 totalpages:function (totalnum) { 
 var total =parseint (Totalnum + this.pagelimit ()-1)/This.pagelimit ()), 
 arraytotalpages = []; 
For (Var i=1. i<= Total; i++) { 
 Arraytotalpages.push (i); 
         } 
 return arraytotalpages; 
       } 
     }, 
 instancemethods:{ 
     } 
   } 
 }); 
 
Use:
 
The 
 code is as follows: 
 Article.findandcountall ({include:[category],offset:article.pageoffset (req.query.pageNum), limit: Article.pagelimit ()}). Success (function (row) { 
 res.render (' Article_list ', { 
 title: ' Article Management ', 
 ArticleList:row.rows, 
pages:{ 
 totalPages:Article.totalPages (row.count), 
 CurrentPage:req.query.pageNum, 
 Router: ' article ' 
       } 
     }); 
   }); 
 
To save the model:
 
The 
 code is as follows: 
 Exports.add = function (req, res) { 
 var form = new Formidable. Incomingform (); 
 Form.uploaddir = Path.join (__dirname, ' ... /files '); 
 form.keepextensions = true; 
 form.parse (req, function (err, fields,files) { 
 var//iconpath = Files.icon.path, 
index = Iconpath.lastindexof ('/') <= 0? Iconpath.lastindexof ('): Iconpath.lastindexof ('/'), 
 icon = path.basename (Files.icon.path),//ICONPATH.SUBSTR (index + 1,iconpath.length-index), 
 iconname = files.icon.name; 
 var title = Fields.title; 
 id = fields.articleid; 
 title = Fields.title, 
 content = fields.content, 
 mincontent = fields.mincontent, 
 sequencing=fields.sequencing = = 0? 0:1, 
 category = Fields.category; 
Article.sync (); Create a table if it does not exist. 
 Category.find (Category). Success (function (c) { 
 var Article = article.build ({ 
 Title:title, 
 Content:content, 
 Mincontent:mincontent, 
 Icon:icon, 
 Iconname:iconname, 
 sequencing:sequencing 
         }); 
 Article.save () 
. Success (Function (a) { 
 A.setcategory (c); 
 return Res.redirect ('/admin/article '); 
         }); 
       }); End Category 
   }); 
 } 
 
Path.basename:
 
The 
 code is as follows: 
//iconpath = Files.icon.path, 
//index = Iconpath.lastindexof ('/') <= 0? Iconpath.lastindexof ('): Iconpath.lastindexof ('/'), 
 icon = <strong>path.basename</strong> (Files.icon.path),//ICONPATH.SUBSTR (index + 1,iconpath.length -index), 
 
Get the filename, for example:/a/b/aa.txt => aa.txt. At first I used an intercept string, but I can do it, but the operating system is different. Mac uses '/'.  Window below is ', I'm also a problem that was discovered after the deployment was complete. Later found Path.basename direct replacement (document reading less, the disadvantage AH). The goodwill of the Node.js was added 1 points. :)
 
3. The Redis cache frequently queries and rarely changes data.
 
The 
 code is as follows: 
 getcountall:function (objfun) { 
 redis.get (' Articles_getcountall ', function (err,reply) { 
 if (err) { 
 Console.log (ERR); 
 return; 
         } 
 if (reply = = null) { 
Db.all (' SELECT count (articles. CategoryID) as count,categories.name,categories.id from articles left join categories on Articles.categoryid = Categories . ID GROUP BY articles. CategoryID ', function (err,row) { 
 redis.set (' Articles_getcountall ', json.stringify (row)); 
 objfun (row); 
           }); 
}else{ 
 Objfun (Reply); 
         } 
       }); 
 
This method is defined in the model layer. Because it is express, so as far as possible with the MVC way to develop. In fact, route implements the Controller Layer feature (route folder, which should be named Controller).