// AddAutoPrefix Add auto router to ControllerRegister with prefix. // example beego.AddAutoPrefix("/admin",&MainContorlller{}), // MainController has method List and Page. // visit the url /admin/main/list to execute List function // /admin/main/page to execute Page function. func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) { reflectVal := reflect.ValueOf(c) rt := reflectVal.Type() ct := reflect.Indirect(reflectVal).Type() controllerName := strings.TrimSuffix(ct.Name(), "Controller") for i := 0; i < rt.NumMethod(); i++ { if !utils.InSlice(rt.Method(i).Name, exceptMethod) { route := &controllerInfo{} route.routerType = routerTypeBeego route.methods = map[string]string{"*": rt.Method(i).Name} route.controllerType = ct pattern := path.Join(prefix, strings.ToLower(controllerName), strings.ToLower(rt.Method(i).Name), "*") patternInit := path.Join(prefix, controllerName, rt.Method(i).Name, "*") patternFix := path.Join(prefix, strings.ToLower(controllerName), strings.ToLower(rt.Method(i).Name)) patternFixInit := path.Join(prefix, controllerName, rt.Method(i).Name) route.pattern = pattern for _, m := range HTTPMETHOD { p.addToRouter(m, pattern, route) p.addToRouter(m, patternInit, route) p.addToRouter(m, patternFix, route) p.addToRouter(m, patternFixInit, route) } } } }
// ErrorController registers ControllerInterface to each http err code string. // usage: // beego.ErrorController(&controllers.ErrorController{}) func ErrorController(c ControllerInterface) *App { reflectVal := reflect.ValueOf(c) rt := reflectVal.Type() ct := reflect.Indirect(reflectVal).Type() for i := 0; i < rt.NumMethod(); i++ { methodName := rt.Method(i).Name if !utils.InSlice(methodName, exceptMethod) && strings.HasPrefix(methodName, "Error") { errName := strings.TrimPrefix(methodName, "Error") ErrorMaps[errName] = &errorInfo{ errorType: errorTypeController, controllerType: ct, method: methodName, } } } return BeeApp }
// BuildTemplate will build all template files in a directory. // it makes beego can render any template file in view directory. func BuildTemplate(dir string, files ...string) error { if _, err := os.Stat(dir); err != nil { if os.IsNotExist(err) { return nil } return errors.New("dir open err") } self := &templateFile{ root: dir, files: make(map[string][]string), } err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { return self.visit(path, f, err) }) if err != nil { fmt.Printf("filepath.Walk() returned %v\n", err) return err } buildAllFiles := len(files) == 0 for _, v := range self.files { for _, file := range v { if buildAllFiles || utils.InSlice(file, files) { templatesLock.Lock() ext := filepath.Ext(file) var t *template.Template if len(ext) == 0 { t, err = getTemplate(self.root, file, v...) } else if fn, ok := beeTemplateEngines[ext[1:]]; ok { t, err = fn(self.root, file, beegoTplFuncMap) } else { t, err = getTemplate(self.root, file, v...) } if err != nil { logs.Trace("parse template err:", file, err) } else { beeTemplates[file] = t } templatesLock.Unlock() } } } return nil }
func (t *Tree) addtree(segments []string, tree *Tree, wildcards []string, reg string) { if len(segments) == 0 { panic("prefix should has path") } seg := segments[0] iswild, params, regexpStr := splitSegment(seg) // if it's ? meaning can igone this, so add one more rule for it if len(params) > 0 && params[0] == ":" { params = params[1:] if len(segments[1:]) > 0 { t.addtree(segments[1:], tree, append(wildcards, params...), reg) } else { filterTreeWithPrefix(tree, wildcards, reg) } } //Rule: /login/*/access match /login/2009/11/access //if already has *, and when loop the access, should as a regexpStr if !iswild && utils.InSlice(":splat", wildcards) { iswild = true regexpStr = seg } //Rule: /user/:id/* if seg == "*" && len(wildcards) > 0 && reg == "" { regexpStr = "(.+)" } if len(segments) == 1 { if iswild { if regexpStr != "" { if reg == "" { rr := "" for _, w := range wildcards { if w == ":splat" { rr = rr + "(.+)/" } else { rr = rr + "([^/]+)/" } } regexpStr = rr + regexpStr } else { regexpStr = "/" + regexpStr } } else if reg != "" { if seg == "*.*" { regexpStr = "([^.]+).(.+)" } else { for _, w := range params { if w == "." || w == ":" { continue } regexpStr = "([^/]+)/" + regexpStr } } } reg = strings.Trim(reg+"/"+regexpStr, "/") filterTreeWithPrefix(tree, append(wildcards, params...), reg) t.wildcard = tree } else { reg = strings.Trim(reg+"/"+regexpStr, "/") filterTreeWithPrefix(tree, append(wildcards, params...), reg) tree.prefix = seg t.fixrouters = append(t.fixrouters, tree) } return } if iswild { if t.wildcard == nil { t.wildcard = NewTree() } if regexpStr != "" { if reg == "" { rr := "" for _, w := range wildcards { if w == ":splat" { rr = rr + "(.+)/" } else { rr = rr + "([^/]+)/" } } regexpStr = rr + regexpStr } else { regexpStr = "/" + regexpStr } } else if reg != "" { if seg == "*.*" { regexpStr = "([^.]+).(.+)" params = params[1:] } else { for range params { regexpStr = "([^/]+)/" + regexpStr } } } else { if seg == "*.*" { params = params[1:] } } reg = strings.TrimRight(strings.TrimRight(reg, "/")+"/"+regexpStr, "/") t.wildcard.addtree(segments[1:], tree, append(wildcards, params...), reg) } else { subTree := NewTree() subTree.prefix = seg t.fixrouters = append(t.fixrouters, subTree) subTree.addtree(segments[1:], tree, append(wildcards, params...), reg) } }
// "/" // "admin" -> func (t *Tree) addseg(segments []string, route interface{}, wildcards []string, reg string) { if len(segments) == 0 { if reg != "" { t.leaves = append(t.leaves, &leafInfo{runObject: route, wildcards: wildcards, regexps: regexp.MustCompile("^" + reg + "$")}) } else { t.leaves = append(t.leaves, &leafInfo{runObject: route, wildcards: wildcards}) } } else { seg := segments[0] iswild, params, regexpStr := splitSegment(seg) // if it's ? meaning can igone this, so add one more rule for it if len(params) > 0 && params[0] == ":" { t.addseg(segments[1:], route, wildcards, reg) params = params[1:] } //Rule: /login/*/access match /login/2009/11/access //if already has *, and when loop the access, should as a regexpStr if !iswild && utils.InSlice(":splat", wildcards) { iswild = true regexpStr = seg } //Rule: /user/:id/* if seg == "*" && len(wildcards) > 0 && reg == "" { regexpStr = "(.+)" } if iswild { if t.wildcard == nil { t.wildcard = NewTree() } if regexpStr != "" { if reg == "" { rr := "" for _, w := range wildcards { if w == ":splat" { rr = rr + "(.+)/" } else { rr = rr + "([^/]+)/" } } regexpStr = rr + regexpStr } else { regexpStr = "/" + regexpStr } } else if reg != "" { if seg == "*.*" { regexpStr = "/([^.]+).(.+)" params = params[1:] } else { for range params { regexpStr = "/([^/]+)" + regexpStr } } } else { if seg == "*.*" { params = params[1:] } } t.wildcard.addseg(segments[1:], route, append(wildcards, params...), reg+regexpStr) } else { var subTree *Tree for _, sub := range t.fixrouters { if sub.prefix == seg { subTree = sub break } } if subTree == nil { subTree = NewTree() subTree.prefix = seg t.fixrouters = append(t.fixrouters, subTree) } subTree.addseg(segments[1:], route, wildcards, reg) } } }