1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-26 01:04:06 +08:00

tce opt ctx.cgi

This commit is contained in:
shaoying 2018-08-14 20:16:49 +08:00
parent da6859c5e0
commit 8f37fd7b23
7 changed files with 378 additions and 100 deletions

View File

@ -9,4 +9,3 @@ source etc/local.shy
alias import nfs
alias send send
alias dial dial
config debug on

View File

@ -1162,17 +1162,17 @@ func (m *Message) Sort(key string, arg ...string) *Message { // {{{
result = true
}
case "time":
ti, e := time.ParseInLocation(m.Conf("time_layout"), table[i][key], time.Local)
ti, e := time.ParseInLocation(m.Confx("time_layout"), table[i][key], time.Local)
m.Assert(e)
tj, e := time.ParseInLocation(m.Conf("time_layout"), table[j][key], time.Local)
tj, e := time.ParseInLocation(m.Confx("time_layout"), table[j][key], time.Local)
m.Assert(e)
if tj.Before(ti) {
result = true
}
case "time_r":
ti, e := time.ParseInLocation(m.Conf("time_layout"), table[i][key], time.Local)
ti, e := time.ParseInLocation(m.Confx("time_layout"), table[i][key], time.Local)
m.Assert(e)
tj, e := time.ParseInLocation(m.Conf("time_layout"), table[j][key], time.Local)
tj, e := time.ParseInLocation(m.Confx("time_layout"), table[j][key], time.Local)
m.Assert(e)
if ti.Before(tj) {
result = true
@ -1598,13 +1598,13 @@ func (m *Message) Confv(key string, args ...interface{}) interface{} { // {{{
hand = x.Hand
}
switch value := x.Value.(type) {
switch x.Value.(type) {
case string:
x.Value = fmt.Sprintf("%v", value)
x.Value = fmt.Sprintf("%v", args[0])
case bool:
x.Value = Right(fmt.Sprintf("%v", value))
x.Value = Right(fmt.Sprintf("%v", args[0]))
case int:
i, e := strconv.Atoi(fmt.Sprintf("%v", value))
i, e := strconv.Atoi(fmt.Sprintf("%v", args[0]))
m.Assert(e)
x.Value = i
case nil:
@ -1940,7 +1940,7 @@ var CGI = template.FuncMap{
}
if m, ok := arg[0].(*Message); ok {
if len(arg) == 1 {
return fmt.Sprintf("%v", m)
return fmt.Sprintf("%v", m.Format())
}
switch which := arg[1].(type) {
@ -2005,32 +2005,27 @@ var CGI = template.FuncMap{
}
return ""
}, // }}}
"conf": func(arg ...interface{}) string { // {{{
"conf": func(arg ...interface{}) interface{} { // {{{
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
if len(arg) == 1 {
return fmt.Sprintf("%v", m)
list := []string{}
for k, _ := range m.target.Configs {
list = append(list, k)
}
return list
}
switch which := arg[1].(type) {
case string:
if len(arg) == 2 {
return m.Conf(which)
}
switch value := arg[2].(type) {
case string:
return m.Conf(which, value)
case int:
return fmt.Sprintf("%d", m.Confi(which, value))
case bool:
return fmt.Sprintf("%t", m.Confs(which, value))
default:
return m.Conf(which, fmt.Sprintf("%v", arg[2]))
return m.Confv(which)
}
return m.Confv(which, arg[2:]...)
}
}
return ""
@ -2051,69 +2046,155 @@ var CGI = template.FuncMap{
return ""
}, // }}}
"detail": func(arg ...interface{}) string { // {{{
"detail": func(arg ...interface{}) interface{} { // {{{
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return strings.Join(m.Meta["detail"], "")
return m.Meta["detail"]
}
return m.Detail(arg[1:]...)
index := 0
switch value := arg[1].(type) {
case int:
index = value
case string:
i, e := strconv.Atoi(value)
m.Assert(e)
index = i
}
if len(arg) == 2 {
return m.Detail(index)
}
return m.Detail(index, arg[2])
case map[string][]string:
return strings.Join(m["detail"], "")
case []string:
return strings.Join(m, "")
default:
return fmt.Sprintf("%v", arg[0])
}
return ""
}, // }}}
"option": func(arg ...interface{}) string { // {{{
"option": func(arg ...interface{}) interface{} { // {{{
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return fmt.Sprintf("%v", m)
return m.Meta["option"]
}
switch which := arg[1].(type) {
switch value := arg[1].(type) {
case int:
if 0 <= value && value < len(m.Meta["option"]) {
return m.Meta["option"][value]
}
case string:
if len(arg) == 2 {
return m.Option(which)
return m.Meta[value]
}
return m.Option(which, arg[2:]...)
switch val := arg[2].(type) {
case int:
if 0 <= val && val < len(m.Meta[value]) {
return m.Meta[value][val]
}
}
}
case map[string][]string:
if len(arg) == 1 {
return strings.Join(m["option"], "")
}
switch value := arg[1].(type) {
case string:
return strings.Join(m[value], "")
}
case []string:
return strings.Join(m, "")
default:
return fmt.Sprintf("%v", arg[0])
}
return ""
}, // }}}
"result": func(arg ...interface{}) string { // {{{
"result": func(arg ...interface{}) interface{} { // {{{
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return strings.Join(m.Meta["result"], "")
return m.Meta["result"]
}
return m.Result(arg[1:]...)
index := 0
switch value := arg[1].(type) {
case int:
index = value
case string:
i, e := strconv.Atoi(value)
m.Assert(e)
index = i
}
if len(arg) == 2 {
return m.Result(index)
}
return m.Result(index, arg[2])
case map[string][]string:
return strings.Join(m["result"], "")
case []string:
return strings.Join(m, "")
default:
return fmt.Sprintf("%v", arg[0])
}
return ""
}, // }}}
"append": func(arg ...interface{}) string { // {{{
"append": func(arg ...interface{}) interface{} { // {{{
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return fmt.Sprintf("%v", m)
return m.Meta["append"]
}
switch which := arg[1].(type) {
switch value := arg[1].(type) {
case int:
if 0 <= value && value < len(m.Meta["append"]) {
return m.Meta["append"][value]
}
case string:
if len(arg) == 2 {
return m.Append(which)
return m.Meta[value]
}
return m.Append(which, arg[2:]...)
switch val := arg[2].(type) {
case int:
if 0 <= val && val < len(m.Meta[value]) {
return m.Meta[value][val]
}
}
}
case map[string][]string:
if len(arg) == 1 {
return strings.Join(m["append"], "")
}
switch value := arg[1].(type) {
case string:
return strings.Join(m[value], "")
}
case []string:
return strings.Join(m, "")
default:
return fmt.Sprintf("%v", arg[0])
}
return ""
}, // }}}

View File

@ -66,11 +66,26 @@ func (nfs *NFS) open(name string) (*os.File, error) { // {{{
}
// }}}
func dir(m *ctx.Message, name string, level int) { // {{{
func dir(m *ctx.Message, name string, level int, deep bool, fields []string) { // {{{
back, e := os.Getwd()
m.Assert(e)
os.Chdir(name)
defer os.Chdir(back)
s, e := os.Stat(".")
for _, k := range fields {
switch k {
case "filename":
m.Add("append", "filename", "..")
case "dir":
m.Add("append", "dir", "true")
case "size":
m.Add("append", "size", 0)
case "line":
m.Add("append", "line", 0)
case "time":
m.Add("append", "time", s.ModTime().Format("2006-01-02 15:04:05"))
}
}
if fs, e := ioutil.ReadDir("."); m.Assert(e) {
for _, f := range fs {
@ -119,15 +134,23 @@ func dir(m *ctx.Message, name string, level int) { // {{{
if !(m.Confx("dir_type") == "file" && f.IsDir() ||
m.Confx("dir_type") == "dir" && !f.IsDir()) {
m.Add("append", "filename", filename)
m.Add("append", "dir", f.IsDir())
m.Add("append", "size", f.Size())
m.Add("append", "line", line)
m.Add("append", "time", f.ModTime().Format("2006-01-02 15:04:05"))
for _, k := range fields {
switch k {
case "filename":
m.Add("append", "filename", filename)
case "dir":
m.Add("append", "dir", f.IsDir())
case "size":
m.Add("append", "size", f.Size())
case "line":
m.Add("append", "line", line)
case "time":
m.Add("append", "time", f.ModTime().Format("2006-01-02 15:04:05"))
}
}
}
if f.IsDir() {
dir(m, f.Name(), level+1)
if f.IsDir() && deep {
dir(m, f.Name(), level+1, deep, fields)
}
}
}
@ -815,7 +838,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"dir_name": &ctx.Config{Name: "dir_name(name/tree/path/full)", Value: "name", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"},
"dir_info": &ctx.Config{Name: "dir_info(sizes/lines/files/dirs)", Value: "sizes lines files dirs", Help: "dir命令输出目录的统计信息, info: 输出统计信息, 否则输出"},
"dir_deep": &ctx.Config{Name: "dir_deep(yes/no)", Value: "yes", Help: "dir命令输出目录的统计信息, info: 输出统计信息, 否则输出"},
"dir_type": &ctx.Config{Name: "dir_type(file/dir)", Value: "file", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"},
"dir_field": &ctx.Config{Name: "dir_field", Value: "filename line size time", Help: "表格排序字段"},
"sort_field": &ctx.Config{Name: "sort_field", Value: "line", Help: "表格排序字段"},
"sort_order": &ctx.Config{Name: "sort_order(int/int_r/string/string_r/time/time_r)", Value: "int", Help: "表格排序类型"},
@ -1093,7 +1118,11 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
// }}}
}},
"pwd": &ctx.Command{Name: "pwd", Help: "查看当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if len(arg) > 0 { // {{{
if m.Options("dir") { // {{{
m.Echo(m.Option("dir"))
return
}
if len(arg) > 0 {
os.Chdir(arg[0])
}
wd, e := os.Getwd()
@ -1101,14 +1130,19 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
m.Echo(wd) // }}}
}},
"dir": &ctx.Command{
Name: "dir dir [dir_info info] [dir_name name|tree|path|full] [dir_type file|dir] [sort_field name] [sort_order type]",
Name: "dir dir [dir_deep yes|no] [dir_info info] [dir_name name|tree|path|full] [dir_type file|dir] [sort_field name] [sort_order type]",
Help: "查看目录, dir: 目录名, dir_info: 显示统计信息, dir_name: 文件名类型, dir_type: 文件类型, sort_field: 排序字段, sort_order: 排序类型",
Form: map[string]int{"dir_info": 1, "dir_name": 1, "dir_type": 1, "sort_field": 1, "sort_order": 1},
Form: map[string]int{"dir_field": 1, "dir_deep": 1, "dir_info": 1, "dir_name": 1, "dir_type": 1, "sort_field": 1, "sort_order": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
d := "." // {{{
d := "./" + m.Option("dir") // {{{
if len(arg) > 0 {
d = arg[0]
}
if s, e := os.Stat(d); m.Assert(e) && !s.IsDir() {
d = path.Dir(d)
}
fields := strings.Split(m.Confx("dir_field"), " ")
trip := 0
if m.Confx("dir_name") == "path" {
wd, e := os.Getwd()
@ -1121,7 +1155,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
m.Option(v, 0)
}
dir(m, d, 0)
m.Option("time_layout", "2006-01-02 15:04:05")
dir(m, d, 0, ctx.Right(m.Confx("dir_deep")), fields)
m.Sort(m.Confx("sort_field"), m.Confx("sort_order"))
m.Table(func(maps map[string]string, list []string, line int) bool {
for i, v := range list {
@ -1145,9 +1180,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
// }}}
}},
"git": &ctx.Command{
Name: "git branch|status|diff|log|info arg... [git_path path]...",
Help: "版本控制, branch: 分支管理, status: 查看状态, info: 查看分支与状态, git_path: 指定路径",
Form: map[string]int{"git_path": 1, "git_info": 1, "git_log": 1, "git_log_form": 1},
Name: "git branch|status|diff|log|info arg... [dir path]...",
Help: "版本控制, branch: 分支管理, status: 查看状态, info: 查看分支与状态, dir: 指定路径",
Form: map[string]int{"dir": 1, "git_info": 1, "git_log": 1, "git_log_form": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if len(arg) == 0 { // {{{
arg = []string{"info"}
@ -1166,10 +1201,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
wd, e := os.Getwd()
m.Assert(e)
if !m.Has("git_path") {
m.Option("git_path", m.Conf("git_path"))
if !m.Has("dir") {
m.Option("dir", m.Confx("dir"))
}
for _, p := range m.Meta["git_path"] {
for _, p := range m.Meta["dir"] {
if !path.IsAbs(p) {
p = path.Join(wd, p)
}

View File

@ -15,6 +15,7 @@ import ( // {{{
"path"
"bytes"
"mime"
"mime/multipart"
"path/filepath"
@ -111,6 +112,7 @@ func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.C
http.Redirect(w, r, msg.Append("redirect"), http.StatusFound)
return
}
if msg.Has("template") {
msg.Spawn().Cmd("/render", msg.Meta["template"])
return
@ -145,6 +147,12 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{
}
}
r.Form.Add("path", r.URL.Path)
if strings.HasPrefix(r.URL.Path, "/index") {
r.Form.Add("dir", strings.TrimPrefix(r.URL.Path, "/index"))
r.URL.Path = "/index"
}
web.ServeMux.ServeHTTP(w, r)
if web.Message != nil && web.Confs("logheaders") {
@ -296,6 +304,37 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
"argument": []interface{}{"tmux", "show-buffer"},
"template": "result", "title": "buffer",
},
map[string]interface{}{
"module": "nfs", "command": "git",
"argument": []interface{}{},
"template": "result", "title": "git",
},
map[string]interface{}{
"module": "nfs", "command": "dir",
"argument": []interface{}{"dir_type", "all", "dir_deep", "false", "dir_field", "time size line filename", "sort_field", "time", "sort_order", "time_r"},
"template": "append", "title": "",
},
map[string]interface{}{
"template": "upload", "title": "upload",
},
map[string]interface{}{
"template": "create", "title": "create",
},
map[string]interface{}{
"module": "nfs", "detail": []interface{}{"pwd"},
"template": "detail", "title": "detail",
},
},
"xujianing": []interface{}{
map[string]interface{}{
"module": "nfs", "detail": []interface{}{"pwd"},
"template": "detail", "title": "detail",
},
map[string]interface{}{
"module": "nfs", "command": "dir",
"argument": []interface{}{"dir_type", "all", "dir_deep", "false", "dir_field", "time size line filename", "sort_field", "time", "sort_order", "time_r"},
"template": "append", "title": "",
},
},
}, Help: "资源列表"},
},
@ -564,9 +603,48 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
// }}}
}},
"/index": &ctx.Command{Name: "/index", Help: "网页门户", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
r := m.Optionv("request").(*http.Request)
w := m.Optionv("response").(http.ResponseWriter)
w.Header().Add("Content-Type", "text/html")
login := m.Spawn().Cmd("/login")
if login.Has("template") {
m.Copy(login, "append")
return
}
aaa := login.Appendv("aaa").(*ctx.Message)
list := m.Confv("index", aaa.Cap("username"))
if list == nil {
m.Echo("no right, please contact manager")
m.Append("template", "result")
return
}
if m.Options("details") {
if !ctx.Right(m.Find(m.Option("module")).Cmd("right", aaa.Cap("username"), "check", "command", m.Option("details")).Result(0)) {
m.Echo("no right, please contact manager")
m.Append("template", "result")
return
}
msg := m.Find(m.Option("module")).Cmd(m.Option("details"))
m.Copy(msg, "result").Copy(msg, "append")
return
}
dir := path.Join(m.Cap("directory"), m.Option("dir"))
if s, e := os.Stat(dir); e == nil && m.Option("dir") != "" && !s.IsDir() {
w.Header().Set("Content-type", mime.TypeByExtension(dir))
http.ServeFile(w, r, dir)
return
}
if !ctx.Right(m.Spawn(c).Cmd("right", aaa.Cap("username"), "check", "command", "/index", "dir", dir).Result(0)) {
m.Echo("no right, please contact manager")
m.Append("template", "result")
return
}
m.Option("dir", dir)
w.Header().Add("Content-Type", "text/html")
tpl := template.New("render").Funcs(ctx.CGI)
tpl = template.Must(tpl.ParseGlob(path.Join(m.Conf("template_dir"), m.Conf("common_tmpl"))))
tpl = template.Must(tpl.ParseGlob(path.Join(m.Conf("template_dir"), m.Conf("upload_tmpl"))))
@ -577,19 +655,37 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
[]byte{27, 91, 109}, []byte("</span>"),
}
list := m.Confv("index", "shy")
for _, v := range list.([]interface{}) {
val := v.(map[string]interface{})
msg := m.Find(val["module"].(string)).Cmd(val["command"], val["argument"])
for i, v := range msg.Meta["result"] {
b := []byte(v)
for i := 0; i < len(replace)-1; i += 2 {
b = bytes.Replace(b, replace[i], replace[i+1], -1)
}
msg.Meta["result"][i] = string(b)
if _, ok := val["detail"]; ok {
detail := val["detail"].([]interface{})
msg := m.Spawn().Add("detail", detail[0].(string), detail[1:])
msg.Option("title", val["title"])
msg.Option("module", val["module"])
m.Assert(tpl.ExecuteTemplate(w, val["template"].(string), msg))
continue
}
if _, ok := val["module"]; ok {
if _, ok := val["command"]; ok {
msg := m.Find(val["module"].(string)).Cmd(val["command"], val["argument"])
for i, v := range msg.Meta["result"] {
b := []byte(v)
for i := 0; i < len(replace)-1; i += 2 {
b = bytes.Replace(b, replace[i], replace[i+1], -1)
}
msg.Meta["result"][i] = string(b)
}
if msg.Option("title", val["title"]) == "" {
msg.Option("title", m.Option("dir"))
}
m.Assert(tpl.ExecuteTemplate(w, val["template"].(string), msg))
continue
}
}
if _, ok := val["template"]; ok {
m.Assert(tpl.ExecuteTemplate(w, val["template"].(string), m))
}
msg.Option("title", val["title"])
m.Assert(tpl.ExecuteTemplate(w, val["template"].(string), msg.Meta))
}
}},
"/travel": &ctx.Command{Name: "/travel", Help: "文件上传", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
@ -710,13 +806,9 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
// 共享列表
share := m.Sess("share", m.Target())
index := share.Target().Index
m.Log("fuck", "%v", share.Target().Index)
m.Log("fuck", "%v", aaa.Format())
if index != nil && index[aaa.Cap("username")] != nil {
for k, v := range index[aaa.Cap("username")].Index {
m.Log("fuck", "%v", v.Commands)
for _, j := range v.Commands {
m.Log("fuck", "%v", j.Shares)
for _, n := range j.Shares {
for _, nn := range n {
if match, e := regexp.MatchString(nn, m.Option("dir")); m.Assert(e) && match {
@ -925,19 +1017,15 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}},
"/render": &ctx.Command{Name: "/render [main [tmpl]]", Help: "模板响应, main: 模板入口, tmpl: 附加模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
w := m.Optionv("response").(http.ResponseWriter) // {{{
w.Header().Add("Content-Type", "text/html")
tpl := template.Must(template.New("render").Funcs(ctx.CGI).ParseGlob(path.Join(m.Conf("template_dir"), m.Conf("common_tmpl"))))
tpl := template.New("render").Funcs(ctx.CGI)
tpl = template.Must(tpl.ParseGlob(path.Join(m.Conf("template_dir"), m.Conf("common_tmpl"))))
if len(arg) > 1 {
tpl = template.Must(tpl.ParseGlob(path.Join(m.Conf("template_dir"), arg[1])))
}
main := m.Conf("common_main")
if len(arg) > 0 {
main = arg[0]
}
w.Header().Add("Content-Type", "text/html")
m.Assert(tpl.ExecuteTemplate(w, main, m.Message()))
m.Assert(tpl.ExecuteTemplate(w, m.Confx("common_main", arg, 0), m.Message()))
// }}}
}},
"/json": &ctx.Command{Name: "/json", Help: "json响应", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {

View File

@ -22,14 +22,95 @@
<body>
{{end}}
{{define "message"}}
<fieldset class="message"><legend>message</legend>
<pre>{{meta .message}}</pre>
{{define "notice"}}
<fieldset class="notice"><legend>notice</legend>
<pre>{{result .Meta}}</pre>
</fieldset>
<style>
.message {
color:red;
.notice {color:red}
</style>
{{end}}
{{define "detail"}}
<fieldset><legend>{{append . "title"}}</legend>
<a onclick="return action('{{option .Meta "module"}}', '{{detail .Meta}}')" href="/"><code>{{detail .Meta}}</code></a>
<pre><code class="result"></code></pre>
</fieldset>
<script>
function action(module, detail, cb) {
var xhr = new XMLHttpRequest();
cb = function(msg) {
var result = document.getElementsByClassName("result")[0];
result.innerHTML = msg.result;
}
xhr.onreadystatechange = function() {
switch (xhr.readyState) {
case 4:
switch (xhr.status) {
case 200:
try {
var msg = JSON.parse(xhr.responseText||'{"result":[]}');
} catch (e) {
msg = {"result": [xhr.responseText]}
}
msg && console.log(msg)
msg.result && console.log(msg.result.join(""));
typeof cb == "function" && cb(msg)
}
break;
}
}
xhr.open("POST", "?module="+encodeURIComponent(module)+"&details="+encodeURIComponent(detail));
xhr.send()
return false
}
</script>
{{end}}
{{define "result"}}
<fieldset><legend>{{append . "title"}}</legend>
<pre><code>{{result .Meta|unscaped}}</code></pre>
</fieldset>
{{end}}
{{define "append_link"}}
<td><a onclick="return jump('{{.}}')" href="{{.}}"><code>{{.}}</code></a></td>
<script>
function jump(to) {
location.href = location.href + "/" +to;
return false
}
</script>
{{end}}
{{define "append"}}
<fieldset><legend>{{append . "title"}}</legend>
<table class="append">
{{$msg := .}}
{{$ncol := append . |len}}
{{$nrow := append . 0|append .|len}}
<tr>{{range append .}}<th class="append_head">{{.}}</th>{{end}}</tr>
{{range $row, $val := append . 0|append .}}
<tr>
{{range append $msg}}
{{$value := append $msg . $row}}
{{if eq . "filename"}}
{{template "append_link" $value}}
{{else}}
<td><code>{{$value}}</code></td>
{{end}}
{{end}}
</tr>
{{end}}
</table>
</fieldset>
<style>
.append td {padding-right:20px}
.append th {background-color:lightgreen}
.append code {font-size:14px}
</style>
{{end}}

View File

@ -84,8 +84,8 @@
{{$meta := .Meta}}
{{template "head" $meta}}
{{if meta $meta.message}}
{{template "message" $meta}}
{{if meta $meta.notice}}
{{template "notice" $meta}}
{{end}}
{{template "login" $meta}}
{{template "tail" $meta}}

View File

@ -112,12 +112,6 @@
{{end}}
{{end}}
{{define "result"}}
<fieldset><legend>{{meta . "title"}}</legend>
<pre><code>{{meta . "result"|unscaped}}</code></pre>
</fieldset>
{{end}}
{{define "upload"}}
<fieldset><legend>upload</legend>
<form method="POST" action="/create?dir={{option . "dir"}}" enctype="multipart/form-data">