[12 Project 学 Node.js] Project 2: Basic Express Website

Description:

using routingjade templatenodemailer module

Express Setup

首先,安装 express globally
npm install -g express

修改package.json,加入dependencies,一一列出要install的package,改完存档
"*": 代表要最新版本

{  "name": "2_express_website",  "version": "1.0.0",  "description": "Simple website",  "main": "app.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"  },  "author": "gogocatmario",  "license": "ISC",  "dependencies": {      "body-parser": "*",      "express": "*",      "jade": "*",      "nodemailer": "*"  }}

执行batch install
npm会把dependencies列出的所有module都install到project目录
npm install

Express Example

撰写app.js,并执行server,打开网页确认是否有画面,且console有show log

var express = require('express');var path = require('path');var bodyParser = require('body-parser');var nodemailer = require('nodemailer');var app = express();//set up middlewareapp.use(bodyParser.json());app.use(bodyParser.urlencoded({extended: false}));app.listen(3000);console.log('Server is running on port 3000...')

因为此时尚未有routing,所以网页打开会show Cannot GET/
不过先验证网页开得起来就行了。

接下来,加入routing

var express = require('express');var path = require('path');var bodyParser = require('body-parser');var nodemailer = require('nodemailer');var app = express();//set up middlewareapp.use(bodyParser.json());app.use(bodyParser.urlencoded({extended: false}));//routingapp.get('/', function(req, res){    res.send("<h1>Hello world from res</h1>");    console.log("Hello world from console");});app.listen(3000);console.log('Server is running on port 3000....');

确认网页有出现 Hello World,就可以往下一步了。

Page Routes & Views (using Jade)

Jade Setup (加到app.js)

//viewsapp.set('views', path.join(__dirname, 'views'));app.set('view engine', 'jade');

修改 routing (res.send 改成 res.render)

//routingapp.get('/', function(req, res){    res.render('index');});

create views 资料夹,用来放jade views

建立index.jade
h3 Hello World

相关连结:
Jade example:
https://naltatis.github.io/jade-syntax-docs/
Jade Convertor:
http://html2jade.org/

上面是简单的jade使用範例
可以建立一个範本,让每个jade文件reuse,不需要所有jade都包含完整的code

建立layout.jade,用来当作所有views的範本

doctype htmlhtml head  title my jade template body  h1 Hello World

修改index.jade,开始参考layout.jade,只有block content的位置内容不同

extends layoutblock content h3 Hello World

为layout.jade加入bootstrap css

create public 资料夹,在public中建立stylesheet资料夹用来放css
将download下来的bootstrap.css copy到stylesheet中

目录会长得像这样:

express_website-node_modules-public -stylesheet  bootstrap.css-views  index.jade  layout.jadeapp.jspackage.json

修改app.js

//stylesheetapp.use(express.static(path.join(__dirname, 'public')));

使用jumbotron example建立website

http://getbootstrap.com/getting-started/#examples
from: jumbotron + Starter template

开新文件,copy jumbotron html过来,并修改以下几个地方:
<a class="navbar-brand" href="#">PC Repairs</a>

从Starter template複製ul,并修改:

          <ul class="nav navbar-nav">            <li><a href="/">Home</a></li>            <li><a href="/about">About</a></li>            <li><a href="/contact">Contact</a></li>          </ul>

head 中加入bootstrap
<link href="stylesheet/bootstrap.css" rel="stylesheet">

移除不需要的内容后,结果如下

<!DOCTYPE html><html>  <head>    <title>Jumbotron Template for Bootstrap</title>    <!-- Bootstrap core CSS -->    <link href="/stylesheet/bootstrap.css" rel="stylesheet">  </head>  <body>    <nav class="navbar navbar-inverse navbar-fixed-top">      <div class="container">        <div class="navbar-header">          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">            <span class="sr-only">Toggle navigation</span>            <span class="icon-bar"></span>            <span class="icon-bar"></span>            <span class="icon-bar"></span>          </button>          <a class="navbar-brand" href="#">PC Repairs</a>        </div>        <div id="navbar" class="collapse navbar-collapse">          <ul class="nav navbar-nav">            <li><a href="/">Home</a></li>            <li><a href="/about">About</a></li>            <li><a href="/contact">Contact</a></li>          </ul>        </div><!--/.navbar-collapse -->      </div>    </nav>    <!-- Main jumbotron for a primary marketing message or call to action -->    <div class="jumbotron">      <div class="container">        <h1>Hello, world!</h1>        <p>This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>        <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more »</a></p>      </div>    </div>    <div class="container">      <!-- Example row of columns -->      <div class="row">        <div class="col-md-4">          <h2>Heading</h2>          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>          <p><a class="btn btn-default" href="#" role="button">View details »</a></p>        </div>        <div class="col-md-4">          <h2>Heading</h2>          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>          <p><a class="btn btn-default" href="#" role="button">View details »</a></p>       </div>        <div class="col-md-4">          <h2>Heading</h2>          <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>          <p><a class="btn btn-default" href="#" role="button">View details »</a></p>        </div>      </div>      <hr>      <footer>        <p>© 2016 Company, Inc.</p>      </footer>    </div> <!-- /container -->  </body></html>

copy 改好的 html 到 Jade Convertor,copy output jade to layout.jade

