diff --git a/README.md b/README.md index c42cf4a6..6ad35ada 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://drone.io/github.com/astaxie/beego/status.png)](https://drone.io/github.com/astaxie/beego/latest) -beego is a Go Framework which is inspired from tornado and sinatra. +beego is a Go Framework which is inspired from tornado and sinatra. It is a simply & powerful web framework. @@ -24,12 +24,13 @@ Have this features: [中文文档](https://github.com/astaxie/beego/tree/master/docs/zh) + ## LICENSE beego is licensed under the Apache Licence, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html). + ## Use Case - API documentation [gowalker](https://github.com/Unknwon/gowalker) - CMS [toropress](https://github.com/insionng/toropress) - diff --git a/docs/en/HotUpdate.md b/docs/en/HotUpdate.md index b1c82bd5..91bd6a49 100644 --- a/docs/en/HotUpdate.md +++ b/docs/en/HotUpdate.md @@ -1,10 +1,15 @@ -##What is hot update? +## What is hot update? + 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. -##Is hot update necessary? + +## Is hot update necessary? + 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. -##How Beego support hot update? + +## How Beego support hot update? + 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. 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 Above are three problems that we need to solve, you can see my code logic for specific implementation. -##Show time + +## Show time 1. Write code in your Get method: @@ -26,15 +32,15 @@ Above are three problems that we need to solve, you can see my code logic for sp } 2. Open two terminals: - + One execute: ` ps -ef|grep ` - - Another one execute:`curl "http://127.0.0.1:8080/?sleep=20"` - + + Another one execute: `curl "http://127.0.0.1:8080/?sleep=20"` + 3. Hot update `kill -HUP ` - -4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"` -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 +4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"` + +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. diff --git a/docs/en/Install.md b/docs/en/Install.md index cb76e560..f51db397 100644 --- a/docs/en/Install.md +++ b/docs/en/Install.md @@ -1,25 +1,26 @@ -#Installation +# Installation + Beego is a simple web framework, but it uses many third-party packages, so you have to install all dependency packages also. - 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) -- Use `go get ` to install Beego: +- Use `go get ` to install Beego: go get github.com/astaxie/beego - -- Install bee tools for fast-develop Beego applications: - go get github.com/astaxie/bee +- Install bee tools for fast-develop Beego applications: -Good job, you're ready to Beego with powerful bee tools! + go get github.com/astaxie/bee + +Good job, you're ready to Beego with powerful bee tools! ![](images/bee.png) Beego has following dependency packages: -- Session module: [github.com/astaxie/beego/session](github.com/astaxie/beego/session) -- To support redis engine: [github.com/garyburd/redigo/redis](github.com/garyburd/redigo/redis) -- To support mysql engine: [github.com/go-sql-driver/mysql](github.com/go-sql-driver/mysql) -- To support markdown as template function: [github.com/russross/blackfriday](github.com/russross/blackfriday) +- Session module: [github.com/astaxie/beego/session](https://github.com/astaxie/beego/session) +- To support redis engine: [github.com/garyburd/redigo/redis](https://github.com/garyburd/redigo/redis) +- To support mysql engine: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) +- To support markdown as template function: [github.com/russross/blackfriday](https://github.com/russross/blackfriday) - [Introduction](README.md) -- [Quick start](Quickstart.md) \ No newline at end of file +- [Quick start](Quickstart.md) diff --git a/docs/en/Quickstart.md b/docs/en/Quickstart.md index 9aa04cb0..4af1fe67 100644 --- a/docs/en/Quickstart.md +++ b/docs/en/Quickstart.md @@ -1,4 +1,5 @@ # Quick start + 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) **Navigation** @@ -23,11 +24,13 @@ Hey, you say you've never heard about Beego and don't know how to use it? Don't - [Integrated third-party applications](#integrated-third-party-applications) - [Deployment](#deployment) + ## Hello world + This is an example of "Hello world" in Beego: package main - + import ( "github.com/astaxie/beego" ) @@ -54,18 +57,25 @@ Open address [http://127.0.0.1:8080](http://127.0.0.1:8080) in your browser and What happened in behind above example? -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. +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. + 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. + 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`. + 4. Define main function. All applications in Go use main function as entry point as C does. + 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. + 6. Run application in port 8080 as default, press `Ctrl+c` to exit. + ## New project + Get into your $GOPATH, then use following command to setup Beego project: bee create hello - + 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: └── views └── index.tpl + ## Development mode + Beego uses development mode as default, you can use following code to change mode in your application: beego.RunMode = "pro" @@ -95,7 +107,7 @@ No differences between two ways. In development mode, you have following effects: -- If you don't have directory `views`, it prints following error prompt: +- If you don't have directory `views`, it prints following error prompt: 2013/04/13 19:36:17 [W] [stat views: no such file or directory] @@ -104,7 +116,9 @@ In development mode, you have following effects: ![](images/dev.png) + ## Router + 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: type ControllerInterface interface { @@ -132,39 +146,41 @@ Users can use following ways to register route rules: For more convenient configure route rules, Beego references the idea from sinatra, so it supports more kinds of route rules as follows: -- beego.Router("/api/:id([0-9]+)", &controllers.RController{}) +- beego.Router("/api/:id([0-9]+)", &controllers.RController{}) - Customized regular expression match // match /api/123 :id= 123 + Customized regular expression match // match /api/123 :id= 123 + +- beego.Router("/news/:all", &controllers.RController{}) -- beego.Router("/news/:all", &controllers.RController{}) - Match rest of all // match /news/path/to/123.html :all= path/to/123.html - -- beego.Router("/user/:username([\w]+)", &controllers.RController{}) + +- beego.Router("/user/:username([\w]+)", &controllers.RController{}) Regular expression // match /user/astaxie :username = astaxie - -- beego.Router("/download/`*`.`*`", &controllers.RController{}) + +- beego.Router("/download/`*`.`*`", &controllers.RController{}) Wildcard character // match /download/file/api.xml :path= file/api :ext=xml - -- beego.Router("/download/ceshi/`*`", &controllers.RController{}) + +- beego.Router("/download/ceshi/`*`", &controllers.RController{}) wildcard character match rest of all // match /download/ceshi/file/api.json :splat=file/api.json - -- beego.Router("/:id:int", &controllers.RController{}) + +- beego.Router("/:id:int", &controllers.RController{}) Match type int // match :id is int type, Beego uses regular expression ([0-9]+) automatically - -- beego.Router("/:hi:string", &controllers.RController{}) + +- beego.Router("/:hi:string", &controllers.RController{}) Match type string // match :hi is string type, Beego uses regular expression ([\w]+) automatically -##Static files + +## Static files + Go provides `http.ServeFile` for static files, Beego wrapped this function and use following way to register static file folder: beego.SetStaticPath("/static","public") - + - The first argument is the path of your URL. - The second argument is the directory in your application path. @@ -176,37 +192,41 @@ Beego supports multiple static file directories as follows: 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`. -##Filter and middleware + +## Filter and middleware + Beego supports customized filter and middleware, such as security verification, force redirect, etc. Here is an example of verify user name of all requests, check if it's admin. var FilterUser = func(w http.ResponseWriter, r *http.Request) { - if r.URL.User == nil || r.URL.User.Username() != "admin" { - http.Error(w, "", http.StatusUnauthorized) - } + if r.URL.User == nil || r.URL.User.Username() != "admin" { + http.Error(w, "", http.StatusUnauthorized) + } } - - beego.Filter(FilterUser) + beego.Filter(FilterUser) + You can also filter by arguments: beego.Router("/:id([0-9]+)", &admin.EditController{}) beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) { - dosomething() + dosomething() }) - + Filter by prefix is also available: beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) { - dosomething() + dosomething() }) -##Controller + +## Controller + Use `beego.controller` as anonymous in your controller struct to implement the interface in Beego: type xxxController struct { - beego.Controller + beego.Controller } `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 - Init(ct `*`Context, cn string) Initialize context, controller's name, template's name, and container of template arguments - + - Prepare() This is for expend usages, it executes before all the following methods. Users can overload this method for verification for example. - + - Get() 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. - + - Post() 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 Overload all methods for all customized logic processes, let's see an example: type AddController struct { - beego.Controller + beego.Controller } func (this *AddController) Prepare() { @@ -266,54 +286,64 @@ Overload all methods for all customized logic processes, let's see an example: } func (this *AddController) Get() { - this.Data["content"] ="value" - this.Layout = "admin/layout.html" - this.TplNames = "admin/add.tpl" + this.Data["content"] = "value" + this.Layout = "admin/layout.html" + this.TplNames = "admin/add.tpl" } func (this *AddController) Post() { - pkgname := this.GetString("pkgname") - content := this.GetString("content") - pk := models.GetCruPkg(pkgname) - if pk.Id == 0 { - var pp models.PkgEntity - pp.Pid = 0 - pp.Pathname = pkgname - pp.Intro = pkgname - models.InsertPkg(pp) - pk = models.GetCruPkg(pkgname) - } - var at models.Article - at.Pkgid = pk.Id - at.Content = content - models.InsertArticle(at) - this.Ctx.Redirect(302, "/admin/index") - } + pkgname := this.GetString("pkgname") + content := this.GetString("content") + pk := models.GetCruPkg(pkgname) + if pk.Id == 0 { + var pp models.PkgEntity + pp.Pid = 0 + pp.Pathname = pkgname + pp.Intro = pkgname + models.InsertPkg(pp) + pk = models.GetCruPkg(pkgname) + } + var at models.Article + at.Pkgid = pk.Id + at.Content = content + models.InsertArticle(at) + this.Ctx.Redirect(302, "/admin/index") + } + + +## Template + + +### Template directory -##Template -###Template directory 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: beego.ViewsPath = "/myviewpath" -###Auto-render + +### Auto-render + 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. To disable auto-render in configuration file: - + autorender = false To disable auto-render in `main.go`(before you call `beego.Run()` to run the application): beego.AutoRender = false - -###Template data + + +### Template data + 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: - + this.Data["Context"] = "value" - -###Template name -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)。 + + +### Template name + +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). 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: @@ -329,16 +359,18 @@ If you enabled auto-render and you don't tell Beego which template file you are Which is `/.