modify
Showing
7 changed files
with
313 additions
and
3 deletions
| 1 | package beego | 1 | package beego |
| 2 | 2 | ||
| 3 | import "fmt" | 3 | import "./core" |
| 4 | 4 | ||
| 5 | func main(){ | 5 | type C struct { |
| 6 | fmt.Printf("hello world") | 6 | core.Content |
| 7 | } | ||
| 8 | |||
| 9 | type M struct{ | ||
| 10 | core.Model | ||
| 11 | } | ||
| 12 | |||
| 13 | type D struct{ | ||
| 14 | core.Config | ||
| 15 | } | ||
| 16 | |||
| 17 | type U struct{ | ||
| 18 | core.URL | ||
| 19 | } | ||
| 20 | |||
| 21 | type A struct{ | ||
| 22 | core.Controller | ||
| 23 | } | ||
| 24 | |||
| 25 | type V struct{ | ||
| 26 | core.View | ||
| 7 | } | 27 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | package beego | ||
| 2 | |||
| 3 | // Interface for controller types that handle requests | ||
| 4 | type Controller interface { | ||
| 5 | |||
| 6 | // When implemented, handles the request | ||
| 7 | HandleRequest(c *Context) | ||
| 8 | } | ||
| 9 | |||
| 10 | // The ControllerFunc type is an adapter to allow the use of | ||
| 11 | // ordinary functions as goweb handlers. If f is a function | ||
| 12 | // with the appropriate signature, ControllerFunc(f) is a | ||
| 13 | // Controller object that calls f. | ||
| 14 | type ControllerFunc func(*Context) | ||
| 15 | |||
| 16 | // HandleRequest calls f(c). | ||
| 17 | func (f ControllerFunc) HandleRequest(c *Context) { | ||
| 18 | f(c) | ||
| 19 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | package beego | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "regexp" | ||
| 5 | "strings" | ||
| 6 | ) | ||
| 7 | |||
| 8 | /* | ||
| 9 | Route | ||
| 10 | */ | ||
| 11 | |||
| 12 | // Represents a single route mapping | ||
| 13 | type Route struct { | ||
| 14 | pattern string | ||
| 15 | parameterKeys ParameterKeyMap | ||
| 16 | extension string | ||
| 17 | Path string | ||
| 18 | Controller Controller | ||
| 19 | MatcherFuncs []RouteMatcherFunc | ||
| 20 | } | ||
| 21 | |||
| 22 | func (r *Route) String() string { | ||
| 23 | return "{Route:'" + r.Path + "'}" | ||
| 24 | } | ||
| 25 | |||
| 26 | // Makes a new route from the given path | ||
| 27 | func makeRouteFromPath(path string) *Route { | ||
| 28 | |||
| 29 | // get the path segments | ||
| 30 | segments := getPathSegments(path) | ||
| 31 | regexSegments := make([]string, len(segments)) | ||
| 32 | |||
| 33 | // prepare the parameter key map | ||
| 34 | var paramKeys ParameterKeyMap = make(ParameterKeyMap) | ||
| 35 | |||
| 36 | var extension string | ||
| 37 | |||
| 38 | // pull out any dynamic segments | ||
| 39 | for index, _ := range segments { | ||
| 40 | |||
| 41 | if isDynamicSegment(segments[index]) { | ||
| 42 | |||
| 43 | // e.g. {id} | ||
| 44 | |||
| 45 | paramKeys[strings.Trim(segments[index], "{}")] = index | ||
| 46 | regexSegments[index] = ROUTE_REGEX_PLACEHOLDER | ||
| 47 | |||
| 48 | } else if isExtensionSegment(segments[index]) { | ||
| 49 | |||
| 50 | // e.g. .json | ||
| 51 | extension = segments[index] | ||
| 52 | |||
| 53 | // trim off the last space (we don't need it) | ||
| 54 | regexSegments = regexSegments[0 : len(regexSegments)-1] | ||
| 55 | |||
| 56 | } else { | ||
| 57 | |||
| 58 | // e.g. "groups" | ||
| 59 | |||
| 60 | regexSegments[index] = segments[index] | ||
| 61 | |||
| 62 | } | ||
| 63 | |||
| 64 | } | ||
| 65 | |||
| 66 | patternString := "/" + strings.Join(regexSegments, "/") | ||
| 67 | |||
| 68 | // return a new route | ||
| 69 | var route *Route = new(Route) | ||
| 70 | route.pattern = patternString | ||
| 71 | route.extension = extension | ||
| 72 | route.parameterKeys = paramKeys | ||
| 73 | route.Path = path | ||
| 74 | route.Controller = nil | ||
| 75 | return route | ||
| 76 | |||
| 77 | } | ||
| 78 | |||
| 79 | // Gets the parameter values for the route from the specified path | ||
| 80 | func (route *Route) getParameterValueMap(path string) ParameterValueMap { | ||
| 81 | return getParameterValueMap(route.parameterKeys, path) | ||
| 82 | } | ||
| 83 | |||
| 84 | // Checks whether a path matches a route or not | ||
| 85 | func (route *Route) DoesMatchPath(path string) bool { | ||
| 86 | |||
| 87 | match, error := regexp.MatchString(route.pattern, path) | ||
| 88 | |||
| 89 | if error == nil { | ||
| 90 | if match { | ||
| 91 | |||
| 92 | if len(route.extension) > 0 { | ||
| 93 | |||
| 94 | // make sure the extensions match too | ||
| 95 | return strings.HasSuffix(strings.ToLower(path), strings.ToLower(route.extension)) | ||
| 96 | |||
| 97 | } else { | ||
| 98 | return match | ||
| 99 | } | ||
| 100 | |||
| 101 | } else { | ||
| 102 | |||
| 103 | return false | ||
| 104 | |||
| 105 | } | ||
| 106 | |||
| 107 | } | ||
| 108 | |||
| 109 | // error :-( | ||
| 110 | return false | ||
| 111 | |||
| 112 | } | ||
| 113 | |||
| 114 | // Checks whether the context for this request matches the route | ||
| 115 | func (route *Route) DoesMatchContext(c *Context) bool { | ||
| 116 | |||
| 117 | // by default, we match | ||
| 118 | var match bool = true | ||
| 119 | |||
| 120 | if len(route.MatcherFuncs) > 0 { | ||
| 121 | |||
| 122 | // there are some matcher functions, so don't automatically | ||
| 123 | // match by default - let the matchers decide | ||
| 124 | match = false | ||
| 125 | |||
| 126 | // loop through the matcher functions | ||
| 127 | for _, f := range route.MatcherFuncs { | ||
| 128 | |||
| 129 | // modify 'match' based on the result of the matcher function | ||
| 130 | switch f(c) { | ||
| 131 | case NoMatch: | ||
| 132 | match = false | ||
| 133 | case Match: | ||
| 134 | match = true | ||
| 135 | } | ||
| 136 | |||
| 137 | } | ||
| 138 | |||
| 139 | } | ||
| 140 | |||
| 141 | // return the result | ||
| 142 | return match | ||
| 143 | |||
| 144 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
beego/server/server.go
0 → 100644
| 1 | // Copyright 2011 Google Inc. All rights reserved. | ||
| 2 | // Use of this source code is governed by the Apache 2.0 | ||
| 3 | // license that can be found in the LICENSE file. | ||
| 4 | |||
| 5 | package guestbook | ||
| 6 | |||
| 7 | import ( | ||
| 8 | "io" | ||
| 9 | "net/http" | ||
| 10 | "text/template" | ||
| 11 | "time" | ||
| 12 | |||
| 13 | "appengine" | ||
| 14 | "appengine/datastore" | ||
| 15 | "appengine/user" | ||
| 16 | ) | ||
| 17 | |||
| 18 | type Greeting struct { | ||
| 19 | Author string | ||
| 20 | Content string | ||
| 21 | Date time.Time | ||
| 22 | } | ||
| 23 | |||
| 24 | func serve404(w http.ResponseWriter) { | ||
| 25 | w.WriteHeader(http.StatusNotFound) | ||
| 26 | w.Header().Set("Content-Type", "text/plain; charset=utf-8") | ||
| 27 | io.WriteString(w, "Not Found") | ||
| 28 | } | ||
| 29 | |||
| 30 | func serveError(c appengine.Context, w http.ResponseWriter, err error) { | ||
| 31 | w.WriteHeader(http.StatusInternalServerError) | ||
| 32 | w.Header().Set("Content-Type", "text/plain; charset=utf-8") | ||
| 33 | io.WriteString(w, "Internal Server Error") | ||
| 34 | c.Errorf("%v", err) | ||
| 35 | } | ||
| 36 | |||
| 37 | var mainPage = template.Must(template.New("guestbook").Parse( | ||
| 38 | `<html><body> | ||
| 39 | {{range .}} | ||
| 40 | {{with .Author}}<b>{{.|html}}</b>{{else}}An anonymous person{{end}} | ||
| 41 | on <em>{{.Date.Format "3:04pm, Mon 2 Jan"}}</em> | ||
| 42 | wrote <blockquote>{{.Content|html}}</blockquote> | ||
| 43 | {{end}} | ||
| 44 | <form action="/sign" method="post"> | ||
| 45 | <div><textarea name="content" rows="3" cols="60"></textarea></div> | ||
| 46 | <div><input type="submit" value="Sign Guestbook"></div> | ||
| 47 | </form></body></html> | ||
| 48 | `)) | ||
| 49 | |||
| 50 | func handleMainPage(w http.ResponseWriter, r *http.Request) { | ||
| 51 | if r.Method != "GET" || r.URL.Path != "/" { | ||
| 52 | serve404(w) | ||
| 53 | return | ||
| 54 | } | ||
| 55 | c := appengine.NewContext(r) | ||
| 56 | q := datastore.NewQuery("Greeting").Order("-Date").Limit(10) | ||
| 57 | var gg []*Greeting | ||
| 58 | _, err := q.GetAll(c, &gg) | ||
| 59 | if err != nil { | ||
| 60 | serveError(c, w, err) | ||
| 61 | return | ||
| 62 | } | ||
| 63 | w.Header().Set("Content-Type", "text/html; charset=utf-8") | ||
| 64 | if err := mainPage.Execute(w, gg); err != nil { | ||
| 65 | c.Errorf("%v", err) | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | func handleSign(w http.ResponseWriter, r *http.Request) { | ||
| 70 | if r.Method != "POST" { | ||
| 71 | serve404(w) | ||
| 72 | return | ||
| 73 | } | ||
| 74 | c := appengine.NewContext(r) | ||
| 75 | if err := r.ParseForm(); err != nil { | ||
| 76 | serveError(c, w, err) | ||
| 77 | return | ||
| 78 | } | ||
| 79 | g := &Greeting{ | ||
| 80 | Content: r.FormValue("content"), | ||
| 81 | Date: time.Now(), | ||
| 82 | } | ||
| 83 | if u := user.Current(c); u != nil { | ||
| 84 | g.Author = u.String() | ||
| 85 | } | ||
| 86 | if _, err := datastore.Put(c, datastore.NewIncompleteKey(c, "Greeting", nil), g); err != nil { | ||
| 87 | serveError(c, w, err) | ||
| 88 | return | ||
| 89 | } | ||
| 90 | http.Redirect(w, r, "/", http.StatusFound) | ||
| 91 | } | ||
| 92 | |||
| 93 | func init() { | ||
| 94 | http.HandleFunc("/", handleMainPage) | ||
| 95 | http.HandleFunc("/sign", handleSign) | ||
| 96 | } | ... | ... |
examples/blog/configs/app.yaml
0 → 100644
-
Please register or sign in to post a comment