1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-26 09:14:06 +08:00
This commit is contained in:
shaoying 2019-05-13 02:16:26 +08:00
parent 7d27b56595
commit 3631a04bc5
16 changed files with 338 additions and 189 deletions

View File

@ -1,3 +1,5 @@
~aaa
role root user shy
~mdb ~mdb
note model favor spirit spirit relate relate note model favor spirit spirit relate relate
note model money expend expend amount amount note model money expend expend amount amount

View File

@ -906,7 +906,7 @@ func (m *Message) Magic(begin string, chain interface{}, args ...interface{}) in
func (m *Message) Current(text string) string { func (m *Message) Current(text string) string {
cs := []string{} cs := []string{}
if pod := kit.Format(m.Magic("session", "current.pod")); pod != "" { if pod := kit.Format(m.Magic("session", "current.pod")); pod != "" {
cs = append(cs, "context", "ssh", "sh", "node", "'"+pod+"'") cs = append(cs, "context", "ssh", "remote", "'"+pod+"'")
} }
if ctx := kit.Format(m.Magic("session", "current.ctx")); ctx != "" { if ctx := kit.Format(m.Magic("session", "current.ctx")); ctx != "" {
cs = append(cs, "context", ctx) cs = append(cs, "context", ctx)
@ -1540,7 +1540,7 @@ func (m *Message) Cmdm(args ...interface{}) *Message {
arg := []string{} arg := []string{}
if pod := kit.Format(m.Magic("session", "current.pod")); pod != "" { if pod := kit.Format(m.Magic("session", "current.pod")); pod != "" {
arg = append(arg, "context", "ssh", "sh", "node", pod) arg = append(arg, "context", "ssh", "remote", pod)
} }
if ctx := kit.Format(m.Magic("session", "current.ctx")); ctx != "" { if ctx := kit.Format(m.Magic("session", "current.ctx")); ctx != "" {
arg = append(arg, "context", ctx) arg = append(arg, "context", ctx)
@ -1793,7 +1793,9 @@ func (m *Message) Confv(key string, args ...interface{}) interface{} {
defer func() { m.target = target }() defer func() { m.target = target }()
ps := strings.Split(key, ".") ps := strings.Split(key, ".")
m.target, key = m.Sess(ps[0], false).target, ps[1] if msg := m.Sess(ps[0], false); msg != nil {
m.target, key = msg.target, ps[1]
}
} }
var config *Config var config *Config

View File

@ -982,7 +982,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
// 添加设备 // 添加设备
arg = arg[:0] arg = arg[:0]
if kit.Right(val["componet_pod"]) { if kit.Right(val["componet_pod"]) {
arg = append(arg, "sh", "node", kit.Format(m.Magic("session", "current.pod"))) arg = append(arg, "remote", kit.Format(m.Magic("session", "current.pod")))
} }
// 添加命令 // 添加命令
if kit.Right(val["componet_cmd"]) { if kit.Right(val["componet_cmd"]) {

View File

@ -160,7 +160,7 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
}, },
map[string]interface{}{"componet_name": "pod", "componet_help": "pod", "componet_tmpl": "componet", map[string]interface{}{"componet_name": "pod", "componet_help": "pod", "componet_tmpl": "componet",
"componet_view": "PodList", "componet_init": "initPodList", "componet_view": "PodList", "componet_init": "initPodList",
"componet_ctx": "ssh", "componet_cmd": "remote", "inputs": []interface{}{ "componet_ctx": "ssh", "componet_cmd": "node", "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "@current.pod"}, map[string]interface{}{"type": "text", "name": "pod", "value": "@current.pod"},
map[string]interface{}{"type": "button", "value": "refresh"}, map[string]interface{}{"type": "button", "value": "refresh"},
}, },

View File

@ -1,5 +1,9 @@
fieldset.Ocean { fieldset.Ocean {
position:absolute;
width:100px;
height:100px;
background-color:red;
display:none; display:none;
padding:0; padding:0;
} }

View File

@ -1,26 +1,36 @@
var pane = {}
var page = Page({ var page = Page({
initOcean: function(page, field, option) { pane: pane,
page.panes.ocean = field initOcean: function(page, field, option, output) {
ctx.Run(page, option.dataset, ["ocean"], function(msg) { return {"button": ["关闭"], "action": function(event) {
kit.Log(msg.result) pane.ocean.showDialog()
}) }}
return [{"text": ["ocean"]}]
}, },
initRiver: function(page, field, option, output) { initRiver: function(page, field, option, output) {
page.panes.river = field pane.channel = output
page.panes.channel = output
page.showRiver(page, option) page.showRiver(page, option)
return {"button": ["添加"], "action": function(value) { return {"button": ["添加", "查找"], "action": function(value) {
ctx.Run(page, option.dataset, ["river", "create", prompt("name")], function(msg) { switch (value) {
case "添加":
var name = prompt("name")
if (name) {
ctx.Run(page, option.dataset, ["river", "create", name], function(msg) {
page.showRiver(page, option) page.showRiver(page, option)
}) })
}
break
case "查找":
kit.showDialog(pane.ocean)
break
}
}} }}
}, },
showRiver: function(page, option) { showRiver: function(page, option) {
page.panes.channel.innerHTML = "" pane.channel.innerHTML = ""
page.getRiver(page, option, function(line, index) { page.getRiver(page, option, function(line, index) {
page.conf.river = page.conf.river || page.showTarget(page, option, line.key) || line.key page.conf.river = page.conf.river || page.showTarget(page, option, line.key) || line.key
kit.AppendChild(page.panes.channel, [{view: ["item", "div", line.name+"("+line.count+")"], click: function(event) { kit.AppendChild(pane.channel, [{view: ["item", "div", line.name+"("+line.count+")"], click: function(event) {
if (page.conf.river == line.key) { if (page.conf.river == line.key) {
return return
} }
@ -37,17 +47,16 @@ var page = Page({
}) })
}, },
initTarget: function(page, field, option) { initTarget: function(page, field, option) {
page.panes.target = field pane.output = field.querySelector("div.target.output")
page.panes.output = field.querySelector("div.target.output")
ctx.Run(page, option.dataset, ["river"], function(msg) { ctx.Run(page, option.dataset, ["river"], function(msg) {
kit.Log(msg.result) kit.Log(msg.result)
}) })
return [{"text": ["target"]}] return [{"text": ["target"]}]
}, },
showTarget: function(page, option, id) { showTarget: function(page, option, id) {
page.panes.output.innerHTML = "" pane.output.innerHTML = ""
page.getTarget(page, option, id, function(line, index) { page.getTarget(page, option, id, function(line, index) {
kit.AppendChild(page.panes.output, [{"view": ["item", "div", line.text]}]) kit.AppendChild(pane.output, [{"view": ["item", "div", line.text]}])
}) })
}, },
getTarget: function(page, option, id, cb) { getTarget: function(page, option, id, cb) {
@ -61,8 +70,8 @@ var page = Page({
var ui = kit.AppendChild(option, [{"view": ["input", "textarea"], "name": "input", "data": {"onkeyup": function(event){ var ui = kit.AppendChild(option, [{"view": ["input", "textarea"], "name": "input", "data": {"onkeyup": function(event){
if (event.key == "Enter" && !event.shiftKey) { if (event.key == "Enter" && !event.shiftKey) {
var value = event.target.value var value = event.target.value
kit.AppendChild(page.panes.output, [{"text" :[value, "div"]}]) kit.AppendChild(pane.output, [{"text" :[value, "div"]}])
page.panes.output.scrollBy(0,100) pane.output.scrollBy(0,100)
// event.target.value = "" // event.target.value = ""
ctx.Run(page, option.dataset, ["river", "wave", page.conf.river, "text", value], function(msg) { ctx.Run(page, option.dataset, ["river", "wave", page.conf.river, "text", value], function(msg) {
kit.Log(msg.result) kit.Log(msg.result)
@ -73,9 +82,8 @@ var page = Page({
event.preventDefault() event.preventDefault()
} }
}}}]) }}}])
page.panes.input = ui.input pane.input = ui.input
page.panes.source = field
ctx.Run(page, option.dataset, ["river"], function(msg) { ctx.Run(page, option.dataset, ["river"], function(msg) {
msg.Table(function(index, line) { msg.Table(function(index, line) {
console.log(index) console.log(index)
@ -86,14 +94,12 @@ var page = Page({
return return
}, },
initStorm: function(page, field, option) { initStorm: function(page, field, option) {
page.panes.storm = field
ctx.Run(page, option.dataset, ["river"], function(msg) { ctx.Run(page, option.dataset, ["river"], function(msg) {
kit.Log(msg.result) kit.Log(msg.result)
}) })
return [{"text": ["storm"]}] return [{"text": ["storm"]}]
}, },
initSteam: function(page, field, option) { initSteam: function(page, field, option) {
page.panes.steam = field
ctx.Run(page, option.dataset, ["river"], function(msg) { ctx.Run(page, option.dataset, ["river"], function(msg) {
kit.Log(msg.result) kit.Log(msg.result)
}) })
@ -104,46 +110,46 @@ var page = Page({
range: function(sizes) { range: function(sizes) {
sizes = sizes || {} sizes = sizes || {}
var width = document.body.offsetWidth var width = document.body.offsetWidth
var river_width = page.panes.river.offsetWidth var river_width = pane.river.offsetWidth
var storm_width = page.panes.storm.offsetWidth var storm_width = pane.storm.offsetWidth
var source_width = page.panes.source.offsetWidth var source_width = pane.source.offsetWidth
var source_height = page.panes.source.offsetHeight var source_height = pane.source.offsetHeight
var height = document.body.offsetHeight-80 var height = document.body.offsetHeight-80
page.panes.river.style.height = height+"px" pane.river.style.height = height+"px"
page.panes.storm.style.height = height+"px" pane.storm.style.height = height+"px"
page.panes.target.style.height = (height-source_height)+"px" pane.target.style.height = (height-source_height)+"px"
if (sizes.left != undefined) { if (sizes.left != undefined) {
if (sizes.left == 0) { if (sizes.left == 0) {
page.panes.river.style.display = "none" pane.river.style.display = "none"
} else { } else {
page.panes.river.style.display = "block" pane.river.style.display = "block"
page.panes.river.style.width = sizes.left+"px" pane.river.style.width = sizes.left+"px"
} }
} }
if (sizes.right != undefined) { if (sizes.right != undefined) {
if (sizes.right == 0) { if (sizes.right == 0) {
page.panes.storm.style.display = "none" pane.storm.style.display = "none"
} else { } else {
page.panes.storm.style.display = "block" pane.storm.style.display = "block"
page.panes.storm.style.width = sizes.right+"px" pane.storm.style.width = sizes.right+"px"
} }
} }
if (sizes.middle != undefined) { if (sizes.middle != undefined) {
page.panes.source.style.height = sizes.middle+"px" pane.source.style.height = sizes.middle+"px"
page.panes.target.style.height = (height-sizes.middle-4)+"px" pane.target.style.height = (height-sizes.middle-4)+"px"
page.panes.output.style.height = (height-sizes.middle-8)+"px" pane.output.style.height = (height-sizes.middle-8)+"px"
page.panes.input.style.height = (sizes.middle-7)+"px" pane.input.style.height = (sizes.middle-7)+"px"
} else { } else {
var source_height = page.panes.source.offsetHeight-10 var source_height = pane.source.offsetHeight-10
page.panes.input.style.height = source_height+"px" pane.input.style.height = source_height+"px"
page.panes.output.style.height = source_height+"px" pane.output.style.height = source_height+"px"
} }
var source_width = page.panes.source.offsetWidth-10 var source_width = pane.source.offsetWidth-10
page.panes.input.style.width = source_width+"px" pane.input.style.width = source_width+"px"
page.panes.output.style.width = source_width+"px" pane.output.style.width = source_width+"px"
}, },
init: function(exp) { init: function(exp) {
@ -152,6 +158,7 @@ var page = Page({
document.querySelectorAll("body>fieldset").forEach(function(field) { document.querySelectorAll("body>fieldset").forEach(function(field) {
var option = field.querySelector("form.option") var option = field.querySelector("form.option")
var output = field.querySelector("div.output") var output = field.querySelector("div.output")
pane[option.dataset.componet_name] = field
var init = page[field.dataset.init] var init = page[field.dataset.init]
if (typeof init == "function") { if (typeof init == "function") {

View File

@ -13,7 +13,6 @@ exp = example = {
return [{"text": ["shycontext", "div", "title"]}] return [{"text": ["shycontext", "div", "title"]}]
}, },
initField: function(page, field, option, output) { initField: function(page, field, option, output) {
ctx.Runs(page, option)
return return
}, },
initBanner: function(page, field, option, output) { initBanner: function(page, field, option, output) {
@ -30,6 +29,7 @@ exp = example = {
initFooter: function(page, field, option) { initFooter: function(page, field, option) {
return [{"view": ["title", "div", "<a href='mailto:shylinux@163.com'>shylinux@163.com</>"]}] return [{"view": ["title", "div", "<a href='mailto:shylinux@163.com'>shylinux@163.com</>"]}]
}, },
onscroll: function(event, target, action) { onscroll: function(event, target, action) {
var page = this var page = this
switch (action) { switch (action) {
@ -40,6 +40,7 @@ exp = example = {
break break
} }
}, },
onresize: function(event) {},
reload: function() { reload: function() {
location.reload() location.reload()
}, },
@ -51,3 +52,8 @@ function Page(page) {
} }
return page return page
} }
function Pane(pane) {
pane.showDialog = function(width, height) {
kit.showDialog(this, width, height)
}
}

View File

@ -420,6 +420,64 @@ kit = toolkit = {
} }
return true return true
}, },
setView: function(target, args) {
var width = document.body.offsetWidth-10
var height = document.body.offsetHeight-10
for (var k in args) {
switch (k) {
case "dialog":
var w = h = args[k]
if (typeof(args[k]) == "object") {
w = args[k][0]
h = args[k][1]
}
if (w > width) {
w = width
}
args["top"] = (height-h)/2
args["left"] = (width-w)/2
args["width"] = w
args["height"] = h
break
case "window":
var w = h = args[k]
if (typeof(args[k]) == "object") {
w = args[k][0]
h = args[k][1]
}
args["top"] = h/2
args["left"] = w/2
args["width"] = width-w
args["height"] = height-h
break
}
}
for (var k in args) {
switch (k) {
case "top":
case "left":
case "width":
case "height":
target.style[k] = args[k]+"px"
break
}
}
},
showDialog: function(pane, width, height) {
if (pane.style.display == "none") {
pane.style.display = "block"
this.setView(pane, {dialog: [width||800, height||400]})
} else {
pane.style.display = "none"
}
},
showWindow: function(pane, width, height) {
this.setView(pane, {window: [width||80, height||40]})
},
} }
function right(arg) { function right(arg) {

View File

@ -0,0 +1 @@
终端工具链/context.md

View File

@ -1,136 +1 @@
<canvas id="heart" width="400" height="400"></canvas> ## html5
## 简介
- 文档: <https://developer.mozilla.org/en-US/docs/Learn>
- 文档: <https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/>
### miniCAD在线绘图
<div class="cmd_shape bar"></div>
<div class="cmd_stroke bar"></div>
<div class="cmd_color bar"></div>
<div class="ctrl_show bar"></div>
<canvas id="draw" width="400" height="400"
onmousemove="draw_move(event)"
onmouseup="draw_point(event)"
></canvas>
<div class="ctrl_status bar"></div>
<div class="debug_info"></div>
<div class="ctrl_data bar"></div>
<table>
<thead>
<tr>
<th>color</th>
<th>stroke</th>
<th>shape</th>
<th>x1</th>
<th>y1</th>
<th>x2</th>
<th>y2</th>
<th>text</th>
</tr>
</thead>
<tbody id="draw_history"></tbody>
</table>
### canvas绘图
<canvas id="demo0" class="demo" width="120" height="120"></canvas>
```
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(10,10,100,100);
</script>
```
### 画矩形
```
fillRect(x, y, width, height)
strokeRect(x, y, width, height)
clearRect(x, y, width, height)
```
### 画路径
<canvas id="demo2" class="demo" width="120" height="120"></canvas>
```
<canvas id="demo2" width="120" height="120"></canvas>
<script>
var ctx2 = document.getElementById("demo2").getContext("2d");
ctx2.beginPath();
ctx2.moveTo(60,10);
ctx2.lineTo(10,110);
ctx2.lineTo(110,110);
ctx2.fill();
</script>
```
```
beginPath()
moveTo(x, y)
LineTo(x, y)
closePath()
stroke()
fill()
arc(x, y, radius, startAngle, endAngle, anticlockwise)
arcTo(x1, y1, x2, y2, radius)
quadraticCurveTo(cp1x, cp1y, x, y)
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
new Path2D()
```
### 设置样式
<canvas id="demo3" class="demo" width="120" height="120"></canvas>
```
fillStyle = "red"
fillStyle = "#FF0000"
fillStyle = "rgb(255,0,0)"
fillStyle = "rgb(255,0,0,1)"
strokeStyle =
var img = new Image();
img.src = "img.png";
img.onLoad = function() {}
createPattern(img, style)
createLinearGradient(x1, y1, x2, y2)
createRadialGradient(x1, y1, r1, x2, y2, r2)
addColorStop(position, color)
shadowOffsetX
shadowOffsetY
shadowBlur
shadowColor
lineWidth
lineCap
lineJoin
```
### 输出文字
```
font
textAlign
textBaseline
direction
measureText()
fillText(text, x, y[, maxWidth])
strokeText(text, x, y[, maxWidth])
```
### 坐标变换
```
save()
restore()
translate(x,y)
rotate(angle)
scale(x, y)
transform(a,b,c,d,e,f)
setTransform(a,b,c,d,e,f)
resetTransform()
```
<link rel="stylesheet" href="/wiki/html5.css" type="text/css"></link>
<script src="/wiki/html5.js"></script>

View File

@ -0,0 +1 @@
## javascript

View File

@ -0,0 +1,136 @@
<canvas id="heart" width="400" height="400"></canvas>
## 简介
- 文档: <https://developer.mozilla.org/en-US/docs/Learn>
- 文档: <https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/>
### miniCAD在线绘图
<div class="cmd_shape bar"></div>
<div class="cmd_stroke bar"></div>
<div class="cmd_color bar"></div>
<div class="ctrl_show bar"></div>
<canvas id="draw" width="400" height="400"
onmousemove="draw_move(event)"
onmouseup="draw_point(event)"
></canvas>
<div class="ctrl_status bar"></div>
<div class="debug_info"></div>
<div class="ctrl_data bar"></div>
<table>
<thead>
<tr>
<th>color</th>
<th>stroke</th>
<th>shape</th>
<th>x1</th>
<th>y1</th>
<th>x2</th>
<th>y2</th>
<th>text</th>
</tr>
</thead>
<tbody id="draw_history"></tbody>
</table>
### canvas绘图
<canvas id="demo0" class="demo" width="120" height="120"></canvas>
```
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(10,10,100,100);
</script>
```
### 画矩形
```
fillRect(x, y, width, height)
strokeRect(x, y, width, height)
clearRect(x, y, width, height)
```
### 画路径
<canvas id="demo2" class="demo" width="120" height="120"></canvas>
```
<canvas id="demo2" width="120" height="120"></canvas>
<script>
var ctx2 = document.getElementById("demo2").getContext("2d");
ctx2.beginPath();
ctx2.moveTo(60,10);
ctx2.lineTo(10,110);
ctx2.lineTo(110,110);
ctx2.fill();
</script>
```
```
beginPath()
moveTo(x, y)
LineTo(x, y)
closePath()
stroke()
fill()
arc(x, y, radius, startAngle, endAngle, anticlockwise)
arcTo(x1, y1, x2, y2, radius)
quadraticCurveTo(cp1x, cp1y, x, y)
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
new Path2D()
```
### 设置样式
<canvas id="demo3" class="demo" width="120" height="120"></canvas>
```
fillStyle = "red"
fillStyle = "#FF0000"
fillStyle = "rgb(255,0,0)"
fillStyle = "rgb(255,0,0,1)"
strokeStyle =
var img = new Image();
img.src = "img.png";
img.onLoad = function() {}
createPattern(img, style)
createLinearGradient(x1, y1, x2, y2)
createRadialGradient(x1, y1, r1, x2, y2, r2)
addColorStop(position, color)
shadowOffsetX
shadowOffsetY
shadowBlur
shadowColor
lineWidth
lineCap
lineJoin
```
### 输出文字
```
font
textAlign
textBaseline
direction
measureText()
fillText(text, x, y[, maxWidth])
strokeText(text, x, y[, maxWidth])
```
### 坐标变换
```
save()
restore()
translate(x,y)
rotate(angle)
scale(x, y)
transform(a,b,c,d,e,f)
setTransform(a,b,c,d,e,f)
resetTransform()
```
<link rel="stylesheet" href="/wiki/html5.css" type="text/css"></link>
<script src="/wiki/html5.js"></script>

View File

@ -327,10 +327,76 @@ chat模块提供了信息管理。
- iOS - iOS
- Android - Android
### 应用接口
context的应用模块都是web的子模块在web模块启动HTTP服务后会根据模块名与命令名自动生成路由。
web模块会将所有的HTTP请求转换成context的命令调用所以HTTP的应用接口和普通命令除了名字必须以"/"开头,其它没有太大区别。
当web接收到HTTP请求后可以调用单个命令如 http://shylinux.com/code/consul 就会调用code模块下的/consul命令
可以调用多个命令如 http://shylinux.com/code/?componet_group=login 就会调用web模块下的/render命令
根据code的componet下的login组件依次调用每个接口的命令然后将执行结果与参数一起调用golang的template渲染生成HTML。
所有命令都解析完成后就可以生成一个完整的网页。当然如果Accept是application/json则会跳过模块渲染直接返回多条命令的执行结果。
所以componet就是接口的集合统一提供参数配置、权限检查、命令执行、模板渲染降低内部命令与外部应用的耦合性但又将前后端完全融合在一起。
如下是web.code模块的应用接口定义。配置componet下定义了多个组件每个组件下定义了多个接口。
login就是登录页面下面定义了三个接口code、login、tail
其中code使用模板head生成网页头会包括一些配置如favicon可以指定图标文件styles指定引用模式表。
其中tail使用模板tail生成网页尾会包括一些配置如scripts指定引用脚本文件。
login就是网页组件了生成一个网页登录的输入表单并接收表单请求调用aaa模块的auth命令进行用户身份的验证。
其中arguments指定了Form表单字段的列表。
```
...
var Index = &ctx.Context{Name: "code", Help: "代码中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"skip_login": &ctx.Config{Name: "skip_login", Value: map[string]interface{}{"/consul": "true"}, Help: "免密登录"},
"componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
"login": []interface{}{
map[string]interface{}{"componet_name": "code", "componet_tmpl": "head", "metas": []interface{}{
map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"},
}, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}},
map[string]interface{}{"componet_name": "login", "componet_help": "login", "componet_tmpl": "componet",
"componet_ctx": "aaa", "componet_cmd": "auth", "componet_args": []interface{}{"@sessid", "ship", "username", "@username", "password", "@password"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "username", "value": "", "label": "username"},
map[string]interface{}{"type": "password", "name": "password", "value": "", "label": "password"},
map[string]interface{}{"type": "button", "value": "login"},
},
"display_append": "", "display_result": "",
},
map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail",
"scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"},
},
},
...
```
### 网页开发
#### 模板
usr/template 存放了网页的模板文件context会调用golang的template接口进行后端渲染生成html文件。
componet下每一个接口都会指定一个模板web模块下的/render命令会依次渲染从而生成一个完整的网页。
- usr/template/common.tmpl 公共模板
- usr/template/code/ code模块的模板
- usr/template/wiki/ wiki
- usr/template/chat/
usr/librarys 存放了css与js
### 小程序 ### 小程序
### 开发板 ### 开发板
## 接口开发 ## 接口开发
### componet
### python ### python
### java ### java
### c ### c

View File

@ -0,0 +1 @@
usr/wiki/自然/编程/前端小程序