mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 14:00:54 +00:00
Merge branch 'astaxie/develop' into emptybodyfix
# Conflicts: # config.go
This commit is contained in:
commit
920862884d
@ -2,9 +2,9 @@ language: go
|
|||||||
|
|
||||||
go:
|
go:
|
||||||
- tip
|
- tip
|
||||||
|
- 1.6.0
|
||||||
- 1.5.3
|
- 1.5.3
|
||||||
- 1.4.3
|
- 1.4.3
|
||||||
- 1.3.3
|
|
||||||
services:
|
services:
|
||||||
- redis-server
|
- redis-server
|
||||||
- mysql
|
- mysql
|
||||||
@ -21,9 +21,9 @@ install:
|
|||||||
- go get github.com/bradfitz/gomemcache/memcache
|
- go get github.com/bradfitz/gomemcache/memcache
|
||||||
- go get github.com/garyburd/redigo/redis
|
- go get github.com/garyburd/redigo/redis
|
||||||
- go get github.com/beego/x2j
|
- go get github.com/beego/x2j
|
||||||
|
- go get github.com/couchbase/go-couchbase
|
||||||
- go get github.com/beego/goyaml2
|
- go get github.com/beego/goyaml2
|
||||||
- go get github.com/belogik/goes
|
- go get github.com/belogik/goes
|
||||||
- go get github.com/couchbase/go-couchbase
|
|
||||||
- go get github.com/siddontang/ledisdb/config
|
- go get github.com/siddontang/ledisdb/config
|
||||||
- go get github.com/siddontang/ledisdb/ledis
|
- go get github.com/siddontang/ledisdb/ledis
|
||||||
- go get golang.org/x/tools/cmd/vet
|
- go get golang.org/x/tools/cmd/vet
|
||||||
|
52
config.go
52
config.go
@ -16,7 +16,10 @@ package beego
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
<<<<<<< HEAD
|
||||||
"html/template"
|
"html/template"
|
||||||
|
=======
|
||||||
|
>>>>>>> astaxie/develop
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -106,12 +109,9 @@ var (
|
|||||||
AppConfig *beegoAppConfig
|
AppConfig *beegoAppConfig
|
||||||
// AppPath is the absolute path to the app
|
// AppPath is the absolute path to the app
|
||||||
AppPath string
|
AppPath string
|
||||||
// TemplateCache stores template caching
|
|
||||||
TemplateCache map[string]*template.Template
|
|
||||||
// GlobalSessions is the instance for the session manager
|
// GlobalSessions is the instance for the session manager
|
||||||
GlobalSessions *session.Manager
|
GlobalSessions *session.Manager
|
||||||
|
|
||||||
workPath string
|
|
||||||
// appConfigPath is the path to the config files
|
// appConfigPath is the path to the config files
|
||||||
appConfigPath string
|
appConfigPath string
|
||||||
// appConfigProvider is the provider for the config, default is ini
|
// appConfigProvider is the provider for the config, default is ini
|
||||||
@ -120,12 +120,8 @@ var (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
|
AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
|
||||||
workPath, _ = os.Getwd()
|
|
||||||
workPath, _ = filepath.Abs(workPath)
|
|
||||||
|
|
||||||
if workPath != AppPath {
|
os.Chdir(AppPath)
|
||||||
os.Chdir(AppPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
BConfig = &Config{
|
BConfig = &Config{
|
||||||
AppName: "beego",
|
AppName: "beego",
|
||||||
@ -175,7 +171,7 @@ func init() {
|
|||||||
SessionName: "beegosessionID",
|
SessionName: "beegosessionID",
|
||||||
SessionGCMaxLifetime: 3600,
|
SessionGCMaxLifetime: 3600,
|
||||||
SessionProviderConfig: "",
|
SessionProviderConfig: "",
|
||||||
SessionCookieLifeTime: 0, //set cookie default is the brower life
|
SessionCookieLifeTime: 0, //set cookie default is the browser life
|
||||||
SessionAutoSetCookie: true,
|
SessionAutoSetCookie: true,
|
||||||
SessionDomain: "",
|
SessionDomain: "",
|
||||||
},
|
},
|
||||||
@ -189,11 +185,13 @@ func init() {
|
|||||||
|
|
||||||
appConfigPath = filepath.Join(AppPath, "conf", "app.conf")
|
appConfigPath = filepath.Join(AppPath, "conf", "app.conf")
|
||||||
if !utils.FileExists(appConfigPath) {
|
if !utils.FileExists(appConfigPath) {
|
||||||
AppConfig = &beegoAppConfig{config.NewFakeConfig()}
|
AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parseConfig(appConfigPath)
|
if err := parseConfig(appConfigPath); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now only support ini, next will support json.
|
// now only support ini, next will support json.
|
||||||
@ -202,11 +200,11 @@ func parseConfig(appConfigPath string) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// set the runmode first
|
// set the run mode first
|
||||||
if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
|
if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
|
||||||
BConfig.RunMode = envRunMode
|
BConfig.RunMode = envRunMode
|
||||||
} else if runmode := AppConfig.String("RunMode"); runmode != "" {
|
} else if runMode := AppConfig.String("RunMode"); runMode != "" {
|
||||||
BConfig.RunMode = runmode
|
BConfig.RunMode = runMode
|
||||||
}
|
}
|
||||||
|
|
||||||
BConfig.AppName = AppConfig.DefaultString("AppName", BConfig.AppName)
|
BConfig.AppName = AppConfig.DefaultString("AppName", BConfig.AppName)
|
||||||
@ -299,7 +297,7 @@ func parseConfig(appConfigPath string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//init log
|
//init log
|
||||||
BeeLogger.Close()
|
BeeLogger.Reset()
|
||||||
for adaptor, config := range BConfig.Log.Outputs {
|
for adaptor, config := range BConfig.Log.Outputs {
|
||||||
err = BeeLogger.SetLogger(adaptor, config)
|
err = BeeLogger.SetLogger(adaptor, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -393,46 +391,46 @@ func (b *beegoAppConfig) Float(key string) (float64, error) {
|
|||||||
return b.innerConfig.Float(key)
|
return b.innerConfig.Float(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultString(key string, defaultval string) string {
|
func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
|
||||||
if v := b.String(key); v != "" {
|
if v := b.String(key); v != "" {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string {
|
func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
|
||||||
if v := b.Strings(key); len(v) != 0 {
|
if v := b.Strings(key); len(v) != 0 {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int {
|
func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
|
||||||
if v, err := b.Int(key); err == nil {
|
if v, err := b.Int(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 {
|
func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
|
||||||
if v, err := b.Int64(key); err == nil {
|
if v, err := b.Int64(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool {
|
func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
|
||||||
if v, err := b.Bool(key); err == nil {
|
if v, err := b.Bool(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 {
|
func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
|
||||||
if v, err := b.Float(key); err == nil {
|
if v, err := b.Float(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
|
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
|
||||||
|
@ -46,12 +46,16 @@ func (c *fakeConfigContainer) DefaultString(key string, defaultval string) strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConfigContainer) Strings(key string) []string {
|
func (c *fakeConfigContainer) Strings(key string) []string {
|
||||||
return strings.Split(c.getData(key), ";")
|
v := c.getData(key)
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return strings.Split(v, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if len(v) == 0 {
|
if v == nil {
|
||||||
return defaultval
|
return defaultval
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
|
@ -269,15 +269,20 @@ func (c *IniConfigContainer) DefaultString(key string, defaultval string) string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
|
// Return nil if config value does not exist or is empty.
|
||||||
func (c *IniConfigContainer) Strings(key string) []string {
|
func (c *IniConfigContainer) Strings(key string) []string {
|
||||||
return strings.Split(c.String(key), ";")
|
v := c.String(key)
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return strings.Split(v, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaltval
|
// if err != nil return defaltval
|
||||||
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if len(v) == 0 {
|
if v == nil {
|
||||||
return defaultval
|
return defaultval
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
|
@ -71,6 +71,7 @@ peers = one;two;three
|
|||||||
"null": "",
|
"null": "",
|
||||||
"demo2::key1": "",
|
"demo2::key1": "",
|
||||||
"error": "",
|
"error": "",
|
||||||
|
"emptystrings": []string{},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ func (c *JSONConfigContainer) DefaultString(key string, defaultval string) strin
|
|||||||
func (c *JSONConfigContainer) Strings(key string) []string {
|
func (c *JSONConfigContainer) Strings(key string) []string {
|
||||||
stringVal := c.String(key)
|
stringVal := c.String(key)
|
||||||
if stringVal == "" {
|
if stringVal == "" {
|
||||||
return []string{}
|
return nil
|
||||||
}
|
}
|
||||||
return strings.Split(c.String(key), ";")
|
return strings.Split(c.String(key), ";")
|
||||||
}
|
}
|
||||||
@ -181,7 +181,7 @@ func (c *JSONConfigContainer) Strings(key string) []string {
|
|||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaltval
|
// if err != nil return defaltval
|
||||||
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
if v := c.Strings(key); len(v) > 0 {
|
if v := c.Strings(key); v != nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultval
|
||||||
|
@ -174,14 +174,18 @@ func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
|||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
func (c *ConfigContainer) Strings(key string) []string {
|
func (c *ConfigContainer) Strings(key string) []string {
|
||||||
return strings.Split(c.String(key), ";")
|
v := c.String(key)
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return strings.Split(v, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaltval
|
// if err != nil return defaltval
|
||||||
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if len(v) == 0 {
|
if v == nil {
|
||||||
return defaultval
|
return defaultval
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
|
@ -82,4 +82,7 @@ func TestXML(t *testing.T) {
|
|||||||
if xmlconf.String("name") != "astaxie" {
|
if xmlconf.String("name") != "astaxie" {
|
||||||
t.Fatal("get name error")
|
t.Fatal("get name error")
|
||||||
}
|
}
|
||||||
|
if xmlconf.Strings("emptystrings") != nil {
|
||||||
|
t.Fatal("get emtpy strings error")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,14 +211,18 @@ func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
|||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
func (c *ConfigContainer) Strings(key string) []string {
|
func (c *ConfigContainer) Strings(key string) []string {
|
||||||
return strings.Split(c.String(key), ";")
|
v := c.String(key)
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return strings.Split(v, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaltval
|
// if err != nil return defaltval
|
||||||
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if len(v) == 0 {
|
if v == nil {
|
||||||
return defaultval
|
return defaultval
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
|
@ -79,4 +79,8 @@ func TestYaml(t *testing.T) {
|
|||||||
if yamlconf.String("name") != "astaxie" {
|
if yamlconf.String("name") != "astaxie" {
|
||||||
t.Fatal("get name error")
|
t.Fatal("get name error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if yamlconf.Strings("emptystrings") != nil {
|
||||||
|
t.Fatal("get emtpy strings error")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,33 +196,9 @@ func (c *Controller) RenderString() (string, error) {
|
|||||||
|
|
||||||
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
||||||
func (c *Controller) RenderBytes() ([]byte, error) {
|
func (c *Controller) RenderBytes() ([]byte, error) {
|
||||||
//if the controller has set layout, then first get the tplname's content set the content to the layout
|
buf, err := c.renderTemplate()
|
||||||
var buf bytes.Buffer
|
//if the controller has set layout, then first get the tplName's content set the content to the layout
|
||||||
if c.Layout != "" {
|
if err == nil && c.Layout != "" {
|
||||||
if c.TplName == "" {
|
|
||||||
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
|
|
||||||
}
|
|
||||||
|
|
||||||
if BConfig.RunMode == DEV {
|
|
||||||
buildFiles := []string{c.TplName}
|
|
||||||
if c.LayoutSections != nil {
|
|
||||||
for _, sectionTpl := range c.LayoutSections {
|
|
||||||
if sectionTpl == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buildFiles = append(buildFiles, sectionTpl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...)
|
|
||||||
}
|
|
||||||
if _, ok := BeeTemplates[c.TplName]; !ok {
|
|
||||||
panic("can't find templatefile in the path:" + c.TplName)
|
|
||||||
}
|
|
||||||
err := BeeTemplates[c.TplName].ExecuteTemplate(&buf, c.TplName, c.Data)
|
|
||||||
if err != nil {
|
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.Data["LayoutContent"] = template.HTML(buf.String())
|
c.Data["LayoutContent"] = template.HTML(buf.String())
|
||||||
|
|
||||||
if c.LayoutSections != nil {
|
if c.LayoutSections != nil {
|
||||||
@ -231,11 +207,9 @@ func (c *Controller) RenderBytes() ([]byte, error) {
|
|||||||
c.Data[sectionName] = ""
|
c.Data[sectionName] = ""
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
err = BeeTemplates[sectionTpl].ExecuteTemplate(&buf, sectionTpl, c.Data)
|
err = executeTemplate(&buf, sectionTpl, c.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c.Data[sectionName] = template.HTML(buf.String())
|
c.Data[sectionName] = template.HTML(buf.String())
|
||||||
@ -243,30 +217,29 @@ func (c *Controller) RenderBytes() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
err = BeeTemplates[c.Layout].ExecuteTemplate(&buf, c.Layout, c.Data)
|
executeTemplate(&buf, c.Layout, c.Data)
|
||||||
if err != nil {
|
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
return buf.Bytes(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Controller) renderTemplate() (bytes.Buffer, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
if c.TplName == "" {
|
if c.TplName == "" {
|
||||||
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
|
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
|
||||||
}
|
}
|
||||||
if BConfig.RunMode == DEV {
|
if BConfig.RunMode == DEV {
|
||||||
BuildTemplate(BConfig.WebConfig.ViewsPath, c.TplName)
|
buildFiles := []string{c.TplName}
|
||||||
|
if c.Layout != "" && c.LayoutSections != nil {
|
||||||
|
for _, sectionTpl := range c.LayoutSections {
|
||||||
|
if sectionTpl == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buildFiles = append(buildFiles, sectionTpl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...)
|
||||||
}
|
}
|
||||||
if _, ok := BeeTemplates[c.TplName]; !ok {
|
return buf, executeTemplate(&buf, c.TplName, c.Data)
|
||||||
panic("can't find templatefile in the path:" + c.TplName)
|
|
||||||
}
|
|
||||||
buf.Reset()
|
|
||||||
err := BeeTemplates[c.TplName].ExecuteTemplate(&buf, c.TplName, c.Data)
|
|
||||||
if err != nil {
|
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect sends the redirection response to url with status code.
|
// Redirect sends the redirection response to url with status code.
|
||||||
|
@ -47,17 +47,17 @@ var colors = []brush{
|
|||||||
|
|
||||||
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
||||||
type consoleWriter struct {
|
type consoleWriter struct {
|
||||||
lg *log.Logger
|
lg *log.Logger
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
Color bool `json:"color"`
|
Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConsole create ConsoleWriter returning as LoggerInterface.
|
// NewConsole create ConsoleWriter returning as LoggerInterface.
|
||||||
func NewConsole() Logger {
|
func NewConsole() Logger {
|
||||||
cw := &consoleWriter{
|
cw := &consoleWriter{
|
||||||
lg: log.New(os.Stdout, "", 0),
|
lg: log.New(os.Stdout, "", 0),
|
||||||
Level: LevelDebug,
|
Level: LevelDebug,
|
||||||
Color: true,
|
Colorful: true,
|
||||||
}
|
}
|
||||||
return cw
|
return cw
|
||||||
}
|
}
|
||||||
@ -68,7 +68,11 @@ func (c *consoleWriter) Init(jsonConfig string) error {
|
|||||||
if len(jsonConfig) == 0 {
|
if len(jsonConfig) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return json.Unmarshal([]byte(jsonConfig), c)
|
err := json.Unmarshal([]byte(jsonConfig), c)
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
c.Colorful = false
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in console.
|
// WriteMsg write message in console.
|
||||||
@ -77,12 +81,11 @@ func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
msg = formatLogTime(when) + msg
|
msg = formatLogTime(when) + msg
|
||||||
if runtime.GOOS == "windows" || !c.Color {
|
if c.Colorful {
|
||||||
|
c.lg.Println(colors[level](msg))
|
||||||
|
} else {
|
||||||
c.lg.Println(msg)
|
c.lg.Println(msg)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
c.lg.Println(colors[level](msg))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
logs/log.go
55
logs/log.go
@ -98,6 +98,8 @@ type BeeLogger struct {
|
|||||||
loggerFuncCallDepth int
|
loggerFuncCallDepth int
|
||||||
asynchronous bool
|
asynchronous bool
|
||||||
msgChan chan *logMsg
|
msgChan chan *logMsg
|
||||||
|
signalChan chan string
|
||||||
|
wg sync.WaitGroup
|
||||||
outputs []*nameLogger
|
outputs []*nameLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +111,7 @@ type nameLogger struct {
|
|||||||
type logMsg struct {
|
type logMsg struct {
|
||||||
level int
|
level int
|
||||||
msg string
|
msg string
|
||||||
when time.Time
|
when time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var logMsgPool *sync.Pool
|
var logMsgPool *sync.Pool
|
||||||
@ -122,6 +124,7 @@ func NewLogger(channelLen int64) *BeeLogger {
|
|||||||
bl.level = LevelDebug
|
bl.level = LevelDebug
|
||||||
bl.loggerFuncCallDepth = 2
|
bl.loggerFuncCallDepth = 2
|
||||||
bl.msgChan = make(chan *logMsg, channelLen)
|
bl.msgChan = make(chan *logMsg, channelLen)
|
||||||
|
bl.signalChan = make(chan string, 1)
|
||||||
return bl
|
return bl
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +136,7 @@ func (bl *BeeLogger) Async() *BeeLogger {
|
|||||||
return &logMsg{}
|
return &logMsg{}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
bl.wg.Add(1)
|
||||||
go bl.startLogger()
|
go bl.startLogger()
|
||||||
return bl
|
return bl
|
||||||
}
|
}
|
||||||
@ -232,11 +236,26 @@ func (bl *BeeLogger) EnableFuncCallDepth(b bool) {
|
|||||||
// start logger chan reading.
|
// start logger chan reading.
|
||||||
// when chan is not empty, write logs.
|
// when chan is not empty, write logs.
|
||||||
func (bl *BeeLogger) startLogger() {
|
func (bl *BeeLogger) startLogger() {
|
||||||
|
gameOver := false
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case bm := <-bl.msgChan:
|
case bm := <-bl.msgChan:
|
||||||
bl.writeToLoggers(bm.when, bm.msg, bm.level)
|
bl.writeToLoggers(bm.when, bm.msg, bm.level)
|
||||||
logMsgPool.Put(bm)
|
logMsgPool.Put(bm)
|
||||||
|
case sg := <-bl.signalChan:
|
||||||
|
// Now should only send "flush" or "close" to bl.signalChan
|
||||||
|
bl.flush()
|
||||||
|
if sg == "close" {
|
||||||
|
for _, l := range bl.outputs {
|
||||||
|
l.Destroy()
|
||||||
|
}
|
||||||
|
bl.outputs = nil
|
||||||
|
gameOver = true
|
||||||
|
}
|
||||||
|
bl.wg.Done()
|
||||||
|
}
|
||||||
|
if gameOver {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,13 +364,41 @@ func (bl *BeeLogger) Trace(format string, v ...interface{}) {
|
|||||||
|
|
||||||
// Flush flush all chan data.
|
// Flush flush all chan data.
|
||||||
func (bl *BeeLogger) Flush() {
|
func (bl *BeeLogger) Flush() {
|
||||||
for _, l := range bl.outputs {
|
if bl.asynchronous {
|
||||||
l.Flush()
|
bl.signalChan <- "flush"
|
||||||
|
bl.wg.Wait()
|
||||||
|
bl.wg.Add(1)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
bl.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close close logger, flush all chan data and destroy all adapters in BeeLogger.
|
// Close close logger, flush all chan data and destroy all adapters in BeeLogger.
|
||||||
func (bl *BeeLogger) Close() {
|
func (bl *BeeLogger) Close() {
|
||||||
|
if bl.asynchronous {
|
||||||
|
bl.signalChan <- "close"
|
||||||
|
bl.wg.Wait()
|
||||||
|
} else {
|
||||||
|
bl.flush()
|
||||||
|
for _, l := range bl.outputs {
|
||||||
|
l.Destroy()
|
||||||
|
}
|
||||||
|
bl.outputs = nil
|
||||||
|
}
|
||||||
|
close(bl.msgChan)
|
||||||
|
close(bl.signalChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset close all outputs, and set bl.outputs to nil
|
||||||
|
func (bl *BeeLogger) Reset() {
|
||||||
|
bl.Flush()
|
||||||
|
for _, l := range bl.outputs {
|
||||||
|
l.Destroy()
|
||||||
|
}
|
||||||
|
bl.outputs = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bl *BeeLogger) flush() {
|
||||||
for {
|
for {
|
||||||
if len(bl.msgChan) > 0 {
|
if len(bl.msgChan) > 0 {
|
||||||
bm := <-bl.msgChan
|
bm := <-bl.msgChan
|
||||||
@ -363,9 +410,7 @@ func (bl *BeeLogger) Close() {
|
|||||||
}
|
}
|
||||||
for _, l := range bl.outputs {
|
for _, l := range bl.outputs {
|
||||||
l.Flush()
|
l.Flush()
|
||||||
l.Destroy()
|
|
||||||
}
|
}
|
||||||
bl.outputs = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatLogTime(when time.Time) string {
|
func formatLogTime(when time.Time) string {
|
||||||
|
@ -102,7 +102,7 @@ func (pder *MemProvider) SessionRead(sid string) (Store, error) {
|
|||||||
pder.lock.RUnlock()
|
pder.lock.RUnlock()
|
||||||
pder.lock.Lock()
|
pder.lock.Lock()
|
||||||
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
||||||
element := pder.list.PushBack(newsess)
|
element := pder.list.PushFront(newsess)
|
||||||
pder.sessions[sid] = element
|
pder.sessions[sid] = element
|
||||||
pder.lock.Unlock()
|
pder.lock.Unlock()
|
||||||
return newsess, nil
|
return newsess, nil
|
||||||
@ -134,7 +134,7 @@ func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
|
|||||||
pder.lock.RUnlock()
|
pder.lock.RUnlock()
|
||||||
pder.lock.Lock()
|
pder.lock.Lock()
|
||||||
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
||||||
element := pder.list.PushBack(newsess)
|
element := pder.list.PushFront(newsess)
|
||||||
pder.sessions[sid] = element
|
pder.sessions[sid] = element
|
||||||
pder.lock.Unlock()
|
pder.lock.Unlock()
|
||||||
return newsess, nil
|
return newsess, nil
|
||||||
|
@ -201,7 +201,9 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
|
|||||||
if err != nil || cookie.Value == "" {
|
if err != nil || cookie.Value == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
manager.provider.SessionDestroy(cookie.Value)
|
|
||||||
|
sid, _ := url.QueryUnescape(cookie.Value)
|
||||||
|
manager.provider.SessionDestroy(sid)
|
||||||
if manager.config.EnableSetCookie {
|
if manager.config.EnableSetCookie {
|
||||||
expiration := time.Now()
|
expiration := time.Now()
|
||||||
cookie = &http.Cookie{Name: manager.config.CookieName,
|
cookie = &http.Cookie{Name: manager.config.CookieName,
|
||||||
|
@ -93,12 +93,14 @@ type serveContentHolder struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
staticFileMap = make(map[string]*serveContentHolder)
|
staticFileMap = make(map[string]*serveContentHolder)
|
||||||
mapLock sync.Mutex
|
mapLock sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, error) {
|
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, error) {
|
||||||
mapKey := acceptEncoding + ":" + filePath
|
mapKey := acceptEncoding + ":" + filePath
|
||||||
|
mapLock.RLock()
|
||||||
mapFile, _ := staticFileMap[mapKey]
|
mapFile, _ := staticFileMap[mapKey]
|
||||||
|
mapLock.RUnlock()
|
||||||
if isOk(mapFile, fi) {
|
if isOk(mapFile, fi) {
|
||||||
return mapFile.encoding != "", mapFile.encoding, mapFile, nil
|
return mapFile.encoding != "", mapFile.encoding, mapFile, nil
|
||||||
}
|
}
|
||||||
|
129
template.go
129
template.go
@ -18,23 +18,41 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/astaxie/beego/utils"
|
"github.com/astaxie/beego/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
beegoTplFuncMap = make(template.FuncMap)
|
beegoTplFuncMap = make(template.FuncMap)
|
||||||
// BeeTemplates caching map and supported template file extensions.
|
// beeTemplates caching map and supported template file extensions.
|
||||||
BeeTemplates = make(map[string]*template.Template)
|
beeTemplates = make(map[string]*template.Template)
|
||||||
// BeeTemplateExt stores the template extension which will build
|
templatesLock sync.RWMutex
|
||||||
BeeTemplateExt = []string{"tpl", "html"}
|
// beeTemplateExt stores the template extension which will build
|
||||||
|
beeTemplateExt = []string{"tpl", "html"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func executeTemplate(wr io.Writer, name string, data interface{}) error {
|
||||||
|
if BConfig.RunMode == DEV {
|
||||||
|
templatesLock.RLock()
|
||||||
|
defer templatesLock.RUnlock()
|
||||||
|
}
|
||||||
|
if t, ok := beeTemplates[name]; ok {
|
||||||
|
err := t.ExecuteTemplate(wr, name, data)
|
||||||
|
if err != nil {
|
||||||
|
Trace("template Execute err:", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
panic("can't find templatefile in the path:" + name)
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
beegoTplFuncMap["dateformat"] = DateFormat
|
beegoTplFuncMap["dateformat"] = DateFormat
|
||||||
beegoTplFuncMap["date"] = Date
|
beegoTplFuncMap["date"] = Date
|
||||||
@ -53,7 +71,6 @@ func init() {
|
|||||||
beegoTplFuncMap["config"] = GetConfig
|
beegoTplFuncMap["config"] = GetConfig
|
||||||
beegoTplFuncMap["map_get"] = MapGet
|
beegoTplFuncMap["map_get"] = MapGet
|
||||||
|
|
||||||
// go1.2 added template funcs
|
|
||||||
// Comparisons
|
// Comparisons
|
||||||
beegoTplFuncMap["eq"] = eq // ==
|
beegoTplFuncMap["eq"] = eq // ==
|
||||||
beegoTplFuncMap["ge"] = ge // >=
|
beegoTplFuncMap["ge"] = ge // >=
|
||||||
@ -66,17 +83,21 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddFuncMap let user to register a func in the template.
|
// AddFuncMap let user to register a func in the template.
|
||||||
func AddFuncMap(key string, funname interface{}) error {
|
func AddFuncMap(key string, fn interface{}) error {
|
||||||
beegoTplFuncMap[key] = funname
|
beegoTplFuncMap[key] = fn
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type templatefile struct {
|
type templateFile struct {
|
||||||
root string
|
root string
|
||||||
files map[string][]string
|
files map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tf *templatefile) visit(paths string, f os.FileInfo, err error) error {
|
// visit will make the paths into two part,the first is subDir (without tf.root),the second is full path(without tf.root).
|
||||||
|
// if tf.root="views" and
|
||||||
|
// paths is "views/errors/404.html",the subDir will be "errors",the file will be "errors/404.html"
|
||||||
|
// paths is "views/admin/errors/404.html",the subDir will be "admin/errors",the file will be "admin/errors/404.html"
|
||||||
|
func (tf *templateFile) visit(paths string, f os.FileInfo, err error) error {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -88,24 +109,16 @@ func (tf *templatefile) visit(paths string, f os.FileInfo, err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
replace := strings.NewReplacer("\\", "/")
|
replace := strings.NewReplacer("\\", "/")
|
||||||
a := []byte(paths)
|
file := strings.TrimLeft(replace.Replace(paths[len(tf.root):]), "/")
|
||||||
a = a[len([]byte(tf.root)):]
|
subDir := filepath.Dir(file)
|
||||||
file := strings.TrimLeft(replace.Replace(string(a)), "/")
|
|
||||||
subdir := filepath.Dir(file)
|
|
||||||
if _, ok := tf.files[subdir]; ok {
|
|
||||||
tf.files[subdir] = append(tf.files[subdir], file)
|
|
||||||
} else {
|
|
||||||
m := make([]string, 1)
|
|
||||||
m[0] = file
|
|
||||||
tf.files[subdir] = m
|
|
||||||
}
|
|
||||||
|
|
||||||
|
tf.files[subDir] = append(tf.files[subDir], file)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasTemplateExt return this path contains supported template extension of beego or not.
|
// HasTemplateExt return this path contains supported template extension of beego or not.
|
||||||
func HasTemplateExt(paths string) bool {
|
func HasTemplateExt(paths string) bool {
|
||||||
for _, v := range BeeTemplateExt {
|
for _, v := range beeTemplateExt {
|
||||||
if strings.HasSuffix(paths, "."+v) {
|
if strings.HasSuffix(paths, "."+v) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -115,12 +128,12 @@ func HasTemplateExt(paths string) bool {
|
|||||||
|
|
||||||
// AddTemplateExt add new extension for template.
|
// AddTemplateExt add new extension for template.
|
||||||
func AddTemplateExt(ext string) {
|
func AddTemplateExt(ext string) {
|
||||||
for _, v := range BeeTemplateExt {
|
for _, v := range beeTemplateExt {
|
||||||
if v == ext {
|
if v == ext {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BeeTemplateExt = append(BeeTemplateExt, ext)
|
beeTemplateExt = append(beeTemplateExt, ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildTemplate will build all template files in a directory.
|
// BuildTemplate will build all template files in a directory.
|
||||||
@ -132,7 +145,7 @@ func BuildTemplate(dir string, files ...string) error {
|
|||||||
}
|
}
|
||||||
return errors.New("dir open err")
|
return errors.New("dir open err")
|
||||||
}
|
}
|
||||||
self := &templatefile{
|
self := &templateFile{
|
||||||
root: dir,
|
root: dir,
|
||||||
files: make(map[string][]string),
|
files: make(map[string][]string),
|
||||||
}
|
}
|
||||||
@ -146,12 +159,14 @@ func BuildTemplate(dir string, files ...string) error {
|
|||||||
for _, v := range self.files {
|
for _, v := range self.files {
|
||||||
for _, file := range v {
|
for _, file := range v {
|
||||||
if len(files) == 0 || utils.InSlice(file, files) {
|
if len(files) == 0 || utils.InSlice(file, files) {
|
||||||
|
templatesLock.Lock()
|
||||||
t, err := getTemplate(self.root, file, v...)
|
t, err := getTemplate(self.root, file, v...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("parse template err:", file, err)
|
Trace("parse template err:", file, err)
|
||||||
} else {
|
} else {
|
||||||
BeeTemplates[file] = t
|
beeTemplates[file] = t
|
||||||
}
|
}
|
||||||
|
templatesLock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,16 +174,16 @@ func BuildTemplate(dir string, files ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTplDeep(root, file, parent string, t *template.Template) (*template.Template, [][]string, error) {
|
func getTplDeep(root, file, parent string, t *template.Template) (*template.Template, [][]string, error) {
|
||||||
var fileabspath string
|
var fileAbsPath string
|
||||||
if filepath.HasPrefix(file, "../") {
|
if filepath.HasPrefix(file, "../") {
|
||||||
fileabspath = filepath.Join(root, filepath.Dir(parent), file)
|
fileAbsPath = filepath.Join(root, filepath.Dir(parent), file)
|
||||||
} else {
|
} else {
|
||||||
fileabspath = filepath.Join(root, file)
|
fileAbsPath = filepath.Join(root, file)
|
||||||
}
|
}
|
||||||
if e := utils.FileExists(fileabspath); !e {
|
if e := utils.FileExists(fileAbsPath); !e {
|
||||||
panic("can't find template file:" + file)
|
panic("can't find template file:" + file)
|
||||||
}
|
}
|
||||||
data, err := ioutil.ReadFile(fileabspath)
|
data, err := ioutil.ReadFile(fileAbsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, [][]string{}, err
|
return nil, [][]string{}, err
|
||||||
}
|
}
|
||||||
@ -177,11 +192,11 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
|
|||||||
return nil, [][]string{}, err
|
return nil, [][]string{}, err
|
||||||
}
|
}
|
||||||
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"")
|
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"")
|
||||||
allsub := reg.FindAllStringSubmatch(string(data), -1)
|
allSub := reg.FindAllStringSubmatch(string(data), -1)
|
||||||
for _, m := range allsub {
|
for _, m := range allSub {
|
||||||
if len(m) == 2 {
|
if len(m) == 2 {
|
||||||
tlook := t.Lookup(m[1])
|
tl := t.Lookup(m[1])
|
||||||
if tlook != nil {
|
if tl != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !HasTemplateExt(m[1]) {
|
if !HasTemplateExt(m[1]) {
|
||||||
@ -193,17 +208,17 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return t, allsub, nil
|
return t, allSub, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTemplate(root, file string, others ...string) (t *template.Template, err error) {
|
func getTemplate(root, file string, others ...string) (t *template.Template, err error) {
|
||||||
t = template.New(file).Delims(BConfig.WebConfig.TemplateLeft, BConfig.WebConfig.TemplateRight).Funcs(beegoTplFuncMap)
|
t = template.New(file).Delims(BConfig.WebConfig.TemplateLeft, BConfig.WebConfig.TemplateRight).Funcs(beegoTplFuncMap)
|
||||||
var submods [][]string
|
var subMods [][]string
|
||||||
t, submods, err = getTplDeep(root, file, "", t)
|
t, subMods, err = getTplDeep(root, file, "", t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t, err = _getTemplate(t, root, submods, others...)
|
t, err = _getTemplate(t, root, subMods, others...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -211,44 +226,44 @@ func getTemplate(root, file string, others ...string) (t *template.Template, err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func _getTemplate(t0 *template.Template, root string, submods [][]string, others ...string) (t *template.Template, err error) {
|
func _getTemplate(t0 *template.Template, root string, subMods [][]string, others ...string) (t *template.Template, err error) {
|
||||||
t = t0
|
t = t0
|
||||||
for _, m := range submods {
|
for _, m := range subMods {
|
||||||
if len(m) == 2 {
|
if len(m) == 2 {
|
||||||
templ := t.Lookup(m[1])
|
tpl := t.Lookup(m[1])
|
||||||
if templ != nil {
|
if tpl != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//first check filename
|
//first check filename
|
||||||
for _, otherfile := range others {
|
for _, otherFile := range others {
|
||||||
if otherfile == m[1] {
|
if otherFile == m[1] {
|
||||||
var submods1 [][]string
|
var subMods1 [][]string
|
||||||
t, submods1, err = getTplDeep(root, otherfile, "", t)
|
t, subMods1, err = getTplDeep(root, otherFile, "", t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("template parse file err:", err)
|
Trace("template parse file err:", err)
|
||||||
} else if submods1 != nil && len(submods1) > 0 {
|
} else if subMods1 != nil && len(subMods1) > 0 {
|
||||||
t, err = _getTemplate(t, root, submods1, others...)
|
t, err = _getTemplate(t, root, subMods1, others...)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//second check define
|
//second check define
|
||||||
for _, otherfile := range others {
|
for _, otherFile := range others {
|
||||||
fileabspath := filepath.Join(root, otherfile)
|
fileAbsPath := filepath.Join(root, otherFile)
|
||||||
data, err := ioutil.ReadFile(fileabspath)
|
data, err := ioutil.ReadFile(fileAbsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"")
|
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"")
|
||||||
allsub := reg.FindAllStringSubmatch(string(data), -1)
|
allSub := reg.FindAllStringSubmatch(string(data), -1)
|
||||||
for _, sub := range allsub {
|
for _, sub := range allSub {
|
||||||
if len(sub) == 2 && sub[1] == m[1] {
|
if len(sub) == 2 && sub[1] == m[1] {
|
||||||
var submods1 [][]string
|
var subMods1 [][]string
|
||||||
t, submods1, err = getTplDeep(root, otherfile, "", t)
|
t, subMods1, err = getTplDeep(root, otherFile, "", t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("template parse file err:", err)
|
Trace("template parse file err:", err)
|
||||||
} else if submods1 != nil && len(submods1) > 0 {
|
} else if subMods1 != nil && len(subMods1) > 0 {
|
||||||
t, err = _getTemplate(t, root, submods1, others...)
|
t, err = _getTemplate(t, root, subMods1, others...)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -70,10 +70,10 @@ func TestTemplate(t *testing.T) {
|
|||||||
if err := BuildTemplate(dir); err != nil {
|
if err := BuildTemplate(dir); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if len(BeeTemplates) != 3 {
|
if len(beeTemplates) != 3 {
|
||||||
t.Fatalf("should be 3 but got %v", len(BeeTemplates))
|
t.Fatalf("should be 3 but got %v", len(beeTemplates))
|
||||||
}
|
}
|
||||||
if err := BeeTemplates["index.tpl"].ExecuteTemplate(os.Stdout, "index.tpl", nil); err != nil {
|
if err := beeTemplates["index.tpl"].ExecuteTemplate(os.Stdout, "index.tpl", nil); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, name := range files {
|
for _, name := range files {
|
||||||
@ -126,7 +126,7 @@ func TestRelativeTemplate(t *testing.T) {
|
|||||||
if err := BuildTemplate(dir, files[1]); err != nil {
|
if err := BuildTemplate(dir, files[1]); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := BeeTemplates["easyui/rbac/user.tpl"].ExecuteTemplate(os.Stdout, "easyui/rbac/user.tpl", nil); err != nil {
|
if err := beeTemplates["easyui/rbac/user.tpl"].ExecuteTemplate(os.Stdout, "easyui/rbac/user.tpl", nil); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, name := range files {
|
for _, name := range files {
|
||||||
|
9
tree.go
9
tree.go
@ -265,15 +265,14 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string,
|
|||||||
}
|
}
|
||||||
t.wildcard.addseg(segments[1:], route, append(wildcards, params...), reg+regexpStr)
|
t.wildcard.addseg(segments[1:], route, append(wildcards, params...), reg+regexpStr)
|
||||||
} else {
|
} else {
|
||||||
var ok bool
|
|
||||||
var subTree *Tree
|
var subTree *Tree
|
||||||
for _, subTree = range t.fixrouters {
|
for _, sub := range t.fixrouters {
|
||||||
if t.prefix == seg {
|
if sub.prefix == seg {
|
||||||
ok = true
|
subTree = sub
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !ok {
|
if subTree == nil {
|
||||||
subTree = NewTree()
|
subTree = NewTree()
|
||||||
subTree.prefix = seg
|
subTree.prefix = seg
|
||||||
t.fixrouters = append(t.fixrouters, subTree)
|
t.fixrouters = append(t.fixrouters, subTree)
|
||||||
|
12
tree_test.go
12
tree_test.go
@ -221,6 +221,18 @@ func TestAddTree4(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test for issue #1595
|
||||||
|
func TestAddTree5(t *testing.T) {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter("/v1/shop/:id", "shopdetail")
|
||||||
|
tr.AddRouter("/v1/shop/", "shophome")
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := tr.Match("/v1/shop/", ctx)
|
||||||
|
if obj == nil || obj.(string) != "shophome" {
|
||||||
|
t.Fatal("url /v1/shop/ need match router /v1/shop/ ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSplitPath(t *testing.T) {
|
func TestSplitPath(t *testing.T) {
|
||||||
a := splitPath("")
|
a := splitPath("")
|
||||||
if len(a) != 0 {
|
if len(a) != 0 {
|
||||||
|
@ -588,7 +588,7 @@ func (b Base64) GetLimitValue() interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// just for chinese mobile phone number
|
// just for chinese mobile phone number
|
||||||
var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][0679]|[4][579]))\\d{8}$")
|
var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][06789]|[4][579]))\\d{8}$")
|
||||||
|
|
||||||
// Mobile check struct
|
// Mobile check struct
|
||||||
type Mobile struct {
|
type Mobile struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user