Clounea

第 3046 号会员 /

回复了 chris 创建的主题: 关于mgo这个go-mongodb驱动的问题

这个我来回答,前几天刚遇到这个问题。我的个人主页就是go+mongodb开发的,驱动用了mgo。前几天发现链接打不开,检查发现是too many open files的问题。linux里把什么设备啦都当成文件,检查进程的文件描述符发现大量指向mongodb,再检查源代码,发现是有几个处理函数打开了session忘关了。(defer也拯救不了的记性啧啧啧)。重新处理后上线就没这个问题了。
所以说,强烈建议处理函数打开session后加上defer session.Close()。也不缺这一点性能什么的。

回复了 Clounea 创建的主题: 关于web开发中动态加载模板的问题

把最后探索的include方法贴出来好了^_^坑已填平

一个用来传参的struct

   type ChildTemplate struct {
    Name         string
    Filenames    []string
    ChildContext interface{}
}

模板函数

func TemplateIncluder(args ...interface{}) template.HTML {
    if len(args) != 3 {
        log.Fatal("Wrong nums of args in TemplateIncluder,supposed to be 3")
        return ""
    }
    //get template name
    tname, ok := args[0].(string)
    if !ok {
        log.Fatal(("Wrong type of args[0]:template name in TemplateIncluder,supposed to be string"))
        return ""
    }
    //get template filenames []string
    tfnames, ok := args[1].([]string)
    if !ok {
        log.Fatal(("Wrong type of args[1]:template file names in TemplateIncluder,supposed to be []string"))
        return ""
    }
    //create template
    t := template.New(tname)
    for _, tfname := range tfnames {
        t = template.Must(t.ParseFiles(tfname))
    }

    //create buffer to contain the execute result
    buff := new(bytes.Buffer)
    err := t.ExecuteTemplate(buff, tname, args[2])
    if err != nil {
        log.Fatal("Something wrong in execute template in TemplateIncluder")
        return ""
    }

    return template.HTML(buff.String())

}

用来测试的handler函数

  func GetTestHandler(w http.ResponseWriter, r *http.Request) {
    t := template.New("testpage")
    t = t.Funcs(template.FuncMap{"include": TemplateIncluder})
    t, err := t.ParseFiles("static/templates/test.tmpl")
    if err != nil {
        log.Fatal("Wrong in parse files in test handler")
        panic(err)
    }

    context := [2]ChildTemplate{ChildTemplate{"child1", []string{"static/templates/child1.tmpl"}, nil},
        ChildTemplate{"child2", []string{"static/templates/child2.tmpl"}, nil}}

    err = t.ExecuteTemplate(w, "test", context)
    if err != nil {
        panic(err)
    }
}

对应的test.tmpl

{{define "test"}}
{{range .}}
{{include .Name .Filenames .ChildContext}}
{{end}}
{{end}}

需要注意的几点: 1.t.Func一定要在Parse前!因为Parse的过程就是根据注册和内置的各种处理方式把字符串翻译成动作和文本节点。Parse后再t.Func是会panic的 2.模板处理函数的返回值为template.HTML而不是string可以避免转义

回复了 Clounea 创建的主题: 关于web开发中动态加载模板的问题

hhhh楼上就是两层处理方式啊,第一次执行配置文件和模板,第二次再执行数据和生成模板及确定的子模板。我再看看有没有可能像之前发类似问题的仁兄一样通过写个include函数解决吧……实在找不到的话就这么做好了www

回复了 Clounea 创建的主题: 关于web开发中动态加载模板的问题

查了一下template的处理的源代码,结果简单粗暴(没人性QAQ)到吐血,先贴上来

    func (t *Tree) templateControl() Node {
    var name string
    token := t.nextNonSpace()
    switch token.typ {
    case itemString, itemRawString:
        s, err := strconv.Unquote(token.val)
        if err != nil {
            t.error(err)
        }
        name = s
    default:
        t.unexpected(token, "template invocation")
    }
    var pipe *PipeNode
    if t.nextNonSpace().typ != itemRightDelim {
        t.backup()
        // Do not pop variables; they persist until "end".
        pipe = t.pipeline("template")
    }
    return t.newTemplate(token.pos, t.lex.lineNumber(), name, pipe)
}

可以看出来了,读取到template后对于后面的读到空格前的token判断是不是所需要的字符串……对于不是要求的字符串的一致报错处理,是不会管对方是不是代表字符串的标识符还是函数名还是括号的……(感觉和整个template都脱节了)= = 求帮助吖,直接改源代码不怎么敢下手,用模板函数好像没什么用,代码里已经表示不会识别了= =究竟该怎么做呢? 求思路求帮助!

回复了 Clounea 创建的主题: 关于web开发中动态加载模板的问题

不是不能访问变量的问题…………看我题目啦,是

{{template .TemplateName}}

不能用的问题,没办法这么调用模板,这才是我要问的。不是什么range的问题(崩溃脸)

回复了 Clounea 创建的主题: 关于web开发中动态加载模板的问题

好像不行啊…… 如果说的是因为range而导致上下文不对,我不带range而是

{{template .NameA .}}
{{template .NameB .}}

也不行…… 如果是说template后用定义的$x……就会有错误提示unexpected "$x" in template invocation

回复了 Clounea 创建的主题: 关于GoLang嵌套模板和数据的问题

谢谢三楼,我刚接触确实不太会搞,还不怎么懂这个模板的语法、类C表达式之类的……OTL……去翻Doc也有很多不懂……可以的话能指引一下在哪里、怎么查这些用法么……