From c08c7c617589db993fc57c250ef7dfebd9fff812 Mon Sep 17 00:00:00 2001 From: astaxie Date: Wed, 9 Jan 2013 18:22:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=A7=8B=E8=B0=83=E6=95=B4=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=EF=BC=8C=E5=86=99=E7=AC=AC=E4=BA=8C=E5=B0=8F=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 14.1.md | 94 ++++++++++++++----- 14.2.md | 65 +++++++++++++ 14.3.md | 6 ++ 14.4.md | 6 ++ 14.5.md | 6 ++ 14.6.md | 6 ++ 14.7.md | 5 + 14.md | 33 +++---- images/14.1.bootstrap2.png | Bin 0 -> 1471 bytes images/14.1.bootstrap3.png | Bin 0 -> 22566 bytes preface.md | 185 +++++++++++++++++++------------------ 11 files changed, 273 insertions(+), 133 deletions(-) create mode 100644 14.7.md create mode 100644 images/14.1.bootstrap2.png create mode 100644 images/14.1.bootstrap3.png diff --git a/14.1.md b/14.1.md index 8d29c2fc..6aba36ba 100644 --- a/14.1.md +++ b/14.1.md @@ -1,26 +1,70 @@ -# 14.1 静态文件支持 -我们在前面已经讲过如何处理静态文件,这小节我们详细的介绍如何在beego里面设置和使用静态文件。通过再介绍一个twitter开源的html、css框架bootstrap,无需任何的设计人员就能够让你快速的建立一个漂亮的站点。 - -## beego静态文件实现和设置 - -## bootstrap集成 -Bootstrap是Twitter推出的一个开源的用于前端开发的工具包。Bootstrap是快速开发Web应用程序的前端工具包。它是一个CSS和HTML的集合,它使用了最新的浏览器技术,给你的Web开发提供了时尚的版式,表单,buttons,表格,网格系统等等。 - -- 组件 -  Bootstrap中包含了丰富的Web组件,根据这些组件,可以快速的搭建一个漂亮、功能完备的网站。其中包括以下组件: -  下拉菜单、按钮组、按钮下拉菜单、导航、导航条、面包屑、分页、排版、缩略图、警告对话框、进度条、媒体对象等 -- Javascript插件 -  Bootstrap自带了13个jQuery插件,这些插件为Bootstrap中的组件赋予了“生命”。其中包括: -  模式对话框、标签页、滚动条、弹出框等。 -- 定制自己的框架代码 -  可以对Bootstrap中所有的CSS变量进行修改,依据自己的需求裁剪代码。 - -![](images/14.1.bootstrap.png?raw=true) - -接下来我们利用bootstrap集成到beego框架里面来,快速的建立一个漂亮的站点 - - -## links - * [目录]() - * 上一节: [扩展Web框架](<14.md>) +# 14.1 静态文件支持 +我们在前面已经讲过如何处理静态文件,这小节我们详细的介绍如何在beego里面设置和使用静态文件。通过再介绍一个twitter开源的html、css框架bootstrap,无需任何的设计人员就能够让你快速的建立一个漂亮的站点。 + +## beego静态文件实现和设置 +Go的net/http包中提供了静态文件的服务,`ServeFile`和`FileServer`等函数。beego的静态文件处理就是基于这一层处理的,具体的实现如下所示: + + //static file server + for prefix, staticDir := range StaticDir { + if strings.HasPrefix(r.URL.Path, prefix) { + file := staticDir + r.URL.Path[len(prefix):] + http.ServeFile(w, r, file) + w.started = true + return + } + } + +StaticDir里面保存的是相应的url对应到静态文件所在的目录,因此在处理URL请求的时候只需要判断对应的请求地址是否包含静态处理开头的url,如果是那么就采用http.ServeFile提供服务。 + +举例如下: + + beego.StaticDir["/asset"] = "/static" + +那么请求url如`http://www.beego.me/asset/bootstrap.css`的请求就会请求`/static/bootstrap.css`来提供反馈给客户端。 + +## bootstrap集成 +Bootstrap是Twitter推出的一个开源的用于前端开发的工具包。Bootstrap是快速开发Web应用程序的前端工具包。它是一个CSS和HTML的集合,它使用了最新的浏览器技术,给你的Web开发提供了时尚的版式,表单,buttons,表格,网格系统等等。 + +- 组件 +  Bootstrap中包含了丰富的Web组件,根据这些组件,可以快速的搭建一个漂亮、功能完备的网站。其中包括以下组件: +  下拉菜单、按钮组、按钮下拉菜单、导航、导航条、面包屑、分页、排版、缩略图、警告对话框、进度条、媒体对象等 +- Javascript插件 +  Bootstrap自带了13个jQuery插件,这些插件为Bootstrap中的组件赋予了“生命”。其中包括: +  模式对话框、标签页、滚动条、弹出框等。 +- 定制自己的框架代码 +  可以对Bootstrap中所有的CSS变量进行修改,依据自己的需求裁剪代码。 + +![](images/14.1.bootstrap.png?raw=true) + +接下来我们利用bootstrap集成到beego框架里面来,快速的建立一个漂亮的站点。 + +1. 首先把下载的bootstrap目录放到我们的项目目录,取名为static,如下截图所示 + + ![](images/14.1.bootstrap2.png?raw=true) + +2. 因为beego默认设置了StaticDir的值,所以如果你的静态文件目录是static的话就无须再增加了: + + StaticDir["/static"] = "static" + +3. 模板中使用如下的地址就可以了: + + //css文件 + + + //js文件 + + + //图片文件 + + +上面可以实现把bootstrap集成到beego中来,如下展示的图就是集成进来之后的展现效果图: + +![](images/14.1.bootstrap3.png?raw=true) + +这些模板和格式bootstrap官方都有提供,这边就不在重复贴代码,大家可以上bootstrap官方网站学习如何编写这样的模板。 + + +## links + * [目录]() + * 上一节: [扩展Web框架](<14.md>) * 下一节: [Session支持](<14.2.md>) \ No newline at end of file diff --git a/14.2.md b/14.2.md index e69de29b..42656214 100644 --- a/14.2.md +++ b/14.2.md @@ -0,0 +1,65 @@ +# 14.2 Session支持 +第六章的时候我们介绍过如何在Go语言中使用session,也实现了一个sessionManger,beego基于sessionManager实现了框架方便的处理session功能。 + +## session集成 +beego中主要有如下这些全局变量来控制session处理: + + //related to session + SessionOn bool // 是否开启session模块,默认不开启 + SessionProvider string // session后端提供处理模块,默认是sessionManager支持的memory + SessionName string // 客户端保存的cookies的名称 + SessionGCMaxLifetime int64 // cookies有效期 + + GlobalSessions *session.Manager //全局session控制器 + +当然上面这些变量需要初始化值以及如何配合配置文件设置来设置这些值: + + if ar, err := AppConfig.Bool("sessionon"); err != nil { + SessionOn = false + } else { + SessionOn = ar + } + if ar := AppConfig.String("sessionprovider"); ar == "" { + SessionProvider = "memory" + } else { + SessionProvider = ar + } + if ar := AppConfig.String("sessionname"); ar == "" { + SessionName = "beegosessionID" + } else { + SessionName = ar + } + if ar, err := AppConfig.Int("sessiongcmaxlifetime"); err != nil && ar != 0 { + int64val, _ := strconv.ParseInt(strconv.Itoa(ar), 10, 64) + SessionGCMaxLifetime = int64val + } else { + SessionGCMaxLifetime = 3600 + } + +在beego.Run函数中增加如下代码: + + if SessionOn { + GlobalSessions, _ = session.NewManager(SessionProvider, SessionName, SessionGCMaxLifetime) + go GlobalSessions.GC() + } + +这样如果只要SessionOn设置为true,那么就会默认开启session功能。独立开一个goroutine来处理session。 + +为了方便我们在我们的Controller中方便的使用session,我们在`beego.Controller`中提供了如下方法: + + func (c *Controller) StartSession() (sess session.Session) { + sess = GlobalSessions.SessionStart(c.Ctx.ResponseWriter, c.Ctx.Request) + return + } + +## session使用 +通过上面的代码我们可以看到,beego框架很方便的就继承了session功能,那么我们在项目中如何使用呢?请看的示例代码: + + + + + +## links + * [目录]() + * 上一节: [静态文件支持](<14.1.md>) + * 下一节: [表单及验证支持](<14.3.md>) \ No newline at end of file diff --git a/14.3.md b/14.3.md index e69de29b..b513cf31 100644 --- a/14.3.md +++ b/14.3.md @@ -0,0 +1,6 @@ +# 14.3 表单及验证支持 + +## links + * [目录]() + * 上一节: [Session支持](<14.2.md>) + * 下一节: [用户认证](<14.4.md>) \ No newline at end of file diff --git a/14.4.md b/14.4.md index e69de29b..d266f1b1 100644 --- a/14.4.md +++ b/14.4.md @@ -0,0 +1,6 @@ +# 14.4 用户认证 + +## links + * [目录]() + * 上一节: [表单及验证支持](<14.3.md>) + * 下一节: [多语言支持](<14.5.md>) \ No newline at end of file diff --git a/14.5.md b/14.5.md index e69de29b..72420b06 100644 --- a/14.5.md +++ b/14.5.md @@ -0,0 +1,6 @@ +# 14.5 多语言支持 + +## links + * [目录]() + * 上一节: [用户认证](<14.4.md>) + * 下一节: [pprof支持](<14.6.md>) \ No newline at end of file diff --git a/14.6.md b/14.6.md index e69de29b..c02c13c6 100644 --- a/14.6.md +++ b/14.6.md @@ -0,0 +1,6 @@ +# 14.6 pprof支持 + +## links + * [目录]() + * 上一节: [多语言支持](<14.5.md>) + * 下一节: [小结](<14.7.md>) \ No newline at end of file diff --git a/14.7.md b/14.7.md new file mode 100644 index 00000000..da52dc27 --- /dev/null +++ b/14.7.md @@ -0,0 +1,5 @@ +# 14.7 小结 + +## links + * [目录]() + * 上一节: [pprof支持](<14.6.md>) \ No newline at end of file diff --git a/14.md b/14.md index 7d446bcf..ac25bd71 100644 --- a/14.md +++ b/14.md @@ -1,17 +1,18 @@ -# 14 扩展Web框架 -第十三章介绍了如何开发一个Web框架,通过介绍MVC、路由、日志处理、配置处理完成了一个基本的框架系统,但是一个好的框架需要一些方便的辅助工具来快速的开发Web,那么我们这一章将就如何提供一些快速开发Web的工具进行介绍,第一小节介绍如何处理静态文件,如何利用现有的twitter开源的bootstrap进行快速的开发美观的站点,第二小节介绍如何利用前面介绍的session来进行用户登录处理,第三小节介绍如何方便的输出表单、这些表单如何进行数据验证,如何快速的结合model进行数据的增删改操作,第四小节介绍如何进行一些用户认证,包括http basic认证、http digest认证,第五小节介绍如何利用前面介绍的i18n支持多语言的应用开发。 - -通过本章的扩展,beego框架将具有快速开发Web的特性,最后我们将讲解如何利用这些扩展的特性扩展开发第十三章开发的博客系统,通过开发一个完整、美观的博客系统让读者了解beego开发带给你的快速。 - -## 目录 - * 1 [静态文件支持](14.1.md) - * 2 [Session支持](14.2.md) - * 3 [表单及验证支持](14.3.md) - * 4 [用户认证](14.4.md) - * 5 [多语言支持](14.5.md) - * 6 [小结](14.6.md) - -## links - * [目录]() - * 上一章: [第十三章总结](<13.6.md>) +# 14 扩展Web框架 +第十三章介绍了如何开发一个Web框架,通过介绍MVC、路由、日志处理、配置处理完成了一个基本的框架系统,但是一个好的框架需要一些方便的辅助工具来快速的开发Web,那么我们这一章将就如何提供一些快速开发Web的工具进行介绍,第一小节介绍如何处理静态文件,如何利用现有的twitter开源的bootstrap进行快速的开发美观的站点,第二小节介绍如何利用前面介绍的session来进行用户登录处理,第三小节介绍如何方便的输出表单、这些表单如何进行数据验证,如何快速的结合model进行数据的增删改操作,第四小节介绍如何进行一些用户认证,包括http basic认证、http digest认证,第五小节介绍如何利用前面介绍的i18n支持多语言的应用开发。 + +通过本章的扩展,beego框架将具有快速开发Web的特性,最后我们将讲解如何利用这些扩展的特性扩展开发第十三章开发的博客系统,通过开发一个完整、美观的博客系统让读者了解beego开发带给你的快速。 + +## 目录 + * 1 [静态文件支持](14.1.md) + * 2 [Session支持](14.2.md) + * 3 [表单及验证支持](14.3.md) + * 4 [用户认证](14.4.md) + * 5 [多语言支持](14.5.md) + * 6 [pprof支持](14.6.md) + * 7 [小结](14.7.md) + +## links + * [目录]() + * 上一章: [第十三章总结](<13.6.md>) * 下一节: [静态文件支持](<14.1.md>) \ No newline at end of file diff --git a/images/14.1.bootstrap2.png b/images/14.1.bootstrap2.png new file mode 100644 index 0000000000000000000000000000000000000000..753ffc7901753e9392123dd4bef04c12a311c624 GIT binary patch literal 1471 zcmV;w1wi_VP)2BF)#6n2=J*xbYRn-brIb=Sed+URwOXlEWE`Pl$f?j) zWA2H?AH831UVeDu$t$z7v!-c|yx9pT+kk|Aar5Vm&5qdg;)U}sJpG6mKg{MT7hC-1 z-3JLFgb+$8MM?;H^p)?Yr>A`>P6ES_IggD?z>weA?7Z{p^J4tX##ey}MMN092ZV63 zm1p1hm2dOea<$oPE-Wn6YPI-v8YeYkn+&rFVRI-UuJ@@C0RSC)7}f=)6nZ^y+*@mF zT=*&gIF94GuIsuJrzalTU-{+Qit+MywOUQu;pdOwggTB5000O8h~U`$-amU`T~JD4 z-@0|<##68T6#71Q-iDdCK74(u*=#N?Es5LtvSlU4BEAA-K`$b<@ip*uosx{qTE* zy|qNbhCI1@cb5CCOc3B9+sGw55cVTbRCWCtDS*kq#)J^?61r~%wy`V=A`=>zBVXC_73v%H5I*zr zdu20+Uc7MrqgDr?3{dvP1G``e9S(;8Q56c2V>axg##s{i=Fs?^CxL`DaJ${!y!H%R zy;DlbA?!6h1QEad<5Im|UtV68a_IR)!nJ(0TJ1jf>H7Nm_U?ATW&@xEY^2xg56sWc zAM;2RLC#g0Wm(;BmyPQPOw%mBG{H#LK50ZZkhoVd$kHQte^Kvsp4US$xi5Ni^LpsT zkCeSyjk#81?uQQ^-+2GAt*tG#x>A}fE3}Xn^@xPVH}NLMy8KwwY?1aq zCEzS-sdUF-XHn0co7wK(PQjvjpx~AwB8eh%4)rW5 z0POyCI~|KEf`V5SBgrANLOqN6?bjdg-1!}ox2Pz%PH{1i^724hg=S(=A%-wb`N}1; zE2W}ZRGD+=SbG)KqGow5UrdV{ZTGYf9T)9GC8K?)WV8>JjPgD-+q*$Ul=q>z$|h(Z zDjl_bXw17o)3i-$`%p1Qq9OGnS>7M&p^6U`$!cybpbyO!wS8!uyFpP=W1pY9O2uHB z!(aPQ$!H%c8SO)56K(gj4;`26%>rs4dL-J1W`p*jQD`5^&^}Z$+J{P}P(C#5R?swW z5iObz#gMPrdhz%l=Xey>hkBr*wh8j;LsMP`6wQZ5G=n@0d9{2fKT-0V__J2hIXw|R zRLKe*cds;kXqrW%eW+}r?Vk3b literal 0 HcmV?d00001 diff --git a/images/14.1.bootstrap3.png b/images/14.1.bootstrap3.png new file mode 100644 index 0000000000000000000000000000000000000000..460b81830090fec66ff809ef528bc77a29e55bd9 GIT binary patch literal 22566 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 PEaZre;h{_|o9q7uTRbPs literal 0 HcmV?d00001 diff --git a/preface.md b/preface.md index 4c15541d..49331df6 100644 --- a/preface.md +++ b/preface.md @@ -1,92 +1,93 @@ -* 1.[Go环境配置](1.md) - - 1.1. [Go安装](1.1.md) - - 1.2. [GOPATH 与工作空间](1.2.md) - - 1.3. [Go 命令](1.3.md) - - 1.4. [Go开发工具](1.4.md) - - 1.5. [小结](1.5.md) -* 2.[Go语言基础](2.md) - - 2.1. [你好,Go](2.1.md) - - 2.2. [Go基础](2.2.md) - - 2.3. [流程和函数](2.3.md) - - 2.4. [struct](2.4.md) - - 2.5. [面向对象](2.5.md) - - 2.6. [interface](2.6.md) - - 2.7. [并发](2.7.md) - - 2.8. [小结](2.8.md) -* 3.[Web基础](3.md) - - 3.1 [web工作方式](3.1.md) - - 3.2 [Go搭建一个简单的web服务](3.2.md) - - 3.3 [Go如何使得web工作](3.3.md) - - 3.4 [Go的http包详解](3.4.md) - - 3.5 [小结](3.5.md) -* 4.[表单](4.md) - - 4.1 [处理表单的输入](4.1.md) - - 4.2 [验证表单的输入](4.2.md) - - 4.3 [预防跨站脚本](4.3.md) - - 4.4 [防止多次递交表单](4.4.md) - - 4.5 [处理文件上传](4.5.md) - - 4.6 [小结](4.6.md) -* 5.[访问数据库](5.md) - - 5.1 [database/sql接口](5.1.md) - - 5.2 [使用MySQL数据库](5.2.md) - - 5.3 [使用SQLite数据库](5.3.md) - - 5.4 [使用PostgreSQL数据库](5.4.md) - - 5.5 [使用beedb库进行ORM开发](5.5.md) - - 5.6 [NOSQL数据库操作](5.6.md) - - 5.7 [小结](5.7.md) -* 6.[session和数据存储](6.md) - - 6.1 [session和cookie](6.1.md) - - 6.2 [Go如何使用session](6.2.md) - - 6.3 [session存储](6.3.md) - - 6.4 [预防session劫持](6.4.md) - - 6.5 [小结](6.5.md) -* 7.[文本处理](7.md) - - 7.1 [XML处理](7.1.md) - - 7.2 [JSON处理](7.2.md) - - 7.3 [正则处理](7.3.md) - - 7.4 [模板处理](7.4.md) - - 7.5 [小结](7.5.md) -* 8.[Web服务](8.md) - - 8.1 [Socket编程](8.1.md) - - 8.2 [WebSocket](8.2.md) - - 8.3 [REST](8.3.md) - - 8.4 [RPC](8.4.md) - - 8.5 [小结](8.5.md) -* 9.[安全与加密](9.md) - - 9.1 [预防CSRF攻击](9.1.md) - - 9.2 [确保输入过滤](9.2.md) - - 9.3 [避免XSS攻击](9.3.md) - - 9.4 [避免SQL注入](9.4.md) - - 9.5 [存储密码](9.5.md) - - 9.6 [加密和解密数据](9.6.md) - - 9.7 [小结](9.7.md) -* 10.[国际化和本地化](10.md) - - 10.1 [设置默认地区](10.1.md) - - 10.2 [本地化资源](10.2.md) - - 10.3 [国际化站点](10.3.md) - - 10.4 [小结](10.4.md) -* 11.[错误处理,调试和测试](11.md) - - 11.1 [错误处理](11.1.md) - - 11.2 [使用GDB调试](11.2.md) - - 11.3 [Go怎么写测试用例](11.3.md) - - 11.4 [小结](11.4.md) -* 12.[部署与维护](12.md) - - 12.1 [应用日志](12.1.md) - - 12.2 [网站错误处理](12.2.md) - - 12.3 [应用部署](12.3.md) - - 12.4 [备份和恢复](12.4.md) - - 12.5 [小结](12.5.md) -* 13.[如何设计一个Web框架](13.md)  - - 13.1 [项目规划](13.1.md)  - - 13.2 [自定义路由器设计](13.2.md) - - 13.3 [controller设计](13.3.md) - - 13.4 [日志和配置设计](13.4.md) - - 13.5 [实现博客的增删改](13.5.md) - - 13.6 [小结](13.6.md)  -* 14.[扩展Web框架](14.md) - - 14.1 [静态文件支持](14.1.md) - - 14.2 [Session支持](14.2.md) - - 14.3 [表单支持](14.3.md) - - 14.4 [用户认证](14.4.md) - - 14.5 [多语言支持](14.5.md) - - 14.6 [小结](14.6.md) \ No newline at end of file +* 1.[Go环境配置](1.md) + - 1.1. [Go安装](1.1.md) + - 1.2. [GOPATH 与工作空间](1.2.md) + - 1.3. [Go 命令](1.3.md) + - 1.4. [Go开发工具](1.4.md) + - 1.5. [小结](1.5.md) +* 2.[Go语言基础](2.md) + - 2.1. [你好,Go](2.1.md) + - 2.2. [Go基础](2.2.md) + - 2.3. [流程和函数](2.3.md) + - 2.4. [struct](2.4.md) + - 2.5. [面向对象](2.5.md) + - 2.6. [interface](2.6.md) + - 2.7. [并发](2.7.md) + - 2.8. [小结](2.8.md) +* 3.[Web基础](3.md) + - 3.1 [web工作方式](3.1.md) + - 3.2 [Go搭建一个简单的web服务](3.2.md) + - 3.3 [Go如何使得web工作](3.3.md) + - 3.4 [Go的http包详解](3.4.md) + - 3.5 [小结](3.5.md) +* 4.[表单](4.md) + - 4.1 [处理表单的输入](4.1.md) + - 4.2 [验证表单的输入](4.2.md) + - 4.3 [预防跨站脚本](4.3.md) + - 4.4 [防止多次递交表单](4.4.md) + - 4.5 [处理文件上传](4.5.md) + - 4.6 [小结](4.6.md) +* 5.[访问数据库](5.md) + - 5.1 [database/sql接口](5.1.md) + - 5.2 [使用MySQL数据库](5.2.md) + - 5.3 [使用SQLite数据库](5.3.md) + - 5.4 [使用PostgreSQL数据库](5.4.md) + - 5.5 [使用beedb库进行ORM开发](5.5.md) + - 5.6 [NOSQL数据库操作](5.6.md) + - 5.7 [小结](5.7.md) +* 6.[session和数据存储](6.md) + - 6.1 [session和cookie](6.1.md) + - 6.2 [Go如何使用session](6.2.md) + - 6.3 [session存储](6.3.md) + - 6.4 [预防session劫持](6.4.md) + - 6.5 [小结](6.5.md) +* 7.[文本处理](7.md) + - 7.1 [XML处理](7.1.md) + - 7.2 [JSON处理](7.2.md) + - 7.3 [正则处理](7.3.md) + - 7.4 [模板处理](7.4.md) + - 7.5 [小结](7.5.md) +* 8.[Web服务](8.md) + - 8.1 [Socket编程](8.1.md) + - 8.2 [WebSocket](8.2.md) + - 8.3 [REST](8.3.md) + - 8.4 [RPC](8.4.md) + - 8.5 [小结](8.5.md) +* 9.[安全与加密](9.md) + - 9.1 [预防CSRF攻击](9.1.md) + - 9.2 [确保输入过滤](9.2.md) + - 9.3 [避免XSS攻击](9.3.md) + - 9.4 [避免SQL注入](9.4.md) + - 9.5 [存储密码](9.5.md) + - 9.6 [加密和解密数据](9.6.md) + - 9.7 [小结](9.7.md) +* 10.[国际化和本地化](10.md) + - 10.1 [设置默认地区](10.1.md) + - 10.2 [本地化资源](10.2.md) + - 10.3 [国际化站点](10.3.md) + - 10.4 [小结](10.4.md) +* 11.[错误处理,调试和测试](11.md) + - 11.1 [错误处理](11.1.md) + - 11.2 [使用GDB调试](11.2.md) + - 11.3 [Go怎么写测试用例](11.3.md) + - 11.4 [小结](11.4.md) +* 12.[部署与维护](12.md) + - 12.1 [应用日志](12.1.md) + - 12.2 [网站错误处理](12.2.md) + - 12.3 [应用部署](12.3.md) + - 12.4 [备份和恢复](12.4.md) + - 12.5 [小结](12.5.md) +* 13.[如何设计一个Web框架](13.md)  + - 13.1 [项目规划](13.1.md)  + - 13.2 [自定义路由器设计](13.2.md) + - 13.3 [controller设计](13.3.md) + - 13.4 [日志和配置设计](13.4.md) + - 13.5 [实现博客的增删改](13.5.md) + - 13.6 [小结](13.6.md)  +* 14.[扩展Web框架](14.md) + - 14.1 [静态文件支持](14.1.md) + - 14.2 [Session支持](14.2.md) + - 14.3 [表单支持](14.3.md) + - 14.4 [用户认证](14.4.md) + - 14.5 [多语言支持](14.5.md) + - 14.6 [pprof支持](14.6.md) + - 14.7 [小结](14.7.md) \ No newline at end of file