541d7f71 by Dobrosław Żybort

Update: clean and fix docs markdown

1 parent fdb94aeb
1 ##What is hot update? 1 ## What is hot update?
2
2 If you have used nginx, you may know that nginx supports hot update, which means you can update your nginx without stopping and restarting it. It serves old connections with old version, and accepts new connections with new version. Notice that hot compiling is different from hot update, where hot compiling is monitoring your source files and recompile them when the content changes, it requires stop and restart your applications, `bee start` is a tool for hot compiling. 3 If you have used nginx, you may know that nginx supports hot update, which means you can update your nginx without stopping and restarting it. It serves old connections with old version, and accepts new connections with new version. Notice that hot compiling is different from hot update, where hot compiling is monitoring your source files and recompile them when the content changes, it requires stop and restart your applications, `bee start` is a tool for hot compiling.
3 4
4 ##Is hot update necessary? 5
6 ## Is hot update necessary?
7
5 Some people says that hot update is not as useful as its cool name. In my opinion, this is absolutely necessary because zero-down server is our goal for our services. Even though sometimes some errors or hardware problems may occur, but it belongs to design of high availability, don't mix them up. Service update is a known issue, so we need to fix this problem. 8 Some people says that hot update is not as useful as its cool name. In my opinion, this is absolutely necessary because zero-down server is our goal for our services. Even though sometimes some errors or hardware problems may occur, but it belongs to design of high availability, don't mix them up. Service update is a known issue, so we need to fix this problem.
6 9
7 ##How Beego support hot update? 10
11 ## How Beego support hot update?
12
8 The basic principle of hot update: main process fork a process, and child process execute corresponding programs. So what happens? We know that after forked a process, main process will have all handles, data and stack, etc, but all handles are saved in `CloseOnExec`, so all copied handles will be closed when you execute it unless you clarify this, and we need child process to reuse the handle of `net.Listener`. Once a process calls exec functions, it is "dead", system replaces it with new code. The only thing it left is the process ID, which is the same number but it is a new program after executed. 13 The basic principle of hot update: main process fork a process, and child process execute corresponding programs. So what happens? We know that after forked a process, main process will have all handles, data and stack, etc, but all handles are saved in `CloseOnExec`, so all copied handles will be closed when you execute it unless you clarify this, and we need child process to reuse the handle of `net.Listener`. Once a process calls exec functions, it is "dead", system replaces it with new code. The only thing it left is the process ID, which is the same number but it is a new program after executed.
9 14
10 Therefore, the first thing we need to do is that let child process fork main process and through `os.StartProcess` to append files that contains handle that is going to be inherited. 15 Therefore, the first thing we need to do is that let child process fork main process and through `os.StartProcess` to append files that contains handle that is going to be inherited.
...@@ -15,7 +20,8 @@ The final step is that we want to serve old connections with old version of appl ...@@ -15,7 +20,8 @@ The final step is that we want to serve old connections with old version of appl
15 20
16 Above are three problems that we need to solve, you can see my code logic for specific implementation. 21 Above are three problems that we need to solve, you can see my code logic for specific implementation.
17 22
18 ##Show time 23
24 ## Show time
19 25
20 1. Write code in your Get method: 26 1. Write code in your Get method:
21 27
...@@ -26,15 +32,15 @@ Above are three problems that we need to solve, you can see my code logic for sp ...@@ -26,15 +32,15 @@ Above are three problems that we need to solve, you can see my code logic for sp
26 } 32 }
27 33
28 2. Open two terminals: 34 2. Open two terminals:
29 35
30 One execute: ` ps -ef|grep <application name>` 36 One execute: ` ps -ef|grep <application name>`
31 37
32 Another one execute:`curl "http://127.0.0.1:8080/?sleep=20"` 38 Another one execute: `curl "http://127.0.0.1:8080/?sleep=20"`
33 39
34 3. Hot update 40 3. Hot update
35 41
36 `kill -HUP <PID>` 42 `kill -HUP <PID>`
37
38 4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"`
39 43
40 As you will see, the first request will wait for 20 seconds, but it's served by old process; after hot update, the first request will print old process ID, but the second request will print new process ID.
...\ No newline at end of file ...\ No newline at end of file
44 4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"`
45
46 As you will see, the first request will wait for 20 seconds, but it's served by old process; after hot update, the first request will print old process ID, but the second request will print new process ID.
......
1 #Installation 1 # Installation
2
2 Beego is a simple web framework, but it uses many third-party packages, so you have to install all dependency packages also. 3 Beego is a simple web framework, but it uses many third-party packages, so you have to install all dependency packages also.
3 4
4 - Before anything you do, you have to check that you installed Go in your computer, see more detail about Go installation in my book: [Chapter 1](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/01.1.md) 5 - Before anything you do, you have to check that you installed Go in your computer, see more detail about Go installation in my book: [Chapter 1](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/01.1.md)
5 - Use `go get ` to install Beego: 6 - Use `go get ` to install Beego:
6 7
7 go get github.com/astaxie/beego 8 go get github.com/astaxie/beego
8
9 - Install bee tools for fast-develop Beego applications:
10 9
11 go get github.com/astaxie/bee 10 - Install bee tools for fast-develop Beego applications:
11
12 go get github.com/astaxie/bee
12 13
13 Good job, you're ready to Beego with powerful bee tools! 14 Good job, you're ready to Beego with powerful bee tools!
14 15
15 ![](images/bee.png) 16 ![](images/bee.png)
16 17
...@@ -22,4 +23,4 @@ Beego has following dependency packages: ...@@ -22,4 +23,4 @@ Beego has following dependency packages:
22 - To support markdown as template function: [github.com/russross/blackfriday](https://github.com/russross/blackfriday) 23 - To support markdown as template function: [github.com/russross/blackfriday](https://github.com/russross/blackfriday)
23 24
24 - [Introduction](README.md) 25 - [Introduction](README.md)
25 - [Quick start](Quickstart.md)
...\ No newline at end of file ...\ No newline at end of file
26 - [Quick start](Quickstart.md)
......
1 # Quick start 1 # Quick start
2
2 Hey, you say you've never heard about Beego and don't know how to use it? Don't worry, after you read this section, you will know a lot about Beego. Before you start reading, make sure you installed Beego in your computer, if not, check this tutorial: [Installation](Install.md) 3 Hey, you say you've never heard about Beego and don't know how to use it? Don't worry, after you read this section, you will know a lot about Beego. Before you start reading, make sure you installed Beego in your computer, if not, check this tutorial: [Installation](Install.md)
3 4
4 **Navigation** 5 **Navigation**
...@@ -23,11 +24,13 @@ Hey, you say you've never heard about Beego and don't know how to use it? Don't ...@@ -23,11 +24,13 @@ Hey, you say you've never heard about Beego and don't know how to use it? Don't
23 - [Integrated third-party applications](#integrated-third-party-applications) 24 - [Integrated third-party applications](#integrated-third-party-applications)
24 - [Deployment](#deployment) 25 - [Deployment](#deployment)
25 26
27
26 ## Hello world 28 ## Hello world
29
27 This is an example of "Hello world" in Beego: 30 This is an example of "Hello world" in Beego:
28 31
29 package main 32 package main
30 33
31 import ( 34 import (
32 "github.com/astaxie/beego" 35 "github.com/astaxie/beego"
33 ) 36 )
...@@ -54,18 +57,25 @@ Open address [http://127.0.0.1:8080](http://127.0.0.1:8080) in your browser and ...@@ -54,18 +57,25 @@ Open address [http://127.0.0.1:8080](http://127.0.0.1:8080) in your browser and
54 57
55 What happened in behind above example? 58 What happened in behind above example?
56 59
57 1. We import package `github.com/astaxie/beego`. As we know that Go initialize packages and runs init() function in every package(more detail [here](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/02.3.md#main-function-and-init-function)), so Beego initializes the BeeApp application at this time. 60 1. We import package `github.com/astaxie/beego`. As we know that Go initialize packages and runs init() function in every package ([more details](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/02.3.md#main-function-and-init-function)), so Beego initializes the BeeApp application at this time.
61
58 2. Define controller. We define a struct called `MainController` with a anonymous field `beego.Controller`, so the `MainController` has all methods that `beego.Controller` has. 62 2. Define controller. We define a struct called `MainController` with a anonymous field `beego.Controller`, so the `MainController` has all methods that `beego.Controller` has.
63
59 3. Define RESTful methods. Once we use anonymous combination, `MainController` has already had `Get`, `Post`, `Delete`, `Put` and other methods, these methods will be called when user sends corresponding request, like `Post` method for requests that are using POST method. Therefore, after we overloaded `Get` method in `MainController`, all GET requests will use `Get` method in `MainController` instead of in `beego.Controller`. 64 3. Define RESTful methods. Once we use anonymous combination, `MainController` has already had `Get`, `Post`, `Delete`, `Put` and other methods, these methods will be called when user sends corresponding request, like `Post` method for requests that are using POST method. Therefore, after we overloaded `Get` method in `MainController`, all GET requests will use `Get` method in `MainController` instead of in `beego.Controller`.
65
60 4. Define main function. All applications in Go use main function as entry point as C does. 66 4. Define main function. All applications in Go use main function as entry point as C does.
67
61 5. Register routers, it tells Beego which controller is responsibility for specific requests. Here we register `/` for `MainController`, so all requests in `/` will be handed to `MainController`. Be aware that the first argument is the path and the second one is pointer of controller that you want to register. 68 5. Register routers, it tells Beego which controller is responsibility for specific requests. Here we register `/` for `MainController`, so all requests in `/` will be handed to `MainController`. Be aware that the first argument is the path and the second one is pointer of controller that you want to register.
69
62 6. Run application in port 8080 as default, press `Ctrl+c` to exit. 70 6. Run application in port 8080 as default, press `Ctrl+c` to exit.
63 71
72
64 ## New project 73 ## New project
74
65 Get into your $GOPATH, then use following command to setup Beego project: 75 Get into your $GOPATH, then use following command to setup Beego project:
66 76
67 bee create hello 77 bee create hello
68 78
69 It generates folders and files for your project, directory structure as follows: 79 It generates folders and files for your project, directory structure as follows:
70 80
71 . 81 .
...@@ -82,7 +92,9 @@ It generates folders and files for your project, directory structure as follows: ...@@ -82,7 +92,9 @@ It generates folders and files for your project, directory structure as follows:
82 └── views 92 └── views
83 └── index.tpl 93 └── index.tpl
84 94
95
85 ## Development mode 96 ## Development mode
97
86 Beego uses development mode as default, you can use following code to change mode in your application: 98 Beego uses development mode as default, you can use following code to change mode in your application:
87 99
88 beego.RunMode = "pro" 100 beego.RunMode = "pro"
...@@ -95,7 +107,7 @@ No differences between two ways. ...@@ -95,7 +107,7 @@ No differences between two ways.
95 107
96 In development mode, you have following effects: 108 In development mode, you have following effects:
97 109
98 - If you don't have directory `views`, it prints following error prompt: 110 - If you don't have directory `views`, it prints following error prompt:
99 111
100 2013/04/13 19:36:17 [W] [stat views: no such file or directory] 112 2013/04/13 19:36:17 [W] [stat views: no such file or directory]
101 113
...@@ -104,7 +116,9 @@ In development mode, you have following effects: ...@@ -104,7 +116,9 @@ In development mode, you have following effects:
104 116
105 ![](images/dev.png) 117 ![](images/dev.png)
106 118
119
107 ## Router 120 ## Router
121
108 The main function of router is to connect request URL and handler. Beego wrapped `Controller`, so it connects request URL and `ControllerInterface`. The `ControllerInterface` has following methods: 122 The main function of router is to connect request URL and handler. Beego wrapped `Controller`, so it connects request URL and `ControllerInterface`. The `ControllerInterface` has following methods:
109 123
110 type ControllerInterface interface { 124 type ControllerInterface interface {
...@@ -132,39 +146,41 @@ Users can use following ways to register route rules: ...@@ -132,39 +146,41 @@ Users can use following ways to register route rules:
132 146
133 For more convenient configure route rules, Beego references the idea from sinatra, so it supports more kinds of route rules as follows: 147 For more convenient configure route rules, Beego references the idea from sinatra, so it supports more kinds of route rules as follows:
134 148
135 - beego.Router("/api/:id([0-9]+)", &controllers.RController{}) 149 - beego.Router("/api/:id([0-9]+)", &controllers.RController{})
136 150
137 Customized regular expression match // match /api/123 :id= 123 151 Customized regular expression match // match /api/123 :id= 123
152
153 - beego.Router("/news/:all", &controllers.RController{})
138 154
139 - beego.Router("/news/:all", &controllers.RController{})
140
141 Match rest of all // match /news/path/to/123.html :all= path/to/123.html 155 Match rest of all // match /news/path/to/123.html :all= path/to/123.html
142 156
143 - beego.Router("/user/:username([\w]+)", &controllers.RController{}) 157 - beego.Router("/user/:username([\w]+)", &controllers.RController{})
144 158
145 Regular expression // match /user/astaxie :username = astaxie 159 Regular expression // match /user/astaxie :username = astaxie
146 160
147 - beego.Router("/download/`*`.`*`", &controllers.RController{}) 161 - beego.Router("/download/`*`.`*`", &controllers.RController{})
148 162
149 Wildcard character // match /download/file/api.xml :path= file/api :ext=xml 163 Wildcard character // match /download/file/api.xml :path= file/api :ext=xml
150 164
151 - beego.Router("/download/ceshi/`*`", &controllers.RController{}) 165 - beego.Router("/download/ceshi/`*`", &controllers.RController{})
152 166
153 wildcard character match rest of all // match /download/ceshi/file/api.json :splat=file/api.json 167 wildcard character match rest of all // match /download/ceshi/file/api.json :splat=file/api.json
154 168
155 - beego.Router("/:id:int", &controllers.RController{}) 169 - beego.Router("/:id:int", &controllers.RController{})
156 170
157 Match type int // match :id is int type, Beego uses regular expression ([0-9]+) automatically 171 Match type int // match :id is int type, Beego uses regular expression ([0-9]+) automatically
158 172
159 - beego.Router("/:hi:string", &controllers.RController{}) 173 - beego.Router("/:hi:string", &controllers.RController{})
160 174
161 Match type string // match :hi is string type, Beego uses regular expression ([\w]+) automatically 175 Match type string // match :hi is string type, Beego uses regular expression ([\w]+) automatically
162 176
163 ##Static files 177
178 ## Static files
179
164 Go provides `http.ServeFile` for static files, Beego wrapped this function and use following way to register static file folder: 180 Go provides `http.ServeFile` for static files, Beego wrapped this function and use following way to register static file folder:
165 181
166 beego.SetStaticPath("/static","public") 182 beego.SetStaticPath("/static","public")
167 183
168 - The first argument is the path of your URL. 184 - The first argument is the path of your URL.
169 - The second argument is the directory in your application path. 185 - The second argument is the directory in your application path.
170 186
...@@ -176,37 +192,41 @@ Beego supports multiple static file directories as follows: ...@@ -176,37 +192,41 @@ Beego supports multiple static file directories as follows:
176 192
177 After you setting static directory, when users visit `/images/login/login.png`,Beego accesses `images/login/login.png` in related to your application directory. One more example, if users visit `/static/img/logo.png`, Beego accesses file `public/img/logo.png`. 193 After you setting static directory, when users visit `/images/login/login.png`,Beego accesses `images/login/login.png` in related to your application directory. One more example, if users visit `/static/img/logo.png`, Beego accesses file `public/img/logo.png`.
178 194
179 ##Filter and middleware 195
196 ## Filter and middleware
197
180 Beego supports customized filter and middleware, such as security verification, force redirect, etc. 198 Beego supports customized filter and middleware, such as security verification, force redirect, etc.
181 199
182 Here is an example of verify user name of all requests, check if it's admin. 200 Here is an example of verify user name of all requests, check if it's admin.
183 201
184 var FilterUser = func(w http.ResponseWriter, r *http.Request) { 202 var FilterUser = func(w http.ResponseWriter, r *http.Request) {
185 if r.URL.User == nil || r.URL.User.Username() != "admin" { 203 if r.URL.User == nil || r.URL.User.Username() != "admin" {
186 http.Error(w, "", http.StatusUnauthorized) 204 http.Error(w, "", http.StatusUnauthorized)
187 } 205 }
188 } 206 }
189
190 beego.Filter(FilterUser)
191 207
208 beego.Filter(FilterUser)
209
192 You can also filter by arguments: 210 You can also filter by arguments:
193 211
194 beego.Router("/:id([0-9]+)", &admin.EditController{}) 212 beego.Router("/:id([0-9]+)", &admin.EditController{})
195 beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) { 213 beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) {
196 dosomething() 214 dosomething()
197 }) 215 })
198 216
199 Filter by prefix is also available: 217 Filter by prefix is also available:
200 218
201 beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) { 219 beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) {
202 dosomething() 220 dosomething()
203 }) 221 })
204 222
205 ##Controller 223
224 ## Controller
225
206 Use `beego.controller` as anonymous in your controller struct to implement the interface in Beego: 226 Use `beego.controller` as anonymous in your controller struct to implement the interface in Beego:
207 227
208 type xxxController struct { 228 type xxxController struct {
209 beego.Controller 229 beego.Controller
210 } 230 }
211 231
212 `beego.Controller` implemented`beego.ControllerInterface`, `beego.ControllerInterface` defined following methods: 232 `beego.Controller` implemented`beego.ControllerInterface`, `beego.ControllerInterface` defined following methods:
...@@ -214,15 +234,15 @@ Use `beego.controller` as anonymous in your controller struct to implement the i ...@@ -214,15 +234,15 @@ Use `beego.controller` as anonymous in your controller struct to implement the i
214 - Init(ct `*`Context, cn string) 234 - Init(ct `*`Context, cn string)
215 235
216 Initialize context, controller's name, template's name, and container of template arguments 236 Initialize context, controller's name, template's name, and container of template arguments
217 237
218 - Prepare() 238 - Prepare()
219 239
220 This is for expend usages, it executes before all the following methods. Users can overload this method for verification for example. 240 This is for expend usages, it executes before all the following methods. Users can overload this method for verification for example.
221 241
222 - Get() 242 - Get()
223 243
224 This method executes when client sends request as GET method, 403 as default status code. Users overload this method for customized handle process of GET method. 244 This method executes when client sends request as GET method, 403 as default status code. Users overload this method for customized handle process of GET method.
225 245
226 - Post() 246 - Post()
227 247
228 This method executes when client sends request as POST method, 403 as default status code. Users overload this method for customized handle process of POST method. 248 This method executes when client sends request as POST method, 403 as default status code. Users overload this method for customized handle process of POST method.
...@@ -258,7 +278,7 @@ Use `beego.controller` as anonymous in your controller struct to implement the i ...@@ -258,7 +278,7 @@ Use `beego.controller` as anonymous in your controller struct to implement the i
258 Overload all methods for all customized logic processes, let's see an example: 278 Overload all methods for all customized logic processes, let's see an example:
259 279
260 type AddController struct { 280 type AddController struct {
261 beego.Controller 281 beego.Controller
262 } 282 }
263 283
264 func (this *AddController) Prepare() { 284 func (this *AddController) Prepare() {
...@@ -266,54 +286,64 @@ Overload all methods for all customized logic processes, let's see an example: ...@@ -266,54 +286,64 @@ Overload all methods for all customized logic processes, let's see an example:
266 } 286 }
267 287
268 func (this *AddController) Get() { 288 func (this *AddController) Get() {
269 this.Data["content"] ="value" 289 this.Data["content"] = "value"
270 this.Layout = "admin/layout.html" 290 this.Layout = "admin/layout.html"
271 this.TplNames = "admin/add.tpl" 291 this.TplNames = "admin/add.tpl"
272 } 292 }
273 293
274 func (this *AddController) Post() { 294 func (this *AddController) Post() {
275 pkgname := this.GetString("pkgname") 295 pkgname := this.GetString("pkgname")
276 content := this.GetString("content") 296 content := this.GetString("content")
277 pk := models.GetCruPkg(pkgname) 297 pk := models.GetCruPkg(pkgname)
278 if pk.Id == 0 { 298 if pk.Id == 0 {
279 var pp models.PkgEntity 299 var pp models.PkgEntity
280 pp.Pid = 0 300 pp.Pid = 0
281 pp.Pathname = pkgname 301 pp.Pathname = pkgname
282 pp.Intro = pkgname 302 pp.Intro = pkgname
283 models.InsertPkg(pp) 303 models.InsertPkg(pp)
284 pk = models.GetCruPkg(pkgname) 304 pk = models.GetCruPkg(pkgname)
285 } 305 }
286 var at models.Article 306 var at models.Article
287 at.Pkgid = pk.Id 307 at.Pkgid = pk.Id
288 at.Content = content 308 at.Content = content
289 models.InsertArticle(at) 309 models.InsertArticle(at)
290 this.Ctx.Redirect(302, "/admin/index") 310 this.Ctx.Redirect(302, "/admin/index")
291 } 311 }
312
313
314 ## Template
315
316
317 ### Template directory
292 318
293 ##Template
294 ###Template directory
295 Beego uses `views` as the default directory for template files, parses and caches them as needed(cache is not enable in develop mode), but you can **change**(because only one directory can be used for template files) its directory using following code: 319 Beego uses `views` as the default directory for template files, parses and caches them as needed(cache is not enable in develop mode), but you can **change**(because only one directory can be used for template files) its directory using following code:
296 320
297 beego.ViewsPath = "/myviewpath" 321 beego.ViewsPath = "/myviewpath"
298 322
299 ###Auto-render 323
324 ### Auto-render
325
300 You don't need to call render function manually, Beego calls it automatically after corresponding methods executed. If your application is somehow doesn't need templates, you can disable this feature either in code of `main.go` or configuration file. 326 You don't need to call render function manually, Beego calls it automatically after corresponding methods executed. If your application is somehow doesn't need templates, you can disable this feature either in code of `main.go` or configuration file.
301 327
302 To disable auto-render in configuration file: 328 To disable auto-render in configuration file:
303 329
304 autorender = false 330 autorender = false
305 331
306 To disable auto-render in `main.go`(before you call `beego.Run()` to run the application): 332 To disable auto-render in `main.go`(before you call `beego.Run()` to run the application):
307 333
308 beego.AutoRender = false 334 beego.AutoRender = false
309 335
310 ###Template data 336
337 ### Template data
338
311 You can use `this.Data` in controller methods to access the data in templates. Suppose you want to get content of `{{.Content}}`, you can use following code to do this: 339 You can use `this.Data` in controller methods to access the data in templates. Suppose you want to get content of `{{.Content}}`, you can use following code to do this:
312 340
313 this.Data["Context"] = "value" 341 this.Data["Context"] = "value"
314 342
315 ###Template name 343
316 Beego uses built-in template engine of Go, so there is no different in syntax. As for how to write template file, please visit [Template tutorial](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/07.4.md) 344 ### Template name
345
346 Beego uses built-in template engine of Go, so there is no different in syntax. As for how to write template file, please visit [Template tutorial](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/07.4.md).
317 347
318 Beego parses template files in `viewpath` and render it after you set the name of the template file in controller methods. For example, Beego finds the file `add.tpl` in directory `admin` in following code: 348 Beego parses template files in `viewpath` and render it after you set the name of the template file in controller methods. For example, Beego finds the file `add.tpl` in directory `admin` in following code:
319 349
...@@ -329,16 +359,18 @@ If you enabled auto-render and you don't tell Beego which template file you are ...@@ -329,16 +359,18 @@ If you enabled auto-render and you don't tell Beego which template file you are
329 359
330 Which is `<corresponding controller name>/<request method name>.<template extension>`. For example, your controller name is `AddController` and the request method is POST, and the default file extension is `tpl`, so Beego will try to find file `/<viewpath>/AddController/POST.tpl`. 360 Which is `<corresponding controller name>/<request method name>.<template extension>`. For example, your controller name is `AddController` and the request method is POST, and the default file extension is `tpl`, so Beego will try to find file `/<viewpath>/AddController/POST.tpl`.
331 361
332 ###Layout design 362
363 ### Layout design
364
333 Beego supports layout design, which means if you are working on an administration application, and some part of its user interface is exactly same all the time, then you can make this part as a layout. 365 Beego supports layout design, which means if you are working on an administration application, and some part of its user interface is exactly same all the time, then you can make this part as a layout.
334 366
335 this.Layout = "admin/layout.html" 367 this.Layout = "admin/layout.html"
336 this.TplNames = "admin/add.tpl" 368 this.TplNames = "admin/add.tpl"
337 369
338 You have to set following variable in order to make Beego possible to insert your dynamic content: 370 You have to set following variable in order to make Beego possible to insert your dynamic content:
339 371
340 {{.LayoutContent}} 372 {{.LayoutContent}}
341 373
342 Beego parses template file and assign content to `LayoutContent`, and render them together. 374 Beego parses template file and assign content to `LayoutContent`, and render them together.
343 375
344 Right now, Beego caches all template files, so you can use following way to implement another kind of layout: 376 Right now, Beego caches all template files, so you can use following way to implement another kind of layout:
...@@ -347,12 +379,14 @@ Right now, Beego caches all template files, so you can use following way to impl ...@@ -347,12 +379,14 @@ Right now, Beego caches all template files, so you can use following way to impl
347 Handle logic 379 Handle logic
348 {{template "footer.html"}} 380 {{template "footer.html"}}
349 381
350 ###Template function 382
383 ### Template function
384
351 Beego supports customized template functions that are registered before you call `beego.Run()`. 385 Beego supports customized template functions that are registered before you call `beego.Run()`.
352 386
353 func hello(in string)(out string){ 387 func hello(in string)(out string){
354 out = in + "world" 388 out = in + "world"
355 return 389 return
356 } 390 }
357 391
358 beego.AddFuncMap("hi",hello) 392 beego.AddFuncMap("hi",hello)
...@@ -363,35 +397,45 @@ Then you can use this function in your template files: ...@@ -363,35 +397,45 @@ Then you can use this function in your template files:
363 397
364 There are some built-in template functions: 398 There are some built-in template functions:
365 399
366 * markdown 400 * markdown
367 401
368 This function converts markdown content to HTML format, use {{markdown .Content}} in template files. 402 This function converts markdown content to HTML format, use {{markdown .Content}} in template files.
369 * dateformat 403
404 * dateformat
370 405
371 This function converts time to formatted string, use {{dateformat .Time "2006-01-02T15:04:05Z07:00"}} in template files. 406 This function converts time to formatted string, use {{dateformat .Time "2006-01-02T15:04:05Z07:00"}} in template files.
372 * date 407
408 * date
373 409
374 This function implements date function like in PHP, use formatted string to get corresponding time, use {{date .T "Y-m-d H:i:s"}} in template files. 410 This function implements date function like in PHP, use formatted string to get corresponding time, use {{date .T "Y-m-d H:i:s"}} in template files.
375 * compare 411
412 * compare
376 413
377 This functions compares two objects, returns true if they are same, false otherwise, use {{compare .A .B}} in template files. 414 This functions compares two objects, returns true if they are same, false otherwise, use {{compare .A .B}} in template files.
378 * substr 415
416 * substr
379 417
380 This function cuts out string from another string by index, it supports UTF-8 characters, use {{substr .Str 0 30}} in template files. 418 This function cuts out string from another string by index, it supports UTF-8 characters, use {{substr .Str 0 30}} in template files.
381 * html2str 419
420 * html2str
382 421
383 This function escapes HTML to raw string, use {{html2str .Htmlinfo}} in template files. 422 This function escapes HTML to raw string, use {{html2str .Htmlinfo}} in template files.
384 * str2html 423
424 * str2html
385 425
386 This function outputs string in HTML format without escaping, use {{str2html .Strhtml}} in template files. 426 This function outputs string in HTML format without escaping, use {{str2html .Strhtml}} in template files.
387 * htmlquote 427
428 * htmlquote
388 429
389 This functions implements basic HTML escape, use {{htmlquote .quote}} in template files. 430 This functions implements basic HTML escape, use {{htmlquote .quote}} in template files.
390 * htmlunquote 431
432 * htmlunquote
391 433
392 This functions implements basic invert-escape of HTML, use {{htmlunquote .unquote}} in template files. 434 This functions implements basic invert-escape of HTML, use {{htmlunquote .unquote}} in template files.
393 435
394 ##Handle request 436
437 ## Handle request
438
395 We always need to get data from users, including methods like GET, POST, etc. Beego parses these data automatically, and you can access them by following code: 439 We always need to get data from users, including methods like GET, POST, etc. Beego parses these data automatically, and you can access them by following code:
396 440
397 - GetString(key string) string 441 - GetString(key string) string
...@@ -413,18 +457,20 @@ If you need other types that are not included above, like you need int64 instead ...@@ -413,18 +457,20 @@ If you need other types that are not included above, like you need int64 instead
413 func (this *MainController) Post() { 457 func (this *MainController) Post() {
414 id := this.Input().Get("id") 458 id := this.Input().Get("id")
415 intid, err := strconv.Atoi(id) 459 intid, err := strconv.Atoi(id)
416 } 460 }
417 461
418 To use `this.Ctx.Request` for more information about request, and object properties and method please read [Request](http://golang.org/pkg/net/http/#Request) 462 To use `this.Ctx.Request` for more information about request, and object properties and method please read [Request](http://golang.org/pkg/net/http/#Request)
419 463
420 ###File upload 464
465 ### File upload
466
421 It's very easy to upload file through Beego, but don't forget to add `enctype="multipart/form-data"` in your form, otherwise the browser will not upload anything. 467 It's very easy to upload file through Beego, but don't forget to add `enctype="multipart/form-data"` in your form, otherwise the browser will not upload anything.
422 468
423 Files will be saved in memory, if the size is greater than cache memory, the rest part will be saved as temporary file. The default cache memory is 64 MB, and you can using following ways to change this size. 469 Files will be saved in memory, if the size is greater than cache memory, the rest part will be saved as temporary file. The default cache memory is 64 MB, and you can use following ways to change this size.
424 470
425 In code: 471 In code:
426 472
427 beego.MaxMemory = 1<<22 473 beego.MaxMemory = 1<<22
428 474
429 In configuration file: 475 In configuration file:
430 476
...@@ -435,56 +481,60 @@ Beego provides two convenient functions to upload files: ...@@ -435,56 +481,60 @@ Beego provides two convenient functions to upload files:
435 - GetFile(key string) (multipart.File, `*`multipart.FileHeader, error) 481 - GetFile(key string) (multipart.File, `*`multipart.FileHeader, error)
436 482
437 This function is mainly used to read file name element `the_file` in form and returns corresponding information. You can use this information either filter or save files. 483 This function is mainly used to read file name element `the_file` in form and returns corresponding information. You can use this information either filter or save files.
438 484
439 - SaveToFile(fromfile, tofile string) error 485 - SaveToFile(fromfile, tofile string) error
440 486
441 This function a wrapper of GetFile and gives ability to save file. 487 This function a wrapper of GetFile and gives ability to save file.
442 488
443 This is an example to save file that is uploaded: 489 This is an example to save file that is uploaded:
444 490
445 func (this *MainController) Post() { 491 func (this *MainController) Post() {
446 this.SaveToFile("the_file","/var/www/uploads/uploaded_file.txt"") 492 this.SaveToFile("the_file","/var/www/uploads/uploaded_file.txt"")
447 } 493 }
448 494
449 ###Output Json and XML 495
496 ### Output Json and XML
497
450 Beego considered API function design at the beginning, and we often use Json or XML format data as output. Therefore, it's no reason that Beego doesn't support it: 498 Beego considered API function design at the beginning, and we often use Json or XML format data as output. Therefore, it's no reason that Beego doesn't support it:
451 499
452 Set `content-type` to `application/json` for output raw Json format data: 500 Set `content-type` to `application/json` for output raw Json format data:
453 501
454 func (this *AddController) Get() { 502 func (this *AddController) Get() {
455 mystruct := { ... } 503 mystruct := { ... }
456 this.Data["json"] = &mystruct 504 this.Data["json"] = &mystruct
457 this.ServeJson() 505 this.ServeJson()
458 } 506 }
459 507
460 Set `content-type` to `application/xml` for output raw XML format data: 508 Set `content-type` to `application/xml` for output raw XML format data:
461 509
462 func (this *AddController) Get() { 510 func (this *AddController) Get() {
463 mystruct := { ... } 511 mystruct := { ... }
464 this.Data["xml"]=&mystruct 512 this.Data["xml"]=&mystruct
465 this.ServeXml() 513 this.ServeXml()
466 } 514 }
467 515
468 ##Redirect and error 516
517 ## Redirect and error
518
469 You can use following to redirect: 519 You can use following to redirect:
470 520
471 func (this *AddController) Get() { 521 func (this *AddController) Get() {
472 this.Redirect("/", 302) 522 this.Redirect("/", 302)
473 } 523 }
474 524
475 You can also throw an exception in your controller as follows: 525 You can also throw an exception in your controller as follows:
476 526
477 func (this *MainController) Get() { 527 func (this *MainController) Get() {
478 this.Abort("401") 528 this.Abort("401")
479 v := this.GetSession("asta") 529 v := this.GetSession("asta")
480 if v == nil { 530 if v == nil {
481 this.SetSession("asta", int(1)) 531 this.SetSession("asta", int(1))
482 this.Data["Email"] = 0 532 this.Data["Email"] = 0
483 } else { 533 } else {
484 this.SetSession("asta", v.(int)+1) 534 this.SetSession("asta", v.(int)+1)
485 this.Data["Email"] = v.(int) 535 this.Data["Email"] = v.(int)
486 } 536 }
487 this.TplNames = "index.tpl" 537 this.TplNames = "index.tpl"
488 } 538 }
489 539
490 Then Beego will not execute rest code of the function body when you call `this.Abort("401")`, and gives following default page view to users: 540 Then Beego will not execute rest code of the function body when you call `this.Abort("401")`, and gives following default page view to users:
...@@ -493,56 +543,60 @@ Then Beego will not execute rest code of the function body when you call `this.A ...@@ -493,56 +543,60 @@ Then Beego will not execute rest code of the function body when you call `this.A
493 543
494 Beego supports following error code: 404, 401, 403, 500 and 503, you can customize your error handle, for example, use following code to replace 404 error handle process: 544 Beego supports following error code: 404, 401, 403, 500 and 503, you can customize your error handle, for example, use following code to replace 404 error handle process:
495 545
496 func page_not_found(rw http.ResponseWriter, r *http.Request){ 546 func page_not_found(rw http.ResponseWriter, r *http.Request) {
497 t,_:= template.New("beegoerrortemp").ParseFiles(beego.ViewsPath+"/404.html") 547 t, _ := template.New("beegoerrortemp").ParseFiles(beego.ViewsPath + "/404.html")
498 data :=make(map[string]interface{}) 548 data := make(map[string]interface{})
499 data["content"] = "page not found" 549 data["content"] = "page not found"
500 t.Execute(rw, data) 550 t.Execute(rw, data)
501 } 551 }
502 552
503 func main() { 553 func main() {
504 beego.Errorhandler("404",page_not_found) 554 beego.Errorhandler("404", page_not_found)
505 beego.Router("/", &controllers.MainController{}) 555 beego.Router("/", &controllers.MainController{})
506 beego.Run() 556 beego.Run()
507 } 557 }
508 558
509 You may be able to use your own `404.html` for your 404 error. 559 You may be able to use your own `404.html` for your 404 error.
510 560
511 Beego also gives you ability to modify error message that shows on the error page, the following example shows how to set more meaningful error message when database has problems: 561 Beego also gives you ability to modify error message that shows on the error page, the following example shows how to set more meaningful error message when database has problems:
512 562
513 func dbError(rw http.ResponseWriter, r *http.Request){ 563 func dbError(rw http.ResponseWriter, r *http.Request) {
514 t,_:= template.New("beegoerrortemp").ParseFiles(beego.ViewsPath+"/dberror.html") 564 t, _ := template.New("beegoerrortemp").ParseFiles(beego.ViewsPath + "/dberror.html")
515 data :=make(map[string]interface{}) 565 data := make(map[string]interface{})
516 data["content"] = "database is now down" 566 data["content"] = "database is now down"
517 t.Execute(rw, data) 567 t.Execute(rw, data)
518 } 568 }
519 569
520 func main() { 570 func main() {
521 beego.Errorhandler("dbError",dbError) 571 beego.Errorhandler("dbError", dbError)
522 beego.Router("/", &controllers.MainController{}) 572 beego.Router("/", &controllers.MainController{})
523 beego.Run() 573 beego.Run()
524 } 574 }
525 575
526 After you registered this customized error, you can use `this.Abort("dbError")` for any database error in your applications. 576 After you registered this customized error, you can use `this.Abort("dbError")` for any database error in your applications.
527 577
528 ##Handle response 578
579 ## Handle response
580
529 There are some situations that you may have in response: 581 There are some situations that you may have in response:
530 582
531 1. Output template 583 1. Output template
532 584
533 I've already talked about template above, Beego outputs template after corresponding method executed. 585 I've already talked about template above, Beego outputs template after corresponding method executed.
534 586
535 2. Redirect 587 2. Redirect
536 588
537 You can use this.Redirect("/", 302) to redirect page. 589 You can use this.Redirect("/", 302) to redirect page.
538 590
539 3. Output string 591 3. Output string
540 592
541 Sometimes we just need to print string on the screen: 593 Sometimes we just need to print string on the screen:
542 594
543 this.Ctx.WriteString("ok") 595 this.Ctx.WriteString("ok")
544 596
597
545 ## Sessions 598 ## Sessions
599
546 Beego has a built-in session module and supports four engines, including memory, file, MySQL and redis. You can implement your own engine based on the interface. 600 Beego has a built-in session module and supports four engines, including memory, file, MySQL and redis. You can implement your own engine based on the interface.
547 601
548 It's easy to use session in Beego, use following code in your main() function: 602 It's easy to use session in Beego, use following code in your main() function:
...@@ -594,21 +648,21 @@ There are some arguments you can use in session module: ...@@ -594,21 +648,21 @@ There are some arguments you can use in session module:
594 - SessionOn 648 - SessionOn
595 649
596 Whether enable session or not, default is false, corresponding arguments in configuration file: sessionon. 650 Whether enable session or not, default is false, corresponding arguments in configuration file: sessionon.
597 651
598 - SessionProvider 652 - SessionProvider
599 653
600 Setting session engine, default is memory, other options are file, MySQL and redis, corresponding arguments in configuration file: sessionprovider. 654 Setting session engine, default is memory, other options are file, MySQL and redis, corresponding arguments in configuration file: sessionprovider.
601 655
602 - SessionName 656 - SessionName
603 657
604 Setting name of cookies, it saves in users' browser with name beegosessionID, corresponding arguments in configuration file: sessionname. 658 Setting name of cookies, it saves in users' browser with name beegosessionID, corresponding arguments in configuration file: sessionname.
605 659
606 - SessionGCMaxLifetime 660 - SessionGCMaxLifetime
607 661
608 Setting session expired time, default is 3600 seconds, corresponding arguments in configuration: sessiongcmaxlifetime 662 Setting session expired time, default is 3600 seconds, corresponding arguments in configuration: sessiongcmaxlifetime
609 663
610 - SessionSavePath 664 - SessionSavePath
611 665
612 Setting save path or link address of corresponding file, MySQL and redis engines, default is empty, corresponding arguments in configuration file: sessionsavepath 666 Setting save path or link address of corresponding file, MySQL and redis engines, default is empty, corresponding arguments in configuration file: sessionsavepath
613 667
614 When the SessionProvider is file, SessionSavePath saves file path: 668 When the SessionProvider is file, SessionSavePath saves file path:
...@@ -620,13 +674,15 @@ When the SessionProvider is mysql, SessionSavePath is link address, it uses driv ...@@ -620,13 +674,15 @@ When the SessionProvider is mysql, SessionSavePath is link address, it uses driv
620 674
621 beego.SessionProvider = "mysql" 675 beego.SessionProvider = "mysql"
622 beego.SessionSavePath = "username:password@protocol(address)/dbname?param=value" 676 beego.SessionSavePath = "username:password@protocol(address)/dbname?param=value"
623 677
624 When the SessionProvider is redis, SessionSavePath is link address of redis, it uses driver [redigo](https://github.com/garyburd/redigo): 678 When the SessionProvider is redis, SessionSavePath is link address of redis, it uses driver [redigo](https://github.com/garyburd/redigo):
625 679
626 beego.SessionProvider = "redis" 680 beego.SessionProvider = "redis"
627 beego.SessionSavePath = "127.0.0.1:6379" 681 beego.SessionSavePath = "127.0.0.1:6379"
682
628 683
629 ## Cache 684 ## Cache
685
630 Beego has a built-in cache module, it's like memcache, which caches data in memory. Here is an example of using cache module in Beego: 686 Beego has a built-in cache module, it's like memcache, which caches data in memory. Here is an example of using cache module in Beego:
631 687
632 var ( 688 var (
...@@ -638,7 +694,7 @@ Beego has a built-in cache module, it's like memcache, which caches data in memo ...@@ -638,7 +694,7 @@ Beego has a built-in cache module, it's like memcache, which caches data in memo
638 urllist.Every = 0 // Not expired 694 urllist.Every = 0 // Not expired
639 urllist.Start() 695 urllist.Start()
640 } 696 }
641 697
642 func (this *ShortController) Post() { 698 func (this *ShortController) Post() {
643 var result ShortResult 699 var result ShortResult
644 longurl := this.Input().Get("longurl") 700 longurl := this.Input().Get("longurl")
...@@ -661,8 +717,8 @@ Beego has a built-in cache module, it's like memcache, which caches data in memo ...@@ -661,8 +717,8 @@ Beego has a built-in cache module, it's like memcache, which caches data in memo
661 } 717 }
662 this.Data["json"] = result 718 this.Data["json"] = result
663 this.ServeJson() 719 this.ServeJson()
664 } 720 }
665 721
666 To use cache, you need to initialize a `beego.NewBeeCache` object and set expired time, and enable expired check. Then you can use following methods to achieve other operations: 722 To use cache, you need to initialize a `beego.NewBeeCache` object and set expired time, and enable expired check. Then you can use following methods to achieve other operations:
667 723
668 - Get(name string) interface{} 724 - Get(name string) interface{}
...@@ -670,7 +726,9 @@ To use cache, you need to initialize a `beego.NewBeeCache` object and set expire ...@@ -670,7 +726,9 @@ To use cache, you need to initialize a `beego.NewBeeCache` object and set expire
670 - Delete(name string) (ok bool, err error) 726 - Delete(name string) (ok bool, err error)
671 - IsExist(name string) bool 727 - IsExist(name string) bool
672 728
673 ##Safe map 729
730 ## Safe map
731
674 We know that map is not thread safe in Go, if you don't know it, this article may be helpful for you: [atomic_maps](http://golang.org/doc/faq#atomic_maps). However, we need a kind of thread safe map in practice, especially when we are using goroutines. Therefore, Beego provides a simple built-in thread safe map implementation. 732 We know that map is not thread safe in Go, if you don't know it, this article may be helpful for you: [atomic_maps](http://golang.org/doc/faq#atomic_maps). However, we need a kind of thread safe map in practice, especially when we are using goroutines. Therefore, Beego provides a simple built-in thread safe map implementation.
675 733
676 bm := NewBeeMap() 734 bm := NewBeeMap()
...@@ -680,16 +738,16 @@ We know that map is not thread safe in Go, if you don't know it, this article ma ...@@ -680,16 +738,16 @@ We know that map is not thread safe in Go, if you don't know it, this article ma
680 if !bm.Check("astaxie") { 738 if !bm.Check("astaxie") {
681 t.Error("check err") 739 t.Error("check err")
682 } 740 }
683 741
684 if v := bm.Get("astaxie"); v.(int) != 1 { 742 if v := bm.Get("astaxie"); v.(int) != 1 {
685 t.Error("get err") 743 t.Error("get err")
686 } 744 }
687 745
688 bm.Delete("astaxie") 746 bm.Delete("astaxie")
689 if bm.Check("astaxie") { 747 if bm.Check("astaxie") {
690 t.Error("delete err") 748 t.Error("delete err")
691 } 749 }
692 750
693 This map has following interfaces: 751 This map has following interfaces:
694 752
695 - Get(k interface{}) interface{} 753 - Get(k interface{}) interface{}
...@@ -697,7 +755,9 @@ This map has following interfaces: ...@@ -697,7 +755,9 @@ This map has following interfaces:
697 - Check(k interface{}) bool 755 - Check(k interface{}) bool
698 - Delete(k interface{}) 756 - Delete(k interface{})
699 757
700 ##Log 758
759 ## Log
760
701 Beego has a default BeeLogger object that outputs log into stdout, and you can use your own logger as well: 761 Beego has a default BeeLogger object that outputs log into stdout, and you can use your own logger as well:
702 762
703 beego.SetLogger(*log.Logger) 763 beego.SetLogger(*log.Logger)
...@@ -706,13 +766,14 @@ You can output everything that implemented `*log.Logger`, for example, write to ...@@ -706,13 +766,14 @@ You can output everything that implemented `*log.Logger`, for example, write to
706 766
707 fd,err := os.OpenFile("/var/log/beeapp/beeapp.log", os.O_RDWR|os.O_APPEND, 0644) 767 fd,err := os.OpenFile("/var/log/beeapp/beeapp.log", os.O_RDWR|os.O_APPEND, 0644)
708 if err != nil { 768 if err != nil {
709 beego.Critical("openfile beeapp.log:", err) 769 beego.Critical("openfile beeapp.log:", err)
710 return 770 return
711 } 771 }
712 lg := log.New(fd, "", log.Ldate|log.Ltime) 772 lg := log.New(fd, "", log.Ldate|log.Ltime)
713 beego.SetLogger(lg) 773 beego.SetLogger(lg)
714 774
715 ###Different levels of log 775
776 ### Different levels of log
716 777
717 * Trace(v ...interface{}) 778 * Trace(v ...interface{})
718 * Debug(v ...interface{}) 779 * Debug(v ...interface{})
...@@ -724,43 +785,55 @@ You can output everything that implemented `*log.Logger`, for example, write to ...@@ -724,43 +785,55 @@ You can output everything that implemented `*log.Logger`, for example, write to
724 You can use following code to set log level: 785 You can use following code to set log level:
725 786
726 beego.SetLevel(beego.LevelError) 787 beego.SetLevel(beego.LevelError)
727 788
728 Your project may have a lot of log outputs, but you don't want to output everything after your application is running on the internet, for example, you want to ignore Trace, Debug and Info level log outputs, you can use following setting: 789 Your project may have a lot of log outputs, but you don't want to output everything after your application is running on the internet, for example, you want to ignore Trace, Debug and Info level log outputs, you can use following setting:
729 790
730 beego.SetLevel(beego.LevelWarning) 791 beego.SetLevel(beego.LevelWarning)
731 792
732 Then Beego will not output log that has lower level of LevelWarning. Here is the list of all log levels, order from lower to higher: 793 Then Beego will not output log that has lower level of LevelWarning. Here is the list of all log levels, order from lower to higher:
733 794
734 LevelTrace、LevelDebug、LevelInfo、LevelWarning、 LevelError、LevelCritical 795 LevelTrace, LevelDebug, LevelInfo, LevelWarning, LevelError, LevelCritical
735 796
736 You can use different log level to output different error messages, it's based on how critical the error you think it is: 797 You can use different log level to output different error messages, it's based on how critical the error you think it is:
737 798
799
738 ### Examples of log messages 800 ### Examples of log messages
801
739 - Trace 802 - Trace
740 803
741 * "Entered parse function validation block" 804 * "Entered parse function validation block"
742 * "Validation: entered second 'if'" 805 * "Validation: entered second 'if'"
743 * "Dictionary 'Dict' is empty. Using default value" 806 * "Dictionary 'Dict' is empty. Using default value"
807
744 - Debug 808 - Debug
745 809
746 * "Web page requested: http://somesite.com Params='...'" 810 * "Web page requested: http://somesite.com Params='...'"
747 * "Response generated. Response size: 10000. Sending." 811 * "Response generated. Response size: 10000. Sending."
748 * "New file received. Type:PNG Size:20000" 812 * "New file received. Type:PNG Size:20000"
813
749 - Info 814 - Info
815
750 * "Web server restarted" 816 * "Web server restarted"
751 * "Hourly statistics: Requested pages: 12345 Errors: 123 ..." 817 * "Hourly statistics: Requested pages: 12345 Errors: 123 ..."
752 * "Service paused. Waiting for 'resume' call" 818 * "Service paused. Waiting for 'resume' call"
819
753 - Warn 820 - Warn
821
754 * "Cache corrupted for file='test.file'. Reading from back-end" 822 * "Cache corrupted for file='test.file'. Reading from back-end"
755 * "Database 192.168.0.7/DB not responding. Using backup 192.168.0.8/DB" 823 * "Database 192.168.0.7/DB not responding. Using backup 192.168.0.8/DB"
756 * "No response from statistics server. Statistics not sent" 824 * "No response from statistics server. Statistics not sent"
825
757 - Error 826 - Error
827
758 * "Internal error. Cannot process request #12345 Error:...." 828 * "Internal error. Cannot process request #12345 Error:...."
759 * "Cannot perform login: credentials DB not responding" 829 * "Cannot perform login: credentials DB not responding"
830
760 - Critical 831 - Critical
832
761 * "Critical panic received: .... Shutting down" 833 * "Critical panic received: .... Shutting down"
762 * "Fatal error: ... App is shutting down to prevent data corruption or loss" 834 * "Fatal error: ... App is shutting down to prevent data corruption or loss"
763 835
836
764 ### Example 837 ### Example
765 838
766 func internalCalculationFunc(x, y int) (result int, err error) { 839 func internalCalculationFunc(x, y int) (result int, err error) {
...@@ -782,26 +855,26 @@ You can use different log level to output different error messages, it's based o ...@@ -782,26 +855,26 @@ You can use different log level to output different error messages, it's based o
782 } 855 }
783 retVal := z-3 856 retVal := z-3
784 beego.Debug("Returning ", retVal) 857 beego.Debug("Returning ", retVal)
785 858
786 return retVal, nil 859 return retVal, nil
787 } 860 }
788 861
789 func processInput(input inputData) { 862 func processInput(input inputData) {
790 defer func() { 863 defer func() {
791 if r := recover(); r != nil { 864 if r := recover(); r != nil {
792 beego.Error("Unexpected error occurred: ", r) 865 beego.Error("Unexpected error occurred: ", r)
793 outputs <- outputData{result : 0, error : true} 866 outputs <- outputData{result : 0, error : true}
794 } 867 }
795 }() 868 }()
796 beego.Info("Received input signal. x:",input.x," y:", input.y) 869 beego.Info("Received input signal. x:",input.x," y:", input.y)
797 870
798 res, err := internalCalculationFunc(input.x, input.y) 871 res, err := internalCalculationFunc(input.x, input.y)
799 if err != nil { 872 if err != nil {
800 beego.Warn("Error in calculation:", err.Error()) 873 beego.Warn("Error in calculation:", err.Error())
801 } 874 }
802 875
803 beego.Info("Returning result: ",res," error: ",err) 876 beego.Info("Returning result: ",res," error: ",err)
804 outputs <- outputData{result : res, error : err != nil} 877 outputs <- outputData{result : res, error : err != nil}
805 } 878 }
806 879
807 func main() { 880 func main() {
...@@ -827,7 +900,9 @@ You can use different log level to output different error messages, it's based o ...@@ -827,7 +900,9 @@ You can use different log level to output different error messages, it's based o
827 } 900 }
828 } 901 }
829 902
830 ##Configuration 903
904 ## Configuration
905
831 Beego supports to parse .ini file in path `conf/app.conf`, and you have following options: 906 Beego supports to parse .ini file in path `conf/app.conf`, and you have following options:
832 907
833 appname = beepkg 908 appname = beepkg
...@@ -837,7 +912,7 @@ Beego supports to parse .ini file in path `conf/app.conf`, and you have followin ...@@ -837,7 +912,7 @@ Beego supports to parse .ini file in path `conf/app.conf`, and you have followin
837 autorender = false 912 autorender = false
838 autorecover = false 913 autorecover = false
839 viewspath = "myview" 914 viewspath = "myview"
840 915
841 If you set value in configuration file, Beego uses it to replace default value. 916 If you set value in configuration file, Beego uses it to replace default value.
842 917
843 You can also have other values for your application, for example, database connection information: 918 You can also have other values for your application, for example, database connection information:
...@@ -846,7 +921,7 @@ You can also have other values for your application, for example, database conne ...@@ -846,7 +921,7 @@ You can also have other values for your application, for example, database conne
846 mysqlpass = "rootpass" 921 mysqlpass = "rootpass"
847 mysqlurls = "127.0.0.1" 922 mysqlurls = "127.0.0.1"
848 mysqldb = "beego" 923 mysqldb = "beego"
849 924
850 Then use following code to load your settings: 925 Then use following code to load your settings:
851 926
852 beego.AppConfig.String("mysqluser") 927 beego.AppConfig.String("mysqluser")
...@@ -862,33 +937,35 @@ AppConfig supports following methods: ...@@ -862,33 +937,35 @@ AppConfig supports following methods:
862 - Float(key string) (float64, error) 937 - Float(key string) (float64, error)
863 - String(key string) string 938 - String(key string) string
864 939
865 ##Beego arguments 940
941 ## Beego arguments
942
866 Beego has many configurable arguments, let me introduce to you all of them, so you can use them for more usage in your application: 943 Beego has many configurable arguments, let me introduce to you all of them, so you can use them for more usage in your application:
867 944
868 * BeeApp 945 * BeeApp
869 946
870 Entry point of Beego, it initialized in init() function when you import Beego package. 947 Entry point of Beego, it initialized in init() function when you import Beego package.
871 948
872 * AppConfig 949 * AppConfig
873 950
874 It stores values from file `conf/app.conf` and initialized in init() function. 951 It stores values from file `conf/app.conf` and initialized in init() function.
875 952
876 * HttpAddr 953 * HttpAddr
877 954
878 Application listening address, default is empty for listening all IP. 955 Application listening address, default is empty for listening all IP.
879 956
880 * HttpPort 957 * HttpPort
881 958
882 Application listening port, default is 8080. 959 Application listening port, default is 8080.
883 960
884 * AppName 961 * AppName
885 962
886 Application name, default is "beego". 963 Application name, default is "beego".
887 964
888 * RunMode 965 * RunMode
889 966
890 Application mode, default is "dev" develop mode and gives friendly error messages. 967 Application mode, default is "dev" develop mode and gives friendly error messages.
891 968
892 * AutoRender 969 * AutoRender
893 970
894 This value indicates whether auto-render or not, default is true, you should set to false for API usage applications. 971 This value indicates whether auto-render or not, default is true, you should set to false for API usage applications.
...@@ -905,37 +982,37 @@ Beego has many configurable arguments, let me introduce to you all of them, so y ...@@ -905,37 +982,37 @@ Beego has many configurable arguments, let me introduce to you all of them, so y
905 /debug/pprof/cmdline 982 /debug/pprof/cmdline
906 /debug/pprof/profile 983 /debug/pprof/profile
907 /debug/pprof/symbol 984 /debug/pprof/symbol
908 985
909 For more information about pprof, please read [pprof](http://golang.org/pkg/net/http/pprof/) 986 For more information about pprof, please read [pprof](http://golang.org/pkg/net/http/pprof/)
910 987
911 * ViewsPath 988 * ViewsPath
912 989
913 Template path, default is "views". 990 Template path, default is "views".
914 991
915 * SessionOn 992 * SessionOn
916 993
917 This value indicate whether enable session or not, default is false. 994 This value indicate whether enable session or not, default is false.
918 995
919 * SessionProvider 996 * SessionProvider
920 997
921 Session engine, default is memory. 998 Session engine, default is memory.
922 999
923 * SessionName 1000 * SessionName
924 1001
925 Name for cookie that save in client browser, default is "beegosessionID". 1002 Name for cookie that save in client browser, default is "beegosessionID".
926 1003
927 * SessionGCMaxLifetime 1004 * SessionGCMaxLifetime
928 1005
929 Session expired time, default is 3600 seconds. 1006 Session expired time, default is 3600 seconds.
930 1007
931 * SessionSavePath 1008 * SessionSavePath
932 1009
933 Save path of session, default is empty. 1010 Save path of session, default is empty.
934 1011
935 * UseFcgi 1012 * UseFcgi
936 1013
937 This value indicates whether enable fastcgi or not, default is false. 1014 This value indicates whether enable fastcgi or not, default is false.
938 1015
939 * MaxMemory 1016 * MaxMemory
940 1017
941 Maximum memory size for file upload, default is `1 << 26`(64M). 1018 Maximum memory size for file upload, default is `1 << 26`(64M).
...@@ -944,11 +1021,13 @@ Beego has many configurable arguments, let me introduce to you all of them, so y ...@@ -944,11 +1021,13 @@ Beego has many configurable arguments, let me introduce to you all of them, so y
944 1021
945 This value indicate whether enable gzip or not, default is false. 1022 This value indicate whether enable gzip or not, default is false.
946 1023
947 ##Integrated third-party applications 1024
1025 ## Integrated third-party applications
1026
948 Beego supports to integrate third-party application, you can customized `http.Handler` as follows: 1027 Beego supports to integrate third-party application, you can customized `http.Handler` as follows:
949 1028
950 beego.RouterHandler("/chat/:info(.*)", sockjshandler) 1029 beego.RouterHandler("/chat/:info(.*)", sockjshandler)
951 1030
952 sockjshandler implemented interface `http.Handler`. 1031 sockjshandler implemented interface `http.Handler`.
953 1032
954 Beego has an example for supporting chat of sockjs, here is the code: 1033 Beego has an example for supporting chat of sockjs, here is the code:
...@@ -967,7 +1046,7 @@ Beego has an example for supporting chat of sockjs, here is the code: ...@@ -967,7 +1046,7 @@ Beego has an example for supporting chat of sockjs, here is the code:
967 func chatHandler(s sockjs.Session) { 1046 func chatHandler(s sockjs.Session) {
968 users.Add(s) 1047 users.Add(s)
969 defer users.Remove(s) 1048 defer users.Remove(s)
970 1049
971 for { 1050 for {
972 m := s.Receive() 1051 m := s.Receive()
973 if m == nil { 1052 if m == nil {
...@@ -998,7 +1077,9 @@ Beego has an example for supporting chat of sockjs, here is the code: ...@@ -998,7 +1077,9 @@ Beego has an example for supporting chat of sockjs, here is the code:
998 1077
999 The above example implemented a simple chat room for sockjs, and you can use `http.Handler` for more extensions. 1078 The above example implemented a simple chat room for sockjs, and you can use `http.Handler` for more extensions.
1000 1079
1001 ##Deployment 1080
1081 ## Deployment
1082
1002 Go compiles program to binary file, you only need to copy this binary to your server and run it. Because Beego uses MVC model, so you may have folders for static files, configuration files and template files, so you have to copy those files as well. Here is a real example for deployment. 1083 Go compiles program to binary file, you only need to copy this binary to your server and run it. Because Beego uses MVC model, so you may have folders for static files, configuration files and template files, so you have to copy those files as well. Here is a real example for deployment.
1003 1084
1004 $ mkdir /opt/app/beepkg 1085 $ mkdir /opt/app/beepkg
...@@ -1006,7 +1087,7 @@ Go compiles program to binary file, you only need to copy this binary to your se ...@@ -1006,7 +1087,7 @@ Go compiles program to binary file, you only need to copy this binary to your se
1006 $ cp -fr views /opt/app/beepkg 1087 $ cp -fr views /opt/app/beepkg
1007 $ cp -fr static /opt/app/beepkg 1088 $ cp -fr static /opt/app/beepkg
1008 $ cp -fr conf /opt/app/beepkg 1089 $ cp -fr conf /opt/app/beepkg
1009 1090
1010 Here is the directory structure pf `/opt/app/beepkg`. 1091 Here is the directory structure pf `/opt/app/beepkg`.
1011 1092
1012 . 1093 .
...@@ -1018,12 +1099,12 @@ Here is the directory structure pf `/opt/app/beepkg`. ...@@ -1018,12 +1099,12 @@ Here is the directory structure pf `/opt/app/beepkg`.
1018 │ └── js 1099 │ └── js
1019 └── views 1100 └── views
1020 └── index.tpl 1101 └── index.tpl
1021 ├── beepkg 1102 ├── beepkg
1022 1103
1023 Now you can run your application in server, here are two good ways to manage your applications, and I recommend the first one. 1104 Now you can run your application in server, here are two good ways to manage your applications, and I recommend the first one.
1024 1105
1025 - Supervisord 1106 - Supervisord
1026 1107
1027 More information: [Supervisord](Supervisord.md) 1108 More information: [Supervisord](Supervisord.md)
1028 1109
1029 - nohup 1110 - nohup
...@@ -1031,4 +1112,4 @@ Now you can run your application in server, here are two good ways to manage you ...@@ -1031,4 +1112,4 @@ Now you can run your application in server, here are two good ways to manage you
1031 nohup ./beepkg & 1112 nohup ./beepkg &
1032 1113
1033 - [Introduction](README.md) 1114 - [Introduction](README.md)
1034 - [Step by step](Tutorial.md)
...\ No newline at end of file ...\ No newline at end of file
1115 - [Step by step](Tutorial.md)
......
1 #Beego 1 # Beego
2
2 Beego is a lightweight, open source, non-blocking and scalable web framework for the Go programming language. It's like tornado in Python. This web framework has already been using for building web server and tools in SNDA's CDN system. Documentation and downloads available at [http://astaxie.github.com/beego](http://astaxie.github.com/beego) 3 Beego is a lightweight, open source, non-blocking and scalable web framework for the Go programming language. It's like tornado in Python. This web framework has already been using for building web server and tools in SNDA's CDN system. Documentation and downloads available at [http://astaxie.github.com/beego](http://astaxie.github.com/beego)
3 4
4 It has following main features: 5 It has following main features:
...@@ -19,29 +20,33 @@ The working principles of Beego as follows: ...@@ -19,29 +20,33 @@ The working principles of Beego as follows:
19 Beego is licensed under the Apache Licence, Version 2.0 20 Beego is licensed under the Apache Licence, Version 2.0
20 (http://www.apache.org/licenses/LICENSE-2.0.html). 21 (http://www.apache.org/licenses/LICENSE-2.0.html).
21 22
22 #Simple example 23
24 # Simple example
25
23 The following example prints string "Hello world" to your browser, it shows how easy to build a web application with Beego. 26 The following example prints string "Hello world" to your browser, it shows how easy to build a web application with Beego.
24 27
25 package main 28 package main
26 29
27 import ( 30 import (
28 "github.com/astaxie/beego" 31 "github.com/astaxie/beego"
29 ) 32 )
30 33
31 type MainController struct { 34 type MainController struct {
32 beego.Controller 35 beego.Controller
33 } 36 }
34 37
35 func (this *MainController) Get() { 38 func (this *MainController) Get() {
36 this.Ctx.WriteString("hello world") 39 this.Ctx.WriteString("hello world")
37 } 40 }
38 41
39 func main() { 42 func main() {
40 beego.Router("/", &MainController{}) 43 beego.Router("/", &MainController{})
41 beego.Run() 44 beego.Run()
42 } 45 }
43 46
44 #Handbook 47
48 # Handbook
49
45 - [Purposes](Why.md) 50 - [Purposes](Why.md)
46 - [Installation](Install.md) 51 - [Installation](Install.md)
47 - [Quick start](Quickstart.md) 52 - [Quick start](Quickstart.md)
...@@ -49,5 +54,7 @@ The following example prints string "Hello world" to your browser, it shows how ...@@ -49,5 +54,7 @@ The following example prints string "Hello world" to your browser, it shows how
49 - [Real world usage](Application.md) 54 - [Real world usage](Application.md)
50 - [Hot update](HotUpdate.md) 55 - [Hot update](HotUpdate.md)
51 56
52 #Documentation
53 [Go Walker](http://gowalker.org/github.com/astaxie/beego)
...\ No newline at end of file ...\ No newline at end of file
57
58 # Documentation
59
60 [Go Walker](http://gowalker.org/github.com/astaxie/beego)
......
1 ##supervisord 1 ## supervisord
2 2
3 1. Installation 3 1. Installation
4 4
5 wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg 5 wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
6 6
7 sh setuptools-0.6c11-py2.7.egg 7 sh setuptools-0.6c11-py2.7.egg
8 8
9 easy_install supervisor 9 easy_install supervisor
10 10
11 echo_supervisord_conf >/etc/supervisord.conf 11 echo_supervisord_conf >/etc/supervisord.conf
12 12
13 mkdir /etc/supervisord.conf.d 13 mkdir /etc/supervisord.conf.d
14 14
15 2. Configure /etc/supervisord.conf 15 2. Configure /etc/supervisord.conf
16 16
17 [include] 17 [include]
18 files = /etc/supervisord.conf.d/*.conf 18 files = /etc/supervisord.conf.d/*.conf
19 19
20 3. Add new application 20 3. Add new application
21 21
22 cd /etc/supervisord.conf.d 22 cd /etc/supervisord.conf.d
...@@ -31,4 +31,4 @@ ...@@ -31,4 +31,4 @@
31 startsecs = 5 31 startsecs = 5
32 user = root 32 user = root
33 redirect_stderr = true 33 redirect_stderr = true
34 stdout_logfile = /var/log/supervisord/beepkg.log
...\ No newline at end of file ...\ No newline at end of file
34 stdout_logfile = /var/log/supervisord/beepkg.log
......
1 # 一步一步跟我写博客 1 # 一步一步跟我写博客
2 2
3
3 ## 创建项目 4 ## 创建项目
4 5
6
5 ## 数据库结构设计 7 ## 数据库结构设计
6 8
9
7 ## 控制器设计 10 ## 控制器设计
8 11
12
9 ## 模板设计 13 ## 模板设计
10 14
15
11 ## 用户登陆退出 16 ## 用户登陆退出
12 17
13 ## 数据库操作
...\ No newline at end of file ...\ No newline at end of file
18
19 ## 数据库操作
......
1 # Design purposes and ideas 1 # Design purposes and ideas
2
2 People may ask me why I want to build a new web framework rather than use other good ones. I know there are many excellent web frameworks on the internet and almost all of them are open source, and I have my reasons to do this. 3 People may ask me why I want to build a new web framework rather than use other good ones. I know there are many excellent web frameworks on the internet and almost all of them are open source, and I have my reasons to do this.
3 4
4 Remember when I was writing the book about how to build web applications with Go, I just wanted to tell people what were my valuable experiences with Go in web development, especially I have been working with PHP and Python for almost ten years. At first, I didn't realize that a small web framework can give great help to web developers when they are learning to build web applications in a new programming language, and it also helps people more by studying its source code. Finally, I decided to write a open source web framework called Beego as supporting materiel for my book. 5 Remember when I was writing the book about how to build web applications with Go, I just wanted to tell people what were my valuable experiences with Go in web development, especially I have been working with PHP and Python for almost ten years. At first, I didn't realize that a small web framework can give great help to web developers when they are learning to build web applications in a new programming language, and it also helps people more by studying its source code. Finally, I decided to write a open source web framework called Beego as supporting materiel for my book.
...@@ -9,11 +10,11 @@ I used to use CI in PHP and tornado in Python, there are both lightweight, so th ...@@ -9,11 +10,11 @@ I used to use CI in PHP and tornado in Python, there are both lightweight, so th
9 2. Learn more about languages by studying their source code, it's not hard to read and understand them because they are both lightweight frameworks. 10 2. Learn more about languages by studying their source code, it's not hard to read and understand them because they are both lightweight frameworks.
10 3. It's quite easy to make secondary development of these frameworks for specific purposes. 11 3. It's quite easy to make secondary development of these frameworks for specific purposes.
11 12
12 Those reasons are my original intention of implementing Beego, and used two chapters in my book to introduce and design this lightweight web framework in GO. 13 Those reasons are my original intention of implementing Beego, and used two chapters in my book to introduce and design this lightweight web framework in Go.
13 14
14 Then I started to design logic execution of Beego. Because Go and Python have somewhat similar, I referenced some ideas from tornado to design Beego. As you can see, there is no different between Beego and tornado in RESTful processing; they both use GET, POST or some other methods to implement RESTful. I took some ideas from [https://github.com/drone/routes](https://github.com/drone/routes) at the beginning of designing routes. It uses regular expression in route rules processing, which is an excellent idea that to make up for the default Mux router function in Go. However, I have to design my own interface in order to implement RESTful and use inherited ideas in Python. 15 Then I started to design logic execution of Beego. Because Go and Python have somewhat similar, I referenced some ideas from tornado to design Beego. As you can see, there is no different between Beego and tornado in RESTful processing; they both use GET, POST or some other methods to implement RESTful. I took some ideas from [https://github.com/drone/routes](https://github.com/drone/routes) at the beginning of designing routes. It uses regular expression in route rules processing, which is an excellent idea that to make up for the default Mux router function in Go. However, I have to design my own interface in order to implement RESTful and use inherited ideas in Python.
15 16
16 The controller is the most important part of whole MVC model, and Beego uses the interface and ideas I said above for the controller. Although I haven't decided to have to design the model part, everyone is welcome to implement data management by referencing Beedb, my another open source project. I simply adopt Go built-in template engine for the view part, but add more commonly used functions as template functions. This is how a simple web framework looks like, but I'll keep working on form processing, session handling, log recording, configuration, automated operation, etc, to build a simple but complete web framework. 17 The controller is the most important part of whole MVC model, and Beego uses the interface and ideas I said above for the controller. Although I haven't decided to have to design the model part, everyone is welcome to implement data management by referencing Beedb, my another open source project. I simply adopt Go built-in template engine for the view part, but add more commonly used functions as template functions. This is how a simple web framework looks like, but I'll keep working on form processing, session handling, log recording, configuration, automated operation, etc, to build a simple but complete web framework.
17 18
18 - [Introduction](README.md) 19 - [Introduction](README.md)
19 - [Installation](Install.md)
...\ No newline at end of file ...\ No newline at end of file
20 - [Installation](Install.md)
......
...@@ -2,10 +2,12 @@ ...@@ -2,10 +2,12 @@
2 2
3 热升级是什么呢?了解nginx的同学都知道,nginx是支持热升级的,可以用老进程服务先前链接的链接,使用新进程服务新的链接,即在不停止服务的情况下完成系统的升级与运行参数修改。那么热升级和热编译是不同的概念,热编译是通过监控文件的变化重新编译,然后重启进程,例如bee start就是这样的工具 3 热升级是什么呢?了解nginx的同学都知道,nginx是支持热升级的,可以用老进程服务先前链接的链接,使用新进程服务新的链接,即在不停止服务的情况下完成系统的升级与运行参数修改。那么热升级和热编译是不同的概念,热编译是通过监控文件的变化重新编译,然后重启进程,例如bee start就是这样的工具
4 4
5
5 ## 热升级有必要吗? 6 ## 热升级有必要吗?
6 7
7 很多人认为HTTP的应用有必要支持热升级吗?那么我可以很负责的说非常有必要,不中断服务始终是我们所追求的目标,虽然很多人说可能服务器会坏掉等等,这个是属于高可用的设计范畴,不要搞混了,这个是可预知的问题,所以我们需要避免这样的升级带来的用户不可用。你还在为以前升级搞到凌晨升级而烦恼嘛?那么现在就赶紧拥抱热升级吧。 8 很多人认为HTTP的应用有必要支持热升级吗?那么我可以很负责的说非常有必要,不中断服务始终是我们所追求的目标,虽然很多人说可能服务器会坏掉等等,这个是属于高可用的设计范畴,不要搞混了,这个是可预知的问题,所以我们需要避免这样的升级带来的用户不可用。你还在为以前升级搞到凌晨升级而烦恼嘛?那么现在就赶紧拥抱热升级吧。
8 9
10
9 ## beego如何支持热升级 11 ## beego如何支持热升级
10 热升级的原理基本上就是:主进程fork一个进程,然后子进程exec相应的程序。那么这个过程中发生了什么呢?我们知道进程fork之后会把主进程的所有句柄、数据和堆栈继承过来、但是里面所有的句柄存在一个叫做CloseOnExec,也就是执行exec的时候,copy的所有的句柄都被关闭了,除非特别申明,而我们期望的是子进程能够复用主进程的net.Listener的句柄。一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。 12 热升级的原理基本上就是:主进程fork一个进程,然后子进程exec相应的程序。那么这个过程中发生了什么呢?我们知道进程fork之后会把主进程的所有句柄、数据和堆栈继承过来、但是里面所有的句柄存在一个叫做CloseOnExec,也就是执行exec的时候,copy的所有的句柄都被关闭了,除非特别申明,而我们期望的是子进程能够复用主进程的net.Listener的句柄。一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。
11 13
...@@ -17,6 +19,7 @@ ...@@ -17,6 +19,7 @@
17 19
18 上面是我们需要解决的三个方面的问题,具体的实现大家可以看我实现的代码逻辑。 20 上面是我们需要解决的三个方面的问题,具体的实现大家可以看我实现的代码逻辑。
19 21
22
20 ## 如何演示热升级 23 ## 如何演示热升级
21 24
22 1. 编写代码,在beego应用的控制器中Get方法实现大概如下: 25 1. 编写代码,在beego应用的控制器中Get方法实现大概如下:
...@@ -28,15 +31,15 @@ ...@@ -28,15 +31,15 @@
28 } 31 }
29 32
30 2. 打开两个终端 33 2. 打开两个终端
31 34
32 一个终端输入:` ps -ef|grep 应用名` 35 一个终端输入:` ps -ef|grep 应用名`
33 36
34 一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=20"` 37 一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=20"`
35 38
36 3. 热升级 39 3. 热升级
37 40
38 `kill -HUP 进程ID` 41 `kill -HUP 进程ID`
39
40 4. 打开一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=0"`
41 42
42 我们可以看到这样的结果,第一个请求等待20s,但是处理他的是老的进程,热升级之后,第一个请求还在执行,最后会输出老的进程ID,而第二次请求,输出的是新的进程ID
...\ No newline at end of file ...\ No newline at end of file
43 4. 打开一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=0"`
44
45 我们可以看到这样的结果,第一个请求等待20s,但是处理他的是老的进程,热升级之后,第一个请求还在执行,最后会输出老的进程ID,而第二次请求,输出的是新的进程ID
......
1 # 安装入门 1 # 安装入门
2
2 beego虽然是一个简单的框架,但是其中用到了很多第三方的包,所以在你安装beego的过程中Go会自动安装其他关联的包。 3 beego虽然是一个简单的框架,但是其中用到了很多第三方的包,所以在你安装beego的过程中Go会自动安装其他关联的包。
3 4
4 - 当然第一步你需要安装Go,如何安装Go请参考我的书[第一章](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/01.1.md) 5 - 当然第一步你需要安装Go,如何安装Go请参考我的书[第一章](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/01.1.md)
...@@ -6,10 +7,10 @@ beego虽然是一个简单的框架,但是其中用到了很多第三方的包 ...@@ -6,10 +7,10 @@ beego虽然是一个简单的框架,但是其中用到了很多第三方的包
6 - 安装beego 7 - 安装beego
7 8
8 go get github.com/astaxie/beego 9 go get github.com/astaxie/beego
9 10
10 - 安装bee工具,这个工具可以用来快速的建立beego的应用 11 - 安装bee工具,这个工具可以用来快速的建立beego的应用
11 12
12 go get github.com/astaxie/bee 13 go get github.com/astaxie/bee
13 14
14 这样就完成了beego的安装,你就可以开始开发了,可以通过bee工具来创建beego项目 15 这样就完成了beego的安装,你就可以开始开发了,可以通过bee工具来创建beego项目
15 16
...@@ -19,6 +20,7 @@ beego虽然是一个简单的框架,但是其中用到了很多第三方的包 ...@@ -19,6 +20,7 @@ beego虽然是一个简单的框架,但是其中用到了很多第三方的包
19 20
20 > - session模块:github.com/astaxie/beego/session 21 > - session模块:github.com/astaxie/beego/session
21 22
23
22 > - session模块中支持redis引擎:github.com/garyburd/redigo/redis 24 > - session模块中支持redis引擎:github.com/garyburd/redigo/redis
23 25
24 > - session模块中支持mysql引擎:github.com/go-sql-driver/mysql 26 > - session模块中支持mysql引擎:github.com/go-sql-driver/mysql
...@@ -27,4 +29,4 @@ beego虽然是一个简单的框架,但是其中用到了很多第三方的包 ...@@ -27,4 +29,4 @@ beego虽然是一个简单的框架,但是其中用到了很多第三方的包
27 29
28 30
29 - [beego介绍](README.md) 31 - [beego介绍](README.md)
30 - [快速入门](Quickstart.md)
...\ No newline at end of file ...\ No newline at end of file
32 - [快速入门](Quickstart.md)
......
1 # 快速入门 1 # 快速入门
2
2 你对beego一无所知?没关系,这篇文档会很好的详细介绍beego的各个方面,看这个文档之前首先确认你已经安装了beego,如果你没有安装的话,请看这篇[安装指南](Install.md) 3 你对beego一无所知?没关系,这篇文档会很好的详细介绍beego的各个方面,看这个文档之前首先确认你已经安装了beego,如果你没有安装的话,请看这篇[安装指南](Install.md)
3 4
4 **导航** 5 **导航**
...@@ -23,11 +24,13 @@ ...@@ -23,11 +24,13 @@
23 - [第三方应用集成](#-19) 24 - [第三方应用集成](#-19)
24 - [部署编译应用](#-20) 25 - [部署编译应用](#-20)
25 26
27
26 ## 最小应用 28 ## 最小应用
29
27 一个最小最简单的应用如下代码所示: 30 一个最小最简单的应用如下代码所示:
28 31
29 package main 32 package main
30 33
31 import ( 34 import (
32 "github.com/astaxie/beego" 35 "github.com/astaxie/beego"
33 ) 36 )
...@@ -59,7 +62,7 @@ ...@@ -59,7 +62,7 @@
59 2、定义Controller,这里我们定义了一个struct为`MainController`,充分利用了Go语言的组合的概念,匿名包含了`beego.Controller`,这样我们的`MainController`就拥有了`beego.Controller`的所有方法。 62 2、定义Controller,这里我们定义了一个struct为`MainController`,充分利用了Go语言的组合的概念,匿名包含了`beego.Controller`,这样我们的`MainController`就拥有了`beego.Controller`的所有方法。
60 63
61 3、定义RESTFul方法,通过匿名组合之后,其实目前的`MainController`已经拥有了`Get``Post``Delete``Put`等方法,这些方法是分别用来对应用户请求的Method函数,如果用户发起的是`POST`请求,那么就执行`Post`函数。所以这里我们定义了`MainController``Get`方法用来重写继承的`Get`函数,这样当用户`GET`请求的时候就会执行该函数。 64 3、定义RESTFul方法,通过匿名组合之后,其实目前的`MainController`已经拥有了`Get``Post``Delete``Put`等方法,这些方法是分别用来对应用户请求的Method函数,如果用户发起的是`POST`请求,那么就执行`Post`函数。所以这里我们定义了`MainController``Get`方法用来重写继承的`Get`函数,这样当用户`GET`请求的时候就会执行该函数。
62 65
63 4、定义main函数,所有的Go应用程序和C语言一样都是Main函数作为入口,所以我们这里定义了我们应用的入口。 66 4、定义main函数,所有的Go应用程序和C语言一样都是Main函数作为入口,所以我们这里定义了我们应用的入口。
64 67
65 5、Router注册路由,路由就是告诉beego,当用户来请求的时候,该如何去调用相应的Controller,这里我们注册了请求`/`的时候,请求到`MainController`。这里我们需要知道,Router函数的两个参数函数,第一个是路径,第二个是Controller的指针。 68 5、Router注册路由,路由就是告诉beego,当用户来请求的时候,该如何去调用相应的Controller,这里我们注册了请求`/`的时候,请求到`MainController`。这里我们需要知道,Router函数的两个参数函数,第一个是路径,第二个是Controller的指针。
...@@ -68,12 +71,13 @@ ...@@ -68,12 +71,13 @@
68 71
69 停止服务的话,请按`ctrl+c` 72 停止服务的话,请按`ctrl+c`
70 73
74
71 ## 新建项目 75 ## 新建项目
72 76
73 通过如下命令创建beego项目,首先进入gopath目录 77 通过如下命令创建beego项目,首先进入gopath目录
74 78
75 bee create hello 79 bee create hello
76 80
77 这样就建立了一个项目hello,目录结构如下所示 81 这样就建立了一个项目hello,目录结构如下所示
78 82
79 . 83 .
...@@ -90,10 +94,11 @@ ...@@ -90,10 +94,11 @@
90 └── views 94 └── views
91 └── index.tpl 95 └── index.tpl
92 96
97
93 ## 开发模式 98 ## 开发模式
94 99
95 通过bee创建的项目,beego默认情况下是开发模式。 100 通过bee创建的项目,beego默认情况下是开发模式。
96 101
97 我们可以通过如下的方式改变我们的模式: 102 我们可以通过如下的方式改变我们的模式:
98 103
99 beego.RunMode = "pro" 104 beego.RunMode = "pro"
...@@ -115,6 +120,7 @@ ...@@ -115,6 +120,7 @@
115 120
116 ![](images/dev.png) 121 ![](images/dev.png)
117 122
123
118 ## 路由设置 124 ## 路由设置
119 125
120 路由的主要功能是实现从请求地址到实现方法,beego中封装了`Controller`,所以路由是从路径到`ControllerInterface`的过程,`ControllerInterface`的方法有如下: 126 路由的主要功能是实现从请求地址到实现方法,beego中封装了`Controller`,所以路由是从路径到`ControllerInterface`的过程,`ControllerInterface`的方法有如下:
...@@ -144,40 +150,42 @@ ...@@ -144,40 +150,42 @@
144 150
145 为了用户更加方便的路由设置,beego参考了sinatra的路由实现,支持多种方式的路由: 151 为了用户更加方便的路由设置,beego参考了sinatra的路由实现,支持多种方式的路由:
146 152
147 - beego.Router("/api/:id([0-9]+)", &controllers.RController{}) 153 - beego.Router("/api/:id([0-9]+)", &controllers.RController{})
148 自定义正则匹配 //匹配 /api/123 :id= 123 154 自定义正则匹配 //匹配 /api/123 :id= 123
149 155
150 - beego.Router("/news/:all", &controllers.RController{}) 156 - beego.Router("/news/:all", &controllers.RController{})
151 全匹配方式 //匹配 /news/path/to/123.html :all= path/to/123.html 157 全匹配方式 //匹配 /news/path/to/123.html :all= path/to/123.html
152 158
153 - beego.Router(\`/user/:username([\w]+)\`, &controllers.RController{}) 159 - beego.Router(\`/user/:username([\w]+)\`, &controllers.RController{})
154 正则字符串匹配 //匹配 /user/astaxie :username = astaxie 160 正则字符串匹配 //匹配 /user/astaxie :username = astaxie
155 161
156 - beego.Router("/download/*.*", &controllers.RController{}) 162 - beego.Router("/download/*.*", &controllers.RController{})
157 *匹配方式 //匹配 /download/file/api.xml :path= file/api :ext=xml 163 *匹配方式 //匹配 /download/file/api.xml :path= file/api :ext=xml
158 164
159 - beego.Router("/download/ceshi/*", &controllers.RController{}) 165 - beego.Router("/download/ceshi/*", &controllers.RController{})
160 *全匹配方式 //匹配 /download/ceshi/file/api.json :splat=file/api.json 166 *全匹配方式 //匹配 /download/ceshi/file/api.json :splat=file/api.json
161 167
162 - beego.Router("/:id:int", &controllers.RController{}) 168 - beego.Router("/:id:int", &controllers.RController{})
163 int类型设置方式 //匹配 :id为int类型,框架帮你实现了正则([0-9]+) 169 int类型设置方式 //匹配 :id为int类型,框架帮你实现了正则([0-9]+)
164 170
165 - beego.Router("/:hi:string", &controllers.RController{}) 171 - beego.Router("/:hi:string", &controllers.RController{})
166 string类型设置方式 //匹配 :hi为string类型。框架帮你实现了正则([\w]+) 172 string类型设置方式 //匹配 :hi为string类型。框架帮你实现了正则([\w]+)
167 173
168 如何在Controller中获取,上面的变量可以通过如下方式获取 174 如何在Controller中获取,上面的变量可以通过如下方式获取
169 175
170 this.Ctx.Params[":id"] 176 this.Ctx.Params[":id"]
171 this.Ctx.Params[":username"] 177 this.Ctx.Params[":username"]
172 this.Ctx.Params[":splat"] 178 this.Ctx.Params[":splat"]
173 this.Ctx.Params[":path"] 179 this.Ctx.Params[":path"]
174 this.Ctx.Params[":ext"] 180 this.Ctx.Params[":ext"]
181
175 182
176 ## 静态文件 183 ## 静态文件
184
177 Go语言内部其实已经提供了`http.ServeFile`,通过这个函数可以实现静态文件的服务。beego针对这个功能进行了一层封装,通过下面的方式进行静态文件注册: 185 Go语言内部其实已经提供了`http.ServeFile`,通过这个函数可以实现静态文件的服务。beego针对这个功能进行了一层封装,通过下面的方式进行静态文件注册:
178 186
179 beego.SetStaticPath("/static","public") 187 beego.SetStaticPath("/static","public")
180 188
181 - 第一个参数是路径,url路径信息 189 - 第一个参数是路径,url路径信息
182 - 第二个参数是静态文件目录(相对应用所在的目录) 190 - 第二个参数是静态文件目录(相对应用所在的目录)
183 191
...@@ -189,37 +197,41 @@ beego葵敶辣瘜典隞交釣 ...@@ -189,37 +197,41 @@ beego葵敶辣瘜典隞交釣
189 197
190 设置了如上的静态目录之后,用户访问`/images/login/login.png`,那么就会访问应用对应的目录下面的`images/login/login.png`文件。如果是访问`/static/img/logo.png`,那么就访问`public/img/logo.png`文件。 198 设置了如上的静态目录之后,用户访问`/images/login/login.png`,那么就会访问应用对应的目录下面的`images/login/login.png`文件。如果是访问`/static/img/logo.png`,那么就访问`public/img/logo.png`文件。
191 199
200
192 ## 过滤和中间件 201 ## 过滤和中间件
202
193 beego支持自定义过滤中间件,例如安全验证,强制跳转等 203 beego支持自定义过滤中间件,例如安全验证,强制跳转等
194 204
195 如下例子所示,验证用户名是否是admin,应用于全部的请求: 205 如下例子所示,验证用户名是否是admin,应用于全部的请求:
196 206
197 var FilterUser = func(w http.ResponseWriter, r *http.Request) { 207 var FilterUser = func(w http.ResponseWriter, r *http.Request) {
198 if r.URL.User == nil || r.URL.User.Username() != "admin" { 208 if r.URL.User == nil || r.URL.User.Username() != "admin" {
199 http.Error(w, "", http.StatusUnauthorized) 209 http.Error(w, "", http.StatusUnauthorized)
200 } 210 }
201 } 211 }
202
203 beego.Filter(FilterUser)
204 212
213 beego.Filter(FilterUser)
214
205 还可以通过参数进行过滤,如果匹配参数就执行 215 还可以通过参数进行过滤,如果匹配参数就执行
206 216
207 beego.Router("/:id([0-9]+)", &admin.EditController{}) 217 beego.Router("/:id([0-9]+)", &admin.EditController{})
208 beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) { 218 beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) {
209 dosomething() 219 dosomething()
210 }) 220 })
211 221
212 当然你还可以通过前缀过滤 222 当然你还可以通过前缀过滤
213 223
214 beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) { 224 beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) {
215 dosomething() 225 dosomething()
216 }) 226 })
217 227
228
218 ## 控制器设计 229 ## 控制器设计
230
219 基于beego的Controller设计,只需要匿名组合`beego.Controller`就可以了,如下所示: 231 基于beego的Controller设计,只需要匿名组合`beego.Controller`就可以了,如下所示:
220 232
221 type xxxController struct { 233 type xxxController struct {
222 beego.Controller 234 beego.Controller
223 } 235 }
224 236
225 `beego.Controller`实现了接口`beego.ControllerInterface``beego.ControllerInterface`定义了如下函数: 237 `beego.Controller`实现了接口`beego.ControllerInterface``beego.ControllerInterface`定义了如下函数:
...@@ -227,15 +239,15 @@ beego摰誘銝剝隞塚撉撩頝唾蓮蝑 ...@@ -227,15 +239,15 @@ beego摰誘銝剝隞塚撉撩頝唾蓮蝑
227 - Init(ct *Context, cn string) 239 - Init(ct *Context, cn string)
228 240
229 这个函数主要初始化了Context、相应的Controller名称,模板名,初始化模板参数的容器Data 241 这个函数主要初始化了Context、相应的Controller名称,模板名,初始化模板参数的容器Data
230 242
231 - Prepare() 243 - Prepare()
232 244
233 这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些Method方法之前执行,用户可以重写这个函数实现类似用户验证之类。 245 这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些Method方法之前执行,用户可以重写这个函数实现类似用户验证之类。
234 246
235 - Get() 247 - Get()
236 248
237 如果用户请求的HTTP Method是GET, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Get请求. 249 如果用户请求的HTTP Method是GET, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Get请求.
238 250
239 - Post() 251 - Post()
240 252
241 如果用户请求的HTTP Method是POST, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Post请求. 253 如果用户请求的HTTP Method是POST, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Post请求.
...@@ -271,60 +283,71 @@ beego摰誘銝剝隞塚撉撩頝唾蓮蝑 ...@@ -271,60 +283,71 @@ beego摰誘銝剝隞塚撉撩頝唾蓮蝑
271 所以通过子struct的方法重写,用户就可以实现自己的逻辑,接下来我们看一个实际的例子: 283 所以通过子struct的方法重写,用户就可以实现自己的逻辑,接下来我们看一个实际的例子:
272 284
273 type AddController struct { 285 type AddController struct {
274 beego.Controller 286 beego.Controller
275 } 287 }
276 288
277 func (this *AddController) Prepare() { 289 func (this *AddController) Prepare() {
278 290
279 } 291 }
280 292
281 func (this *AddController) Get() { 293 func (this *AddController) Get() {
282 this.Data["content"] ="value" 294 this.Data["content"] = "value"
283 this.Layout = "admin/layout.html" 295 this.Layout = "admin/layout.html"
284 this.TplNames = "admin/add.tpl" 296 this.TplNames = "admin/add.tpl"
285 } 297 }
286 298
287 func (this *AddController) Post() { 299 func (this *AddController) Post() {
288 pkgname := this.GetString("pkgname") 300 pkgname := this.GetString("pkgname")
289 content := this.GetString("content") 301 content := this.GetString("content")
290 pk := models.GetCruPkg(pkgname) 302 pk := models.GetCruPkg(pkgname)
291 if pk.Id == 0 { 303 if pk.Id == 0 {
292 var pp models.PkgEntity 304 var pp models.PkgEntity
293 pp.Pid = 0 305 pp.Pid = 0
294 pp.Pathname = pkgname 306 pp.Pathname = pkgname
295 pp.Intro = pkgname 307 pp.Intro = pkgname
296 models.InsertPkg(pp) 308 models.InsertPkg(pp)
297 pk = models.GetCruPkg(pkgname) 309 pk = models.GetCruPkg(pkgname)
298 } 310 }
299 var at models.Article 311 var at models.Article
300 at.Pkgid = pk.Id 312 at.Pkgid = pk.Id
301 at.Content = content 313 at.Content = content
302 models.InsertArticle(at) 314 models.InsertArticle(at)
303 this.Ctx.Redirect(302, "/admin/index") 315 this.Ctx.Redirect(302, "/admin/index")
304 } 316 }
305 317
318
306 ## 模板处理 319 ## 模板处理
320
321
307 ### 模板目录 322 ### 模板目录
323
308 beego中默认的模板目录是`views`,用户可以把你的模板文件放到该目录下,beego会自动在该目录下的所有模板文件进行解析并缓存,开发模式下会每次重新解析,不做缓存。当然用户可以通过如下的方式改变模板的目录: 324 beego中默认的模板目录是`views`,用户可以把你的模板文件放到该目录下,beego会自动在该目录下的所有模板文件进行解析并缓存,开发模式下会每次重新解析,不做缓存。当然用户可以通过如下的方式改变模板的目录:
309 325
310 beego.ViewsPath = "/myviewpath" 326 beego.ViewsPath = "/myviewpath"
327
328
311 ### 自动渲染 329 ### 自动渲染
330
312 beego中用户无需手动的调用渲染输出模板,beego会自动的在调用完相应的method方法之后调用Render函数,当然如果你的应用是不需要模板输出的,那么你可以在配置文件或者在main.go中设置关闭自动渲染。 331 beego中用户无需手动的调用渲染输出模板,beego会自动的在调用完相应的method方法之后调用Render函数,当然如果你的应用是不需要模板输出的,那么你可以在配置文件或者在main.go中设置关闭自动渲染。
313 332
314 配置文件配置如下: 333 配置文件配置如下:
315 334
316 autorender = false 335 autorender = false
317 336
318 main.go文件中设置如下: 337 main.go文件中设置如下:
319 338
320 beego.AutoRender = false 339 beego.AutoRender = false
321 340
341
322 ### 模板数据 342 ### 模板数据
343
323 模板中的数据是通过在Controller中`this.Data`获取的,所以如果你想在模板中获取内容`{{.Content}}`,那么你需要在Controller中如下设置: 344 模板中的数据是通过在Controller中`this.Data`获取的,所以如果你想在模板中获取内容`{{.Content}}`,那么你需要在Controller中如下设置:
324 345
325 this.Data["Context"] = "value" 346 this.Data["Context"] = "value"
326 347
348
327 ### 模板名称 349 ### 模板名称
350
328 beego采用了Go语言内置的模板引擎,所有模板的语法和Go的一模一样,至于如何写模板文件,详细的请参考[模板教程](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/07.4.md) 351 beego采用了Go语言内置的模板引擎,所有模板的语法和Go的一模一样,至于如何写模板文件,详细的请参考[模板教程](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/07.4.md)
329 352
330 用户通过在Controller的对应方法中设置相应的模板名称,beego会自动的在viewpath目录下查询该文件并渲染,例如下面的设置,beego会在admin下面找add.tpl文件进行渲染: 353 用户通过在Controller的对应方法中设置相应的模板名称,beego会自动的在viewpath目录下查询该文件并渲染,例如下面的设置,beego会在admin下面找add.tpl文件进行渲染:
...@@ -341,16 +364,18 @@ beego鈭o霂剛蔭芋撘芋祗瘜o璅 ...@@ -341,16 +364,18 @@ beego鈭o霂剛蔭芋撘芋祗瘜o璅
341 364
342 也就是你对应的Controller名字+请求方法名.模板后缀,也就是如果你的Controller名是`AddController`,请求方法是`POST`,默认的文件后缀是`tpl`,那么就会默认请求`/viewpath/AddController/POST.tpl`文件。 365 也就是你对应的Controller名字+请求方法名.模板后缀,也就是如果你的Controller名是`AddController`,请求方法是`POST`,默认的文件后缀是`tpl`,那么就会默认请求`/viewpath/AddController/POST.tpl`文件。
343 366
367
344 ### layout设计 368 ### layout设计
369
345 beego支持layout设计,例如你在管理系统中,其实整个的管理界面是固定的,只会变化中间的部分,那么你可以通过如下的设置: 370 beego支持layout设计,例如你在管理系统中,其实整个的管理界面是固定的,只会变化中间的部分,那么你可以通过如下的设置:
346 371
347 this.Layout = "admin/layout.html" 372 this.Layout = "admin/layout.html"
348 this.TplNames = "admin/add.tpl" 373 this.TplNames = "admin/add.tpl"
349 374
350 在layout.html中你必须设置如下的变量: 375 在layout.html中你必须设置如下的变量:
351 376
352 {{.LayoutContent}} 377 {{.LayoutContent}}
353 378
354 beego就会首先解析TplNames指定的文件,获取内容赋值给LayoutContent,然后最后渲染layout.html文件。 379 beego就会首先解析TplNames指定的文件,获取内容赋值给LayoutContent,然后最后渲染layout.html文件。
355 380
356 目前采用首先把目录下所有的文件进行缓存,所以用户还可以通过类似这样的方式实现layout: 381 目前采用首先把目录下所有的文件进行缓存,所以用户还可以通过类似这样的方式实现layout:
...@@ -359,12 +384,14 @@ beego撠曹圾plNames辣嚗捆韏潛ayoutCont ...@@ -359,12 +384,14 @@ beego撠曹圾plNames辣嚗捆韏潛ayoutCont
359 处理逻辑 384 处理逻辑
360 {{template "footer.html"}} 385 {{template "footer.html"}}
361 386
387
362 ### 模板函数 388 ### 模板函数
389
363 beego支持用户定义模板函数,但是必须在`beego.Run()`调用之前,设置如下: 390 beego支持用户定义模板函数,但是必须在`beego.Run()`调用之前,设置如下:
364 391
365 func hello(in string)(out string){ 392 func hello(in string)(out string){
366 out = in + "world" 393 out = in + "world"
367 return 394 return
368 } 395 }
369 396
370 beego.AddFuncMap("hi",hello) 397 beego.AddFuncMap("hi",hello)
...@@ -375,35 +402,45 @@ beego摰芋嚗敹◆`beego.Run()`靚銋 ...@@ -375,35 +402,45 @@ beego摰芋嚗敹◆`beego.Run()`靚銋
375 402
376 目前beego内置的模板函数有如下: 403 目前beego内置的模板函数有如下:
377 404
378 * markdown 405 * markdown
379 406
380 实现了把markdown文本转化为html信息,使用方法{{markdown .Content}} 407 实现了把markdown文本转化为html信息,使用方法{{markdown .Content}}
381 * dateformat 408
409 * dateformat
382 410
383 实现了时间的格式化,返回字符串,使用方法{{dateformat .Time "2006-01-02T15:04:05Z07:00"}} 411 实现了时间的格式化,返回字符串,使用方法{{dateformat .Time "2006-01-02T15:04:05Z07:00"}}
384 * date 412
413 * date
385 414
386 实现了类似PHP的date函数,可以很方便的根据字符串返回时间,使用方法{{date .T "Y-m-d H:i:s"}} 415 实现了类似PHP的date函数,可以很方便的根据字符串返回时间,使用方法{{date .T "Y-m-d H:i:s"}}
387 * compare 416
417 * compare
388 418
389 实现了比较两个对象的比较,如果相同返回true,否者false,使用方法{{compare .A .B}} 419 实现了比较两个对象的比较,如果相同返回true,否者false,使用方法{{compare .A .B}}
390 * substr 420
421 * substr
391 422
392 实现了字符串的截取,支持中文截取的完美截取,使用方法{{substr .Str 0 30}} 423 实现了字符串的截取,支持中文截取的完美截取,使用方法{{substr .Str 0 30}}
393 * html2str 424
425 * html2str
394 426
395 实现了把html转化为字符串,剔除一些script、css之类的元素,返回纯文本信息,使用方法{{html2str .Htmlinfo}} 427 实现了把html转化为字符串,剔除一些script、css之类的元素,返回纯文本信息,使用方法{{html2str .Htmlinfo}}
396 * str2html 428
429 * str2html
397 430
398 实现了把相应的字符串当作HTML来输出,不转义,使用方法{{str2html .Strhtml}} 431 实现了把相应的字符串当作HTML来输出,不转义,使用方法{{str2html .Strhtml}}
399 * htmlquote 432
433 * htmlquote
400 434
401 实现了基本的html字符转义,使用方法{{htmlquote .quote}} 435 实现了基本的html字符转义,使用方法{{htmlquote .quote}}
402 * htmlunquote 436
437 * htmlunquote
403 438
404 实现了基本的反转移字符,使用方法{{htmlunquote .unquote}} 439 实现了基本的反转移字符,使用方法{{htmlunquote .unquote}}
405 440
441
406 ## request处理 442 ## request处理
443
407 我们经常需要获取用户传递的数据,包括Get、POST等方式的请求,beego里面会自动解析这些数据,你可以通过如下方式获取数据 444 我们经常需要获取用户传递的数据,包括Get、POST等方式的请求,beego里面会自动解析这些数据,你可以通过如下方式获取数据
408 445
409 - GetString(key string) string 446 - GetString(key string) string
...@@ -425,16 +462,18 @@ beego摰芋嚗敹◆`beego.Run()`靚銋 ...@@ -425,16 +462,18 @@ beego摰芋嚗敹◆`beego.Run()`靚銋
425 func (this *MainController) Post() { 462 func (this *MainController) Post() {
426 id := this.Input().Get("id") 463 id := this.Input().Get("id")
427 intid, err := strconv.Atoi(id) 464 intid, err := strconv.Atoi(id)
428 } 465 }
429 466
430 更多其他的request的信息,用户可以通过`this.Ctx.Request`获取信息,关于该对象的属性和方法参考手册[Request](http://golang.org/pkg/net/http/#Request) 467 更多其他的request的信息,用户可以通过`this.Ctx.Request`获取信息,关于该对象的属性和方法参考手册[Request](http://golang.org/pkg/net/http/#Request)
431 468
469
432 ### 文件上传 470 ### 文件上传
471
433 在beego中你可以很容易的处理文件上传,就是别忘记在你的form表单中增加这个属性`enctype="multipart/form-data"`,否者你的浏览器不会传输你的上传文件。 472 在beego中你可以很容易的处理文件上传,就是别忘记在你的form表单中增加这个属性`enctype="multipart/form-data"`,否者你的浏览器不会传输你的上传文件。
434 473
435 文件上传之后一般是放在系统的内存里面,如果文件的size大于设置的缓存内存大小,那么就放在临时文件中,默认的缓存内存是64M,你可以通过如下来调整这个缓存内存大小: 474 文件上传之后一般是放在系统的内存里面,如果文件的size大于设置的缓存内存大小,那么就放在临时文件中,默认的缓存内存是64M,你可以通过如下来调整这个缓存内存大小:
436 475
437 beego.MaxMemory = 1<<22 476 beego.MaxMemory = 1<<22
438 477
439 或者在配置文件中通过如下设置 478 或者在配置文件中通过如下设置
440 479
...@@ -445,42 +484,46 @@ beego舅銝芸靘輻瘜憭辣銝 ...@@ -445,42 +484,46 @@ beego舅銝芸靘輻瘜憭辣銝
445 - GetFile(key string) (multipart.File, *multipart.FileHeader, error) 484 - GetFile(key string) (multipart.File, *multipart.FileHeader, error)
446 485
447 该方法主要用于用户读取表单中的文件名`the_file`,然后返回相应的信息,用户根据这些变量来处理文件上传:过滤、保存文件等。 486 该方法主要用于用户读取表单中的文件名`the_file`,然后返回相应的信息,用户根据这些变量来处理文件上传:过滤、保存文件等。
448 487
449 - SaveToFile(fromfile, tofile string) error 488 - SaveToFile(fromfile, tofile string) error
450 489
451 该方法是在GetFile的基础上实现了快速保存的功能 490 该方法是在GetFile的基础上实现了快速保存的功能
452 491
453 保存的代码例子如下: 492 保存的代码例子如下:
454 493
455 func (this *MainController) Post() { 494 func (this *MainController) Post() {
456 this.SaveToFile("the_file","/var/www/uploads/uploaded_file.txt"") 495 this.SaveToFile("the_file","/var/www/uploads/uploaded_file.txt"")
457 } 496 }
458 497
498
459 ### JSON和XML输出 499 ### JSON和XML输出
500
460 beego当初设计的时候就考虑了API功能的设计,而我们在设计API的时候经常是输出JSON或者XML数据,那么beego提供了这样的方式直接输出: 501 beego当初设计的时候就考虑了API功能的设计,而我们在设计API的时候经常是输出JSON或者XML数据,那么beego提供了这样的方式直接输出:
461 502
462 JSON数据直接输出,设置`content-type``application/json` 503 JSON数据直接输出,设置`content-type``application/json`
463 504
464 func (this *AddController) Get() { 505 func (this *AddController) Get() {
465 mystruct := { ... } 506 mystruct := { ... }
466 this.Data["json"] = &mystruct 507 this.Data["json"] = &mystruct
467 this.ServeJson() 508 this.ServeJson()
468 } 509 }
469 510
470 XML数据直接输出,设置`content-type``application/xml` 511 XML数据直接输出,设置`content-type``application/xml`
471 512
472 func (this *AddController) Get() { 513 func (this *AddController) Get() {
473 mystruct := { ... } 514 mystruct := { ... }
474 this.Data["xml"]=&mystruct 515 this.Data["xml"]=&mystruct
475 this.ServeXml() 516 this.ServeXml()
476 } 517 }
477 518
519
478 ## 跳转和错误 520 ## 跳转和错误
521
479 我们在做Web开发的时候,经常会遇到页面调整和错误处理,beego这这方面也进行了考虑,通过`Redirect`方法来进行跳转: 522 我们在做Web开发的时候,经常会遇到页面调整和错误处理,beego这这方面也进行了考虑,通过`Redirect`方法来进行跳转:
480 523
481 func (this *AddController) Get() { 524 func (this *AddController) Get() {
482 this.Redirect("/", 302) 525 this.Redirect("/", 302)
483 } 526 }
484 527
485 如何中止此次请求并抛出异常,beego可以在控制器中这操作 528 如何中止此次请求并抛出异常,beego可以在控制器中这操作
486 529
...@@ -494,12 +537,12 @@ XML颲嚗挽蝵害content-type`銝槁application/xml`嚗 ...@@ -494,12 +537,12 @@ XML颲嚗挽蝵害content-type`銝槁application/xml`嚗
494 this.SetSession("asta", v.(int)+1) 537 this.SetSession("asta", v.(int)+1)
495 this.Data["Email"] = v.(int) 538 this.Data["Email"] = v.(int)
496 } 539 }
497 this.TplNames = "index.tpl" 540 this.TplNames = "index.tpl"
498 } 541 }
499 542
500 这样`this.Abort("401")`之后的代码不会再执行,而且会默认显示给用户如下页面 543 这样`this.Abort("401")`之后的代码不会再执行,而且会默认显示给用户如下页面
501 544
502 ![](images/401.png) 545 ![](images/401.png)
503 546
504 beego框架默认支持404、401、403、500、503这几种错误的处理。用户可以自定义相应的错误处理,例如下面重新定义404页面: 547 beego框架默认支持404、401、403、500、503这几种错误的处理。用户可以自定义相应的错误处理,例如下面重新定义404页面:
505 548
...@@ -514,7 +557,7 @@ beego獢暺恕404401403500503餈秤 ...@@ -514,7 +557,7 @@ beego獢暺恕404401403500503餈秤
514 beego.Errorhandler("404",page_not_found) 557 beego.Errorhandler("404",page_not_found)
515 beego.Router("/", &controllers.MainController{}) 558 beego.Router("/", &controllers.MainController{})
516 beego.Run() 559 beego.Run()
517 } 560 }
518 561
519 我们可以通过自定义错误页面`404.html`来处理404错误。 562 我们可以通过自定义错误页面`404.html`来处理404错误。
520 563
...@@ -526,33 +569,37 @@ beego犖批銝芾挽霈∪停摰泵銝脤 ...@@ -526,33 +569,37 @@ beego犖批銝芾挽霈∪停摰泵銝脤
526 data["content"] = "database is now down" 569 data["content"] = "database is now down"
527 t.Execute(rw, data) 570 t.Execute(rw, data)
528 } 571 }
529 572
530 func main() { 573 func main() {
531 beego.Errorhandler("dbError",dbError) 574 beego.Errorhandler("dbError",dbError)
532 beego.Router("/", &controllers.MainController{}) 575 beego.Router("/", &controllers.MainController{})
533 beego.Run() 576 beego.Run()
534 } 577 }
535 578
536 一旦在入口注册该错误处理代码,那么你可以在任何你的逻辑中遇到数据库错误调用`this.Abort("dbError")`来进行异常页面处理。 579 一旦在入口注册该错误处理代码,那么你可以在任何你的逻辑中遇到数据库错误调用`this.Abort("dbError")`来进行异常页面处理。
537 580
581
538 ## response处理 582 ## response处理
583
539 response可能会有集中情况: 584 response可能会有集中情况:
540 585
541 1. 模板输出 586 1. 模板输出
542 587
543 模板输出上面模板介绍里面已经介绍,beego会在执行完相应的Controller里面的对应的Method之后输出到模板。 588 模板输出上面模板介绍里面已经介绍,beego会在执行完相应的Controller里面的对应的Method之后输出到模板。
544 589
545 2. 跳转 590 2. 跳转
546 591
547 上一节介绍的跳转就是我们经常用到的页面之间的跳转 592 上一节介绍的跳转就是我们经常用到的页面之间的跳转
548 593
549 3. 字符串输出 594 3. 字符串输出
550 595
551 有些时候我们只是想输出相应的一个字符串,那么我们可以通过如下的代码实现 596 有些时候我们只是想输出相应的一个字符串,那么我们可以通过如下的代码实现
552 597
553 this.Ctx.WriteString("ok") 598 this.Ctx.WriteString("ok")
554 599
600
555 ## Sessions 601 ## Sessions
602
556 beego内置了session模块,目前session模块支持的后端引擎包括memory、file、mysql、redis四中,用户也可以根据相应的interface实现自己的引擎。 603 beego内置了session模块,目前session模块支持的后端引擎包括memory、file、mysql、redis四中,用户也可以根据相应的interface实现自己的引擎。
557 604
558 beego中使用session相当方便,只要在main入口函数中设置如下: 605 beego中使用session相当方便,只要在main入口函数中设置如下:
...@@ -604,21 +651,21 @@ sess撖寡情瘜 ...@@ -604,21 +651,21 @@ sess撖寡情瘜
604 - SessionOn 651 - SessionOn
605 652
606 设置是否开启Session,默认是false,配置文件对应的参数名:sessionon 653 设置是否开启Session,默认是false,配置文件对应的参数名:sessionon
607 654
608 - SessionProvider 655 - SessionProvider
609 656
610 设置Session的引擎,默认是memory,目前支持还有file、mysql、redis等,配置文件对应的参数名:sessionprovider 657 设置Session的引擎,默认是memory,目前支持还有file、mysql、redis等,配置文件对应的参数名:sessionprovider
611 658
612 - SessionName 659 - SessionName
613 660
614 设置cookies的名字,Session默认是保存在用户的浏览器cookies里面的,默认名是beegosessionID,配置文件对应的参数名是:sessionname 661 设置cookies的名字,Session默认是保存在用户的浏览器cookies里面的,默认名是beegosessionID,配置文件对应的参数名是:sessionname
615 662
616 - SessionGCMaxLifetime 663 - SessionGCMaxLifetime
617 664
618 设置Session过期的时间,默认值是3600秒,配置文件对应的参数:sessiongcmaxlifetime 665 设置Session过期的时间,默认值是3600秒,配置文件对应的参数:sessiongcmaxlifetime
619 666
620 - SessionSavePath 667 - SessionSavePath
621 668
622 设置对应file、mysql、redis引擎的保存路径或者链接地址,默认值是空,配置文件对应的参数:sessionsavepath 669 设置对应file、mysql、redis引擎的保存路径或者链接地址,默认值是空,配置文件对应的参数:sessionsavepath
623 670
624 671
...@@ -631,13 +678,15 @@ sess撖寡情瘜 ...@@ -631,13 +678,15 @@ sess撖寡情瘜
631 678
632 beego.SessionProvider = "mysql" 679 beego.SessionProvider = "mysql"
633 beego.SessionSavePath = "username:password@protocol(address)/dbname?param=value" 680 beego.SessionSavePath = "username:password@protocol(address)/dbname?param=value"
634 681
635 当SessionProvider为redis时,SessionSavePath是redis的链接地址,采用了[redigo](https://github.com/garyburd/redigo),如下所示: 682 当SessionProvider为redis时,SessionSavePath是redis的链接地址,采用了[redigo](https://github.com/garyburd/redigo),如下所示:
636 683
637 beego.SessionProvider = "redis" 684 beego.SessionProvider = "redis"
638 beego.SessionSavePath = "127.0.0.1:6379" 685 beego.SessionSavePath = "127.0.0.1:6379"
686
639 687
640 ## Cache设置 688 ## Cache设置
689
641 beego内置了一个cache模块,实现了类似memcache的功能,缓存数据在内存中,主要的使用方法如下: 690 beego内置了一个cache模块,实现了类似memcache的功能,缓存数据在内存中,主要的使用方法如下:
642 691
643 var ( 692 var (
...@@ -649,7 +698,7 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗 ...@@ -649,7 +698,7 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗
649 urllist.Every = 0 //不过期 698 urllist.Every = 0 //不过期
650 urllist.Start() 699 urllist.Start()
651 } 700 }
652 701
653 func (this *ShortController) Post() { 702 func (this *ShortController) Post() {
654 var result ShortResult 703 var result ShortResult
655 longurl := this.Input().Get("longurl") 704 longurl := this.Input().Get("longurl")
...@@ -672,8 +721,8 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗 ...@@ -672,8 +721,8 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗
672 } 721 }
673 this.Data["json"] = result 722 this.Data["json"] = result
674 this.ServeJson() 723 this.ServeJson()
675 } 724 }
676 725
677 上面这个例子演示了如何使用beego的Cache模块,主要是通过`beego.NewBeeCache`初始化一个对象,然后设置过期时间,开启过期检测,在业务逻辑中就可以通过如下的接口进行增删改的操作: 726 上面这个例子演示了如何使用beego的Cache模块,主要是通过`beego.NewBeeCache`初始化一个对象,然后设置过期时间,开启过期检测,在业务逻辑中就可以通过如下的接口进行增删改的操作:
678 727
679 - Get(name string) interface{} 728 - Get(name string) interface{}
...@@ -681,7 +730,9 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗 ...@@ -681,7 +730,9 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗
681 - Delete(name string) (ok bool, err error) 730 - Delete(name string) (ok bool, err error)
682 - IsExist(name string) bool 731 - IsExist(name string) bool
683 732
733
684 ## 安全的Map 734 ## 安全的Map
735
685 我们知道在Go语言里面map是非线程安全的,详细的[atomic_maps](http://golang.org/doc/faq#atomic_maps)。但是我们在平常的业务中经常需要用到线程安全的map,特别是在goroutine的情况下,所以beego内置了一个简单的线程安全的map: 736 我们知道在Go语言里面map是非线程安全的,详细的[atomic_maps](http://golang.org/doc/faq#atomic_maps)。但是我们在平常的业务中经常需要用到线程安全的map,特别是在goroutine的情况下,所以beego内置了一个简单的线程安全的map:
686 737
687 bm := NewBeeMap() 738 bm := NewBeeMap()
...@@ -691,16 +742,16 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗 ...@@ -691,16 +742,16 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗
691 if !bm.Check("astaxie") { 742 if !bm.Check("astaxie") {
692 t.Error("check err") 743 t.Error("check err")
693 } 744 }
694 745
695 if v := bm.Get("astaxie"); v.(int) != 1 { 746 if v := bm.Get("astaxie"); v.(int) != 1 {
696 t.Error("get err") 747 t.Error("get err")
697 } 748 }
698 749
699 bm.Delete("astaxie") 750 bm.Delete("astaxie")
700 if bm.Check("astaxie") { 751 if bm.Check("astaxie") {
701 t.Error("delete err") 752 t.Error("delete err")
702 } 753 }
703 754
704 上面演示了如何使用线程安全的Map,主要的接口有: 755 上面演示了如何使用线程安全的Map,主要的接口有:
705 756
706 - Get(k interface{}) interface{} 757 - Get(k interface{}) interface{}
...@@ -708,7 +759,9 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗 ...@@ -708,7 +759,9 @@ beego蔭鈭銝泌ache璅∪鈭掩隡幟emcache嚗
708 - Check(k interface{}) bool 759 - Check(k interface{}) bool
709 - Delete(k interface{}) 760 - Delete(k interface{})
710 761
762
711 ## 日志处理 763 ## 日志处理
764
712 beego默认有一个初始化的BeeLogger对象输出内容到stdout中,你可以通过如下的方式设置自己的输出: 765 beego默认有一个初始化的BeeLogger对象输出内容到stdout中,你可以通过如下的方式设置自己的输出:
713 766
714 beego.SetLogger(*log.Logger) 767 beego.SetLogger(*log.Logger)
...@@ -717,11 +770,13 @@ beego暺恕銝芸eeLogger撖寡情颲捆stdout銝哨 ...@@ -717,11 +770,13 @@ beego暺恕銝芸eeLogger撖寡情颲捆stdout銝哨
717 770
718 fd,err := os.OpenFile("/var/log/beeapp/beeapp.log", os.O_RDWR|os.O_APPEND, 0644) 771 fd,err := os.OpenFile("/var/log/beeapp/beeapp.log", os.O_RDWR|os.O_APPEND, 0644)
719 if err != nil { 772 if err != nil {
720 beego.Critical("openfile beeapp.log:", err) 773 beego.Critical("openfile beeapp.log:", err)
721 return 774 return
722 } 775 }
723 lg := log.New(fd, "", log.Ldate|log.Ltime) 776 lg := log.New(fd, "", log.Ldate|log.Ltime)
724 beego.SetLogger(lg) 777 beego.SetLogger(lg)
778
779
725 ### 不同级别的log日志函数 780 ### 不同级别的log日志函数
726 781
727 * Trace(v ...interface{}) 782 * Trace(v ...interface{})
...@@ -734,84 +789,96 @@ beego暺恕銝芸eeLogger撖寡情颲捆stdout銝哨 ...@@ -734,84 +789,96 @@ beego暺恕銝芸eeLogger撖寡情颲捆stdout銝哨
734 你可以通过下面的方式设置不同的日志分级: 789 你可以通过下面的方式设置不同的日志分级:
735 790
736 beego.SetLevel(beego.LevelError) 791 beego.SetLevel(beego.LevelError)
737 792
738 当你代码中有很多日志输出之后,如果想上线,但是你不想输出Trace、Debug、Info等信息,那么你可以设置如下: 793 当你代码中有很多日志输出之后,如果想上线,但是你不想输出Trace、Debug、Info等信息,那么你可以设置如下:
739 794
740 beego.SetLevel(beego.LevelWarning) 795 beego.SetLevel(beego.LevelWarning)
741 796
742 这样的话就不会输出小于这个level的日志,日志的排序如下: 797 这样的话就不会输出小于这个level的日志,日志的排序如下:
743 798
744 LevelTrace、LevelDebug、LevelInfo、LevelWarning、 LevelError、LevelCritical 799 LevelTrace、LevelDebug、LevelInfo、LevelWarning、LevelError、LevelCritical
745 800
746 用户可以根据不同的级别输出不同的错误信息,如下例子所示: 801 用户可以根据不同的级别输出不同的错误信息,如下例子所示:
747 802
803
748 ### Examples of log messages 804 ### Examples of log messages
805
749 - Trace 806 - Trace
750 807
751 * "Entered parse function validation block" 808 * "Entered parse function validation block"
752 * "Validation: entered second 'if'" 809 * "Validation: entered second 'if'"
753 * "Dictionary 'Dict' is empty. Using default value" 810 * "Dictionary 'Dict' is empty. Using default value"
811
754 - Debug 812 - Debug
755 813
756 * "Web page requested: http://somesite.com Params='...'" 814 * "Web page requested: http://somesite.com Params='...'"
757 * "Response generated. Response size: 10000. Sending." 815 * "Response generated. Response size: 10000. Sending."
758 * "New file received. Type:PNG Size:20000" 816 * "New file received. Type:PNG Size:20000"
817
759 - Info 818 - Info
819
760 * "Web server restarted" 820 * "Web server restarted"
761 * "Hourly statistics: Requested pages: 12345 Errors: 123 ..." 821 * "Hourly statistics: Requested pages: 12345 Errors: 123 ..."
762 * "Service paused. Waiting for 'resume' call" 822 * "Service paused. Waiting for 'resume' call"
823
763 - Warn 824 - Warn
825
764 * "Cache corrupted for file='test.file'. Reading from back-end" 826 * "Cache corrupted for file='test.file'. Reading from back-end"
765 * "Database 192.168.0.7/DB not responding. Using backup 192.168.0.8/DB" 827 * "Database 192.168.0.7/DB not responding. Using backup 192.168.0.8/DB"
766 * "No response from statistics server. Statistics not sent" 828 * "No response from statistics server. Statistics not sent"
829
767 - Error 830 - Error
831
768 * "Internal error. Cannot process request #12345 Error:...." 832 * "Internal error. Cannot process request #12345 Error:...."
769 * "Cannot perform login: credentials DB not responding" 833 * "Cannot perform login: credentials DB not responding"
834
770 - Critical 835 - Critical
836
771 * "Critical panic received: .... Shutting down" 837 * "Critical panic received: .... Shutting down"
772 * "Fatal error: ... App is shutting down to prevent data corruption or loss" 838 * "Fatal error: ... App is shutting down to prevent data corruption or loss"
773 839
840
774 ### Example 841 ### Example
775 842
776 func internalCalculationFunc(x, y int) (result int, err error) { 843 func internalCalculationFunc(x, y int) (result int, err error) {
777 beego.Debug("calculating z. x:",x," y:",y) 844 beego.Debug("calculating z. x:", x, " y:", y)
778 z := y 845 z := y
779 switch { 846 switch {
780 case x == 3 : 847 case x == 3:
781 beego.Trace("x == 3") 848 beego.Trace("x == 3")
782 panic("Failure.") 849 panic("Failure.")
783 case y == 1 : 850 case y == 1:
784 beego.Trace("y == 1") 851 beego.Trace("y == 1")
785 return 0, errors.New("Error!") 852 return 0, errors.New("Error!")
786 case y == 2 : 853 case y == 2:
787 beego.Trace("y == 2") 854 beego.Trace("y == 2")
788 z = x 855 z = x
789 default : 856 default:
790 beego.Trace("default") 857 beego.Trace("default")
791 z += x 858 z += x
792 } 859 }
793 retVal := z-3 860 retVal := z - 3
794 beego.Debug("Returning ", retVal) 861 beego.Debug("Returning ", retVal)
795 862
796 return retVal, nil 863 return retVal, nil
797 } 864 }
798 865
799 func processInput(input inputData) { 866 func processInput(input inputData) {
800 defer func() { 867 defer func() {
801 if r := recover(); r != nil { 868 if r := recover(); r != nil {
802 beego.Error("Unexpected error occurred: ", r) 869 beego.Error("Unexpected error occurred: ", r)
803 outputs <- outputData{result : 0, error : true} 870 outputs <- outputData{result: 0, error: true}
804 } 871 }
805 }() 872 }()
806 beego.Info("Received input signal. x:",input.x," y:", input.y) 873 beego.Info("Received input signal. x:", input.x, " y:", input.y)
807 874
808 res, err := internalCalculationFunc(input.x, input.y) 875 res, err := internalCalculationFunc(input.x, input.y)
809 if err != nil { 876 if err != nil {
810 beego.Warn("Error in calculation:", err.Error()) 877 beego.Warn("Error in calculation:", err.Error())
811 } 878 }
812 879
813 beego.Info("Returning result: ",res," error: ",err) 880 beego.Info("Returning result: ", res, " error: ", err)
814 outputs <- outputData{result : res, error : err != nil} 881 outputs <- outputData{result: res, error: err != nil}
815 } 882 }
816 883
817 func main() { 884 func main() {
...@@ -828,16 +895,18 @@ LevelTraceevelDebugevelInfoevelWarning LevelErrorevelCritical ...@@ -828,16 +895,18 @@ LevelTraceevelDebugevelInfoevelWarning LevelErrorevelCritical
828 895
829 for { 896 for {
830 select { 897 select {
831 case input := <- inputs: 898 case input := <-inputs:
832 processInput(input) 899 processInput(input)
833 case <- criticalChan: 900 case <-criticalChan:
834 beego.Critical("Caught value from criticalChan: Go shut down.") 901 beego.Critical("Caught value from criticalChan: Go shut down.")
835 panic("Shut down due to critical fault.") 902 panic("Shut down due to critical fault.")
836 } 903 }
837 } 904 }
838 } 905 }
839 906
907
840 ## 配置管理 908 ## 配置管理
909
841 beego支持解析ini文件, beego默认会解析当前应用下的`conf/app.conf`文件 910 beego支持解析ini文件, beego默认会解析当前应用下的`conf/app.conf`文件
842 911
843 通过这个文件你可以初始化很多beego的默认参数 912 通过这个文件你可以初始化很多beego的默认参数
...@@ -849,7 +918,7 @@ beego圾ni辣, beego暺恕隡圾銝conf/app.conf ...@@ -849,7 +918,7 @@ beego圾ni辣, beego暺恕隡圾銝conf/app.conf
849 autorender = false 918 autorender = false
850 autorecover = false 919 autorecover = false
851 viewspath = "myview" 920 viewspath = "myview"
852 921
853 上面这些参数会替换beego默认的一些参数。 922 上面这些参数会替换beego默认的一些参数。
854 923
855 你可以在配置文件中配置应用需要用的一些配置信息,例如下面所示的数据库信息: 924 你可以在配置文件中配置应用需要用的一些配置信息,例如下面所示的数据库信息:
...@@ -858,7 +927,7 @@ beego圾ni辣, beego暺恕隡圾銝conf/app.conf ...@@ -858,7 +927,7 @@ beego圾ni辣, beego暺恕隡圾銝conf/app.conf
858 mysqlpass = "rootpass" 927 mysqlpass = "rootpass"
859 mysqlurls = "127.0.0.1" 928 mysqlurls = "127.0.0.1"
860 mysqldb = "beego" 929 mysqldb = "beego"
861 930
862 那么你就可以通过如下的方式获取设置的配置信息: 931 那么你就可以通过如下的方式获取设置的配置信息:
863 932
864 beego.AppConfig.String("mysqluser") 933 beego.AppConfig.String("mysqluser")
...@@ -874,45 +943,47 @@ AppConfig瘜 ...@@ -874,45 +943,47 @@ AppConfig瘜
874 - Float(key string) (float64, error) 943 - Float(key string) (float64, error)
875 - String(key string) string 944 - String(key string) string
876 945
946
877 ## 系统默认参数 947 ## 系统默认参数
948
878 beego中带有很多可配置的参数,我们来一一认识一下它们,这样有利于我们在接下来的beego开发中可以充分的发挥他们的作用: 949 beego中带有很多可配置的参数,我们来一一认识一下它们,这样有利于我们在接下来的beego开发中可以充分的发挥他们的作用:
879 950
880 * BeeApp 951 * BeeApp
881 952
882 beego默认启动的一个应用器入口,在应用import beego的时候,在init中已经初始化的。 953 beego默认启动的一个应用器入口,在应用import beego的时候,在init中已经初始化的。
883 954
884 * AppConfig 955 * AppConfig
885 956
886 beego的配置文件解析之后的对象,也是在init的时候初始化的,里面保存有解析`conf/app.conf`下面所有的参数数据 957 beego的配置文件解析之后的对象,也是在init的时候初始化的,里面保存有解析`conf/app.conf`下面所有的参数数据
887 958
888 * AppConfigPath 959 * AppConfigPath
889 960
890 配置文件所在的路径,默认是应用程序对应的目录下的`conf/app.conf`,用户可以修改该值配置自己的配置文件 961 配置文件所在的路径,默认是应用程序对应的目录下的`conf/app.conf`,用户可以修改该值配置自己的配置文件
891 962
892 * HttpAddr 963 * HttpAddr
893 964
894 应用监听地址,默认为空,监听所有的网卡IP 965 应用监听地址,默认为空,监听所有的网卡IP
895 966
896 * HttpPort 967 * HttpPort
897 968
898 应用监听端口,默认为8080 969 应用监听端口,默认为8080
899 970
900 * AppName 971 * AppName
901 972
902 应用名称,默认是beego 973 应用名称,默认是beego
903 974
904 * RunMode 975 * RunMode
905 976
906 应用的模式,默认是dev,为开发模式,在开发模式下出错会提示友好的出错页面,如前面错误描述中所述。 977 应用的模式,默认是dev,为开发模式,在开发模式下出错会提示友好的出错页面,如前面错误描述中所述。
907 978
908 * AutoRender 979 * AutoRender
909 980
910 是否模板自动渲染,默认值为true,对于API类型的应用,应用需要把该选项设置为false,不需要渲染模板。 981 是否模板自动渲染,默认值为true,对于API类型的应用,应用需要把该选项设置为false,不需要渲染模板。
911 982
912 * RecoverPanic 983 * RecoverPanic
913 984
914 是否异常恢复,默认值为true,即当应用出现异常的情况,通过recover恢复回来,而不会导致应用异常退出。 985 是否异常恢复,默认值为true,即当应用出现异常的情况,通过recover恢复回来,而不会导致应用异常退出。
915 986
916 * PprofOn 987 * PprofOn
917 988
918 是否启用pprof,默认是false,当开启之后,用户可以通过如下地址查看相应的goroutine执行情况 989 是否启用pprof,默认是false,当开启之后,用户可以通过如下地址查看相应的goroutine执行情况
...@@ -922,48 +993,50 @@ beego銝剖蒂蔭嚗賑銝銝霈方銝賑嚗 ...@@ -922,48 +993,50 @@ beego銝剖蒂蔭嚗賑銝銝霈方銝賑嚗
922 /debug/pprof/profile 993 /debug/pprof/profile
923 /debug/pprof/symbol 994 /debug/pprof/symbol
924 关于pprof的信息,请参考官方的描述[pprof](http://golang.org/pkg/net/http/pprof/) 995 关于pprof的信息,请参考官方的描述[pprof](http://golang.org/pkg/net/http/pprof/)
925 996
926 * ViewsPath 997 * ViewsPath
927 998
928 模板路径,默认值是views 999 模板路径,默认值是views
929 1000
930 * SessionOn 1001 * SessionOn
931 1002
932 session是否开启,默认是false 1003 session是否开启,默认是false
933 1004
934 * SessionProvider 1005 * SessionProvider
935 1006
936 session的引擎,默认是memory 1007 session的引擎,默认是memory
937 1008
938 * SessionName 1009 * SessionName
939 1010
940 存在客户端的cookie名称,默认值是beegosessionID 1011 存在客户端的cookie名称,默认值是beegosessionID
941 1012
942 * SessionGCMaxLifetime 1013 * SessionGCMaxLifetime
943 1014
944 session过期时间,默认值是3600秒 1015 session过期时间,默认值是3600秒
945 1016
946 * SessionSavePath 1017 * SessionSavePath
947 1018
948 session保存路径,默认是空 1019 session保存路径,默认是空
949 1020
950 * UseFcgi 1021 * UseFcgi
951 1022
952 是否启用fastcgi,默认是false 1023 是否启用fastcgi,默认是false
953 1024
954 * MaxMemory 1025 * MaxMemory
955 1026
956 文件上传默认内存缓存大小,默认值是`1 << 26`(64M) 1027 文件上传默认内存缓存大小,默认值是`1 << 26`(64M)
957 1028
958 * EnableGzip 1029 * EnableGzip
959 1030
960 是否开启gzip支持,默认为false不支持gzip,一旦开启了gzip,那么在模板输出的内容会进行gzip或者zlib压缩,根据用户的Accept-Encoding来判断。 1031 是否开启gzip支持,默认为false不支持gzip,一旦开启了gzip,那么在模板输出的内容会进行gzip或者zlib压缩,根据用户的Accept-Encoding来判断。
1032
961 1033
962 ## 第三方应用集成 1034 ## 第三方应用集成
1035
963 beego支持第三方应用的集成,用户可以自定义`http.Handler`,用户可以通过如下方式进行注册路由: 1036 beego支持第三方应用的集成,用户可以自定义`http.Handler`,用户可以通过如下方式进行注册路由:
964 1037
965 beego.RouterHandler("/chat/:info(.*)", sockjshandler) 1038 beego.RouterHandler("/chat/:info(.*)", sockjshandler)
966 1039
967 sockjshandler实现了接口`http.Handler` 1040 sockjshandler实现了接口`http.Handler`
968 1041
969 目前在beego的example中有支持sockjs的chat例子,示例代码如下: 1042 目前在beego的example中有支持sockjs的chat例子,示例代码如下:
...@@ -982,7 +1055,7 @@ sockjshandler摰鈭`http.Handler` ...@@ -982,7 +1055,7 @@ sockjshandler摰鈭`http.Handler`
982 func chatHandler(s sockjs.Session) { 1055 func chatHandler(s sockjs.Session) {
983 users.Add(s) 1056 users.Add(s)
984 defer users.Remove(s) 1057 defer users.Remove(s)
985 1058
986 for { 1059 for {
987 m := s.Receive() 1060 m := s.Receive()
988 if m == nil { 1061 if m == nil {
...@@ -1013,7 +1086,9 @@ sockjshandler摰鈭`http.Handler` ...@@ -1013,7 +1086,9 @@ sockjshandler摰鈭`http.Handler`
1013 1086
1014 通过上面的代码很简单的实现了一个多人的聊天室。上面这个只是一个sockjs的例子,我想通过大家自定义`http.Handler`,可以有很多种方式来进行扩展beego应用。 1087 通过上面的代码很简单的实现了一个多人的聊天室。上面这个只是一个sockjs的例子,我想通过大家自定义`http.Handler`,可以有很多种方式来进行扩展beego应用。
1015 1088
1089
1016 ## 部署编译应用 1090 ## 部署编译应用
1091
1017 Go语言的应用最后编译之后是一个二进制文件,你只需要copy这个应用到服务器上,运行起来就行。beego由于带有几个静态文件、配置文件、模板文件三个目录,所以用户部署的时候需要同时copy这三个目录到相应的部署应用之下,下面以我实际的应用部署为例: 1092 Go语言的应用最后编译之后是一个二进制文件,你只需要copy这个应用到服务器上,运行起来就行。beego由于带有几个静态文件、配置文件、模板文件三个目录,所以用户部署的时候需要同时copy这三个目录到相应的部署应用之下,下面以我实际的应用部署为例:
1018 1093
1019 $ mkdir /opt/app/beepkg 1094 $ mkdir /opt/app/beepkg
...@@ -1021,7 +1096,7 @@ Go霂剛銝銝芯辣嚗閬opy餈 ...@@ -1021,7 +1096,7 @@ Go霂剛銝銝芯辣嚗閬opy餈
1021 $ cp -fr views /opt/app/beepkg 1096 $ cp -fr views /opt/app/beepkg
1022 $ cp -fr static /opt/app/beepkg 1097 $ cp -fr static /opt/app/beepkg
1023 $ cp -fr conf /opt/app/beepkg 1098 $ cp -fr conf /opt/app/beepkg
1024 1099
1025 这样在`/opt/app/beepkg`目录下面就会显示如下的目录结构: 1100 这样在`/opt/app/beepkg`目录下面就会显示如下的目录结构:
1026 1101
1027 . 1102 .
...@@ -1033,12 +1108,12 @@ Go霂剛銝銝芯辣嚗閬opy餈 ...@@ -1033,12 +1108,12 @@ Go霂剛銝銝芯辣嚗閬opy餈
1033 │ └── js 1108 │ └── js
1034 └── views 1109 └── views
1035 └── index.tpl 1110 └── index.tpl
1036 ├── beepkg 1111 ├── beepkg
1037 1112
1038 这样我们就已经把我们需要的应用搬到服务器了,那么接下来就可以开始部署了,我现在服务器端用两种方式来run, 1113 这样我们就已经把我们需要的应用搬到服务器了,那么接下来就可以开始部署了,我现在服务器端用两种方式来run,
1039 1114
1040 - Supervisord 1115 - Supervisord
1041 1116
1042 安装和配置见[Supervisord](Supervisord.md) 1117 安装和配置见[Supervisord](Supervisord.md)
1043 1118
1044 - nohup方式 1119 - nohup方式
......
...@@ -18,22 +18,23 @@ beego是一个类似tornado的Go应用框架,采用了RESTFul的方式来实 ...@@ -18,22 +18,23 @@ beego是一个类似tornado的Go应用框架,采用了RESTFul的方式来实
18 package main 18 package main
19 19
20 import ( 20 import (
21 "github.com/astaxie/beego" 21 "github.com/astaxie/beego"
22 ) 22 )
23 23
24 type MainController struct { 24 type MainController struct {
25 beego.Controller 25 beego.Controller
26 } 26 }
27 27
28 func (this *MainController) Get() { 28 func (this *MainController) Get() {
29 this.Ctx.WriteString("hello world") 29 this.Ctx.WriteString("hello world")
30 } 30 }
31 31
32 func main() { 32 func main() {
33 beego.Router("/", &MainController{}) 33 beego.Router("/", &MainController{})
34 beego.Run() 34 beego.Run()
35 } 35 }
36 36
37
37 # beego 指南 38 # beego 指南
38 39
39 * [为什么设计beego](Why.md) 40 * [为什么设计beego](Why.md)
...@@ -43,8 +44,9 @@ beego是一个类似tornado的Go应用框架,采用了RESTFul的方式来实 ...@@ -43,8 +44,9 @@ beego是一个类似tornado的Go应用框架,采用了RESTFul的方式来实
43 * [beego案例](Application.md) 44 * [beego案例](Application.md)
44 * [热升级](HotUpdate.md) 45 * [热升级](HotUpdate.md)
45 46
47
46 # API接口 48 # API接口
47 49
48 API对于我们平时开发应用非常有用,用于查询一些开发的函数,godoc做的非常好了 50 API对于我们平时开发应用非常有用,用于查询一些开发的函数,godoc做的非常好了
49 51
50 [Go Walker](http://gowalker.org/github.com/astaxie/beego)
...\ No newline at end of file ...\ No newline at end of file
52 [Go Walker](http://gowalker.org/github.com/astaxie/beego)
......
...@@ -3,20 +3,20 @@ ...@@ -3,20 +3,20 @@
3 1. setuptools安装 3 1. setuptools安装
4 4
5 wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg 5 wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
6 6
7 sh setuptools-0.6c11-py2.7.egg 7 sh setuptools-0.6c11-py2.7.egg
8 8
9 easy_install supervisor 9 easy_install supervisor
10 10
11 echo_supervisord_conf >/etc/supervisord.conf 11 echo_supervisord_conf >/etc/supervisord.conf
12 12
13 mkdir /etc/supervisord.conf.d 13 mkdir /etc/supervisord.conf.d
14 14
15 2. 修改配置/etc/supervisord.conf 15 2. 修改配置/etc/supervisord.conf
16 16
17 [include] 17 [include]
18 files = /etc/supervisord.conf.d/*.conf 18 files = /etc/supervisord.conf.d/*.conf
19 19
20 3. 新建管理的应用 20 3. 新建管理的应用
21 21
22 cd /etc/supervisord.conf.d 22 cd /etc/supervisord.conf.d
...@@ -31,4 +31,4 @@ ...@@ -31,4 +31,4 @@
31 startsecs = 5 31 startsecs = 5
32 user = root 32 user = root
33 redirect_stderr = true 33 redirect_stderr = true
34 stdout_logfile = /var/log/supervisord/beepkg.log
...\ No newline at end of file ...\ No newline at end of file
34 stdout_logfile = /var/log/supervisord/beepkg.log
......
1 # 一步一步跟我写博客 1 # 一步一步跟我写博客
2 2
3
3 ## 创建项目 4 ## 创建项目
4 5
6
5 ## 数据库结构设计 7 ## 数据库结构设计
6 8
9
7 ## 控制器设计 10 ## 控制器设计
8 11
12
9 ## 模板设计 13 ## 模板设计
10 14
15
11 ## 用户登陆退出 16 ## 用户登陆退出
12 17
13 ## 数据库操作
...\ No newline at end of file ...\ No newline at end of file
18
19 ## 数据库操作
......
...@@ -17,4 +17,4 @@ ...@@ -17,4 +17,4 @@
17 整个的MVC逻辑中C是最重要的部分,这一块采用了我上面说的接口方式,M模块目前我还没想好怎么做,但是大家可以参考我的另一个开源项目beedb来实现数据的管理,V这一块目前采用了Go语言自带的模板引擎,但是实现了很多方便的模板函数。这样一个简易的框架就完成了,然后我就不断的完善周边的功能,包括表单处理、session处理、日志处理、配置处理、自动化运行等功能。 17 整个的MVC逻辑中C是最重要的部分,这一块采用了我上面说的接口方式,M模块目前我还没想好怎么做,但是大家可以参考我的另一个开源项目beedb来实现数据的管理,V这一块目前采用了Go语言自带的模板引擎,但是实现了很多方便的模板函数。这样一个简易的框架就完成了,然后我就不断的完善周边的功能,包括表单处理、session处理、日志处理、配置处理、自动化运行等功能。
18 18
19 - [beego介绍](README.md) 19 - [beego介绍](README.md)
20 - [安装入门](Install.md)
...\ No newline at end of file ...\ No newline at end of file
20 - [安装入门](Install.md)
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!