From d0e41a94686f333866c6943387273fc6f232ced5 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 9 Mar 2024 05:10:15 +0800 Subject: [PATCH] README --- README.md | 89 +++++++++++++--------------- classfile_v2.go | 2 +- demo/classfile2_blog/get.yap | 1 + demo/classfile2_blog/gop_autogen.go | 26 +++++++- demo/classfile2_blog/main.yap | 1 + demo/classfile2_hello/get.yap | 2 +- demo/classfile2_hello/gop_autogen.go | 2 +- demo/classfile_blog/blog_yap.gox | 5 +- demo/classfile_blog/gop_autogen.go | 7 ++- demo/classfile_hello/gop_autogen.go | 14 ++--- demo/classfile_hello/main.yap | 8 +-- yap.go | 7 ++- 12 files changed, 97 insertions(+), 67 deletions(-) create mode 100644 demo/classfile2_blog/get.yap create mode 100644 demo/classfile2_blog/main.yap diff --git a/README.md b/README.md index ca01b79..834cd7b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ yap - Yet Another Go/Go+ HTTP Web Framework This repo contains three [Go+ classfiles](https://github.com/goplus/gop/blob/main/doc/classfile.md): `yap` (a HTTP Web Framework), `yaptest` (a HTTP Test Framework) and `ydb` (a Go+ Database Framework). -The classfile `yap` has the file suffix `_yap.gox`. The classfile `yaptest` has the file suffix `_ytest.gox`. And the classfile `ydb` has the file suffix `_ydb.gox`. +The classfile `yap` has the file suffix `.yap`. The classfile `yaptest` has the file suffix `_ytest.gox`. And the classfile `ydb` has the file suffix `_ydb.gox`. Before using `yap`, `yaptest` or `ydb`, you need to add `github.com/goplus/yap` to `go.mod`: @@ -17,7 +17,7 @@ Before using `yap`, `yaptest` or `ydb`, you need to add `github.com/goplus/yap` gop get github.com/goplus/yap@latest ``` -For more details, see [YAP Web Framework Manual](doc/manual.md). +For more details, see [YAP Framework Manual](doc/manual.md). ### How to use in Go+ @@ -33,90 +33,82 @@ Then we have it reference a classfile called `yap` as the HTTP Web Framework: gop get github.com/goplus/yap@latest ``` -We can use it to implement a static file server: +Create a file named [get.yap](demo/classfile2_hello/get.yap) with the following content: ```coffee -static "/foo", FS("public") -static "/" # Equivalent to static "/", FS("static") - -run ":8080" -``` - -We can also add the ability to handle dynamic GET/POST requests: - -```coffee -static "/foo", FS("public") -static "/" # Equivalent to static "/", FS("static") - -get "/p/:id", ctx => { - ctx.json { - "id": ctx.param("id"), - } -} - -run ":8080" +html `Hello, YAP!` ``` -Save this code to `hello_yap.gox` file and execute: +Execute the following commands: ```sh -mkdir -p yap/static yap/public # Static resources can be placed in these directories gop mod tidy gop run . ``` -A simplest web program is running now. At this time, if you visit http://localhost:8080/p/123, you will get: +A simplest web program is running now. At this time, if you visit http://localhost:8080, you will get: ``` -{"id":"123"} +Hello, YAP! ``` + ### yap: HTTP Web Framework -This classfile has the file suffix `_yap.gox`. +This classfile has the file suffix `.yap`. + #### Router and Parameters -demo in Go+ classfile ([hello_yap.gox](demo/classfile_hello/hello_yap.gox)): +YAP uses filenames to define routes. `get.yap`'s route is `get "/"` (GET homepage), and `get_p_#id.yap`'s route is `get "/p/:id"` (In fact, the filename can also be `get_p_:id.yap`, but it is not recommended because `:` is not allowed to exist in filenames under Windows). + +Let's create a file named [get_p_#id.yap](demo/classfile2_hello/get_p_%23id.yap) with the following content: ```coffee -get "/p/:id", ctx => { - ctx.json { - "id": ctx.param("id"), - } -} -handle "/", ctx => { - ctx.html `Hello, Yap!` +json { + "id": param("id"), } +``` -run ":8080" +Execute `gop run .` and visit http://localhost:8080/p/123, you will get: + +``` +{"id": "123"} ``` -#### Static files -Static files server demo in Go+ classfile ([staticfile_yap.gox](demo/classfile_static/staticfile_yap.gox)): +#### YAP Template + +In most cases, we will not use the `html` directive to return a html page, but use the yap template. See [get_p_#id.yap](demo/classfile2_blog/get_p_%23id.yap): ```coffee -static "/foo", FS("public") -static "/" +yap "article", { + "id": param("id"), +} +``` -run ":8080" + +### Run at specified address + +By default the YAP server runs on `localhost:8080`, but you can change it in [main.yap](demo/classfile2_blog/main.yap) file: + +```coffee +run ":8888" ``` -#### YAP Template -demo in Go+ classfile ([blog_yap.gox](demo/classfile_blog/blog_yap.gox), [article_yap.html](demo/classfile_blog/yap/article_yap.html)): +#### Static files + +Static files server demo ([main.yap](demo/classfile2_static/main.yap)): ```coffee -get "/p/:id", ctx => { - ctx.yap "article", { - "id": ctx.param("id"), - } -} +static "/foo", FS("public") +static "/" run ":8080" ``` + ### yaptest: HTTP Test Framework This classfile has the file suffix `_ytest.gox`. @@ -169,6 +161,7 @@ The directive `testServer` creates the `foo` server by [net/http/httptest](https For more details, see [yaptest - Go+ HTTP Test Framework](ytest). + ### ydb: Database Framework This classfile has the file suffix `_ydb.gox`. diff --git a/classfile_v2.go b/classfile_v2.go index 3409896..e4cd146 100644 --- a/classfile_v2.go +++ b/classfile_v2.go @@ -65,6 +65,6 @@ func Gopt_AppV2_Main(app AppType, handlers ...iHandler) { if me, ok := app.(interface{ MainEntry() }); ok { me.MainEntry() } else { - app.Run(":8080") + app.Run("localhost:8080") } } diff --git a/demo/classfile2_blog/get.yap b/demo/classfile2_blog/get.yap new file mode 100644 index 0000000..f24522e --- /dev/null +++ b/demo/classfile2_blog/get.yap @@ -0,0 +1 @@ +html `Hello, YAP!` diff --git a/demo/classfile2_blog/gop_autogen.go b/demo/classfile2_blog/gop_autogen.go index 84a4161..2c6acfa 100644 --- a/demo/classfile2_blog/gop_autogen.go +++ b/demo/classfile2_blog/gop_autogen.go @@ -6,12 +6,34 @@ import "github.com/goplus/yap" const _ = true +type get struct { + yap.Handler + *AppV2 +} type get_p_id struct { yap.Handler + *AppV2 +} +type AppV2 struct { + yap.AppV2 +} +//line demo/classfile2_blog/main.yap:1 +func (this *AppV2) MainEntry() { +//line demo/classfile2_blog/main.yap:1:1 + this.Run(":8888") } - func main() { - yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_id)) + yap.Gopt_AppV2_Main(new(AppV2), new(get), new(get_p_id)) +} +//line demo/classfile2_blog/get.yap:1 +func (this *get) Main(_gop_arg0 *yap.Context) { +//line demo/classfile2_blog/main.yap:1:1 + this.Handler.Main(_gop_arg0) +//line demo/classfile2_blog/get.yap:1:1 + this.Html__1(`Hello, YAP!`) +} +func (this *get) Classfname() string { + return "get" } //line demo/classfile2_blog/get_p_#id.yap:1 func (this *get_p_id) Main(_gop_arg0 *yap.Context) { diff --git a/demo/classfile2_blog/main.yap b/demo/classfile2_blog/main.yap new file mode 100644 index 0000000..0c14db1 --- /dev/null +++ b/demo/classfile2_blog/main.yap @@ -0,0 +1 @@ +run ":8888" diff --git a/demo/classfile2_hello/get.yap b/demo/classfile2_hello/get.yap index 79f1936..19b9469 100644 --- a/demo/classfile2_hello/get.yap +++ b/demo/classfile2_hello/get.yap @@ -1 +1 @@ -html `Hello, Yap!` +html `Hello, YAP!` diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go index a05e04f..9c90c18 100644 --- a/demo/classfile2_hello/gop_autogen.go +++ b/demo/classfile2_hello/gop_autogen.go @@ -20,7 +20,7 @@ func main() { func (this *get) Main(_gop_arg0 *yap.Context) { this.Handler.Main(_gop_arg0) //line demo/classfile2_hello/get.yap:1:1 - this.Html__1(`Hello, Yap!`) + this.Html__1(`Hello, YAP!`) } func (this *get) Classfname() string { return "get" diff --git a/demo/classfile_blog/blog_yap.gox b/demo/classfile_blog/blog_yap.gox index 894fe66..8f834c0 100644 --- a/demo/classfile_blog/blog_yap.gox +++ b/demo/classfile_blog/blog_yap.gox @@ -3,5 +3,8 @@ get "/p/:id", ctx => { "id": ctx.param("id"), } } +get "/", ctx => { + ctx.html `Hello, YAP!` +} -run ":8080" +run ":8888" diff --git a/demo/classfile_blog/gop_autogen.go b/demo/classfile_blog/gop_autogen.go index a42ea2d..798a163 100644 --- a/demo/classfile_blog/gop_autogen.go +++ b/demo/classfile_blog/gop_autogen.go @@ -16,8 +16,13 @@ func (this *blog) MainEntry() { //line demo/classfile_blog/blog_yap.gox:2:1 ctx.Yap__1("article", map[string]string{"id": ctx.Param("id")}) }) +//line demo/classfile_blog/blog_yap.gox:6:1 + this.Get("/", func(ctx *yap.Context) { //line demo/classfile_blog/blog_yap.gox:7:1 - this.Run(":8080") + ctx.Html__1(`Hello, YAP!`) + }) +//line demo/classfile_blog/blog_yap.gox:10:1 + this.Run(":8888") } func main() { yap.Gopt_App_Main(new(blog)) diff --git a/demo/classfile_hello/gop_autogen.go b/demo/classfile_hello/gop_autogen.go index aa7f026..c8aa50a 100644 --- a/demo/classfile_hello/gop_autogen.go +++ b/demo/classfile_hello/gop_autogen.go @@ -12,17 +12,17 @@ type AppV2 struct { //line demo/classfile_hello/main.yap:1 func (this *AppV2) MainEntry() { //line demo/classfile_hello/main.yap:1:1 - this.Get("/p/:id", func(ctx *yap.Context) { + this.Get("/", func(ctx *yap.Context) { //line demo/classfile_hello/main.yap:2:1 - ctx.Json__1(map[string]string{"id": ctx.Param("id")}) + ctx.Html__1(`Hello, YAP!`) }) -//line demo/classfile_hello/main.yap:6:1 - this.Handle("/", func(ctx *yap.Context) { -//line demo/classfile_hello/main.yap:7:1 - ctx.Html__1(`Hello, Yap!`) +//line demo/classfile_hello/main.yap:4:1 + this.Get("/p/:id", func(ctx *yap.Context) { +//line demo/classfile_hello/main.yap:5:1 + ctx.Json__1(map[string]string{"id": ctx.Param("id")}) }) //line demo/classfile_hello/main.yap:10:1 - this.Run(":8080") + this.Run("localhost:8080") } func main() { yap.Gopt_AppV2_Main(new(AppV2)) diff --git a/demo/classfile_hello/main.yap b/demo/classfile_hello/main.yap index d8ad6c5..55a2b69 100644 --- a/demo/classfile_hello/main.yap +++ b/demo/classfile_hello/main.yap @@ -1,10 +1,10 @@ +get "/", ctx => { + ctx.html `Hello, YAP!` +} get "/p/:id", ctx => { ctx.json { "id": ctx.param("id"), } } -handle "/", ctx => { - ctx.html `Hello, Yap!` -} -run ":8080" +run "localhost:8080" diff --git a/yap.go b/yap.go index e177825..73b85b4 100644 --- a/yap.go +++ b/yap.go @@ -140,7 +140,12 @@ func (p *Engine) Handler(mws ...func(h http.Handler) http.Handler) http.Handler // Accepted connections are configured to enable TCP keep-alives. func (p *Engine) Run(addr string, mws ...func(h http.Handler) http.Handler) error { h := p.Handler(mws...) - return p.las(addr, h) + log.Println("Listen", addr) + err := p.las(addr, h) + if err != nil { + log.Println(err) + } + return err } // SetLAS sets listenAndServe func to listens on the TCP network address addr