doctype htmlhtml  head    title Jumbotron Template for Bootstrap    // Bootstrap core CSS    link(href='/stylesheet/bootstrap.css', rel='stylesheet')  body    nav.navbar.navbar-inverse.navbar-fixed-top      .container        .navbar-header          button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#navbar', aria-expanded='false', aria-controls='navbar')            span.sr-only Toggle navigation            span.icon-bar            span.icon-bar            span.icon-bar          a.navbar-brand(href='#') PC Repairs        #navbar.collapse.navbar-collapse          ul.nav.navbar-nav            li              a(href='/') Home            li              a(href='/about') About            li              a(href='/contact') Contact        // /.navbar-collapse    // Main jumbotron for a primary marketing message or call to action    .jumbotron      .container        h1 Hello, world!        p          | This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.        p          a.btn.btn-primary.btn-lg(href='#', role='button') Learn more »    .container      // Example row of columns      .row        .col-md-4          h2 Heading          p            | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.          p            a.btn.btn-default(href='#', role='button') View details »        .col-md-4          h2 Heading          p            | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.          p            a.btn.btn-default(href='#', role='button') View details »        .col-md-4          h2 Heading          p            | Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.          p            a.btn.btn-default(href='#', role='button') View details »      hr      footer        p © 2016 Company, Inc.    // /container

layout.jade中的main jumbotron段落应该只在index页面出现
因此将 main jumbotron内容copy到 index.jade

要剪下的部份

    // Main jumbotron for a primary marketing message or call to action    .jumbotron      .container        h1 Hello World        p          | This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.        p          a.btn.btn-primary.btn-lg(href='#', role='button') Learn more »    .container      // Example row of columns      .row        .col-md-4          h2 Heading          p            | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.          p            a.btn.btn-default(href='#', role='button') View details »        .col-md-4          h2 Heading          p            | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.          p            a.btn.btn-default(href='#', role='button') View details »        .col-md-4          h2 Heading          p            | Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.          p            a.btn.btn-default(href='#', role='button') View details » 

在layout.jade剪下的位置加入 block content
(记得空格位置要对齐,不然jade转html时会搞错)

     ...     // /.nav-collapse block content hr footer     ...

置中footer,加入class="text-center"

... footer  p(class="text-center") © 2016 Company, Inc.// /container

在 index.jade 使用参数代入值

修改routing,加入title参数

//routingapp.get('/', function(req, res){    res.render('index', {title: 'Welcome'});});

修改index.jade,把 Hello World 改成代入参数的格式

...    .jumbotron      .container        h1 #{title}        p...

如此一来,index page 就设定好了,接下来加入 about page

修改app.js,加入about routing

app.get('/about', function(req, res){    res.render('about');});

create about.jade
p 里面需要在T前面加上pipeline,不然jade convert时会以为是Tab,就只会show "is the ..."

extends layoutblock content h1 About Us p  |This is the about page

到这里,index page 和 about page 都设定完成。

Nodemailer Module

接下来要create contact page

修改app.js,加入contact的routing

app.get('/contact', function(req, res){    res.render('contact');});

create contact.jade,建立表单

extends layoutblock content .container  form(method='post', action='contact/send')   h1 Contact   .form-group    label Name    input.form-control(type='text',    name='name', placeholder='Enter Name')   .form-group    label Email    input.form-control(type='email',    name='email', placeholder='Enter Email')   .form-group    label Message    textarea.form-control(name='message', placeholder='Enter Message')   button.btn.btn-default(type='Submit') Submit

Contact 画面长得像这样
http://img2.58codes.com/2024/20104222LEsukNozRO.png

当点选Submit button时,会透过POST送出request
针对POST request,需要撰写对应的server动作

修改app.js,加入POST request routing
其中的 user / pass / from 需填写寄件者的gmail 帐户和密码
to 的内容则填写收件者的 gmail 帐户

app.post('/contact/send', function(req, res){    //console.log('Test');    //specify server options    var transporter = nodemailer.createTransport({        service: 'Gmail',        auth: {            user: 'your gmail',              pass: 'your gmail password'        }    });    //setup mail options    var mailOptions = {        from: 'Your Name <your gmail>',        to: 'your gmail',        subject: 'Website Submission',        text: 'You have a submission with the following details... Name: ' + req.body.name + 'Email: ' + req.body.email + 'Message: ' + req.body.message,        html: '<p>You have a submission with the following details...</p><ul><li>Name: '+req.body.name+'</li><li>Email: '+req.body.email+'</li><li>Message: '+req.body.message+'</li></ul>'    };    transporter.sendMail(mailOptions, function(error, info){        if(error){            console.log(error);            res.redirect('/');        } else {            console.log('Message Sent: ' + info.response);            res.redirect('/');        }    });});

注:
讲者有提示,目前nodemailer应该只support gmail engine
其他家的email或是自己的SMTP,还没办法用nodemailer

到gmail暂时开启低安全程式存取权限(不然gmail不给寄信),测试完之后记得改回来
(google 关键字: gmail access for less secure apps)

http://img2.58codes.com/2024/20104222jzzBxtIBEM.png
接着启动server,填写contact form按submit,就可以到 gmail 去收信了
http://img2.58codes.com/2024/20104222BwFYhkWfU4.png

最后修改几个地方练习一下改jade,结束这回合。

app.jsapp.get('/', function(req, res){    res.render('index', {title: 'Computer Not Working?'});});index.jade...  .container      // Example row of columns      .row        .col-md-4          h2 Virus Removal....          h2 Hardware Issues....          h2 Software Issues....

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章