B5net

人生是场无尽旅途,欢声笑语,踟蹰彷徨,走过的是岁月,路过的是迷茫。向前,是希望极光;回首,是悠长深巷。

golang 中的html模板 actions指令使用方法

Published on:2022-11-02

在官方包中已有介绍,主要记录一些使用事项操作


一、关于 {{ . }} 的介绍


  "." 代表当前作用域的当前对象。

       一般情况下为顶级作用域(由ExecuteTemplate或gin的context.HTML中出入的第三个参数data)

       在 {{with pipeline}} {{.}} {{end}} 包含的里面中 {{ . }}代表with 中的pipeline

       在 {{range $index,$item := pipeline}}   {{ . }}  {{end}}  包含的里面中 {{ . }}代表当前循环的 $item

   如果想在range和with里面使用原来的顶级对象需要使用前缀$,即 使用$. 代表原来顶级.

{{ range $index,$item := .typeList}}
<input type="radio" value="{{$item.Key}}" {{if eq $.info.Type $item.Key}} checked {{end}}/>{{$item.Value}}
{{end}}


二、自定义方法的使用


   全局的方法或者通过func (*Template) Funcs 添加的 FunMap类型方法可以直接调用

{{ printf "%s其他文字" "替换文字" }}   //替换文字其他文字
{{ "替换文字22" | printf "%s其他文字11" }} //替换文字22其他文字11
{{ len .lists}}


自定义方法我们可以同像数据一样 传入一个map[string]any 键为函数名 值为函数体,使用call 关键字来调用

temp.ExecuteTemplate(ctx.Writer, "test/index", map[string]any{
"split": func(s string,sep string) []string{
return strings.Split(s,sep)
},
"join": func(elems []string,sep string) string {
return strings.Join(elems,sep)
},
"makeArray": func(args ...any) []any {
arr := make([]any, len(args))
for i := 0; i < len(args); i++ {
arr[i] = args[i]
}
return arr
},
})


在html中我们需要使用call 关键字来调用自定义方法

{{ $upload_img := call .makeArray "name:img_upload" "cat:demo" "link:1" "tips:格式为jpg,jpeg,png,gif;大小不能超过10M") }}
{{ $_file_list := call .split .info.FileList "," }}


在if中使用

{{range $index,$item := .roleList}}
<input type="checkbox" value="{{$item.Id}}"{{if call $.inArray $item.Id $.roleIds }} checked {{end}}/> {{$item.Name}}
{{end}}


三、html中显示html内容


直接将html通过数据传递到模板 会将html进行安全编码,在页面中显示的是html标签。需要使用

html/template 包下的HTML方法

template.HTML(xxxx)



官方文档

Actions

下面是一个action(动作)的列表。"Arguments"和"pipelines"代表数据的执行结果,细节定义在后面。

{{/* a comment */}}
    注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止,就像这里表示的一样。
{{pipeline}}
    pipeline的值的默认文本表示会被拷贝到输出里。
{{if pipeline}} T1 {{end}}
    如果pipeline的值为empty,不产生输出,否则输出T1执行结果。不改变dot的值。
    Empty值包括false、0、任意nil指针或者nil接口,任意长度为0的数组、切片、字典。
{{if pipeline}} T1 {{else}} T0 {{end}}
    如果pipeline的值为empty,输出T0执行结果,否则输出T1执行结果。不改变dot的值。
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
    用于简化if-else链条,else action可以直接包含另一个if;等价于:
        {{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}
{{range pipeline}} T1 {{end}}
    pipeline的值必须是数组、切片、字典或者通道。
    如果pipeline的值其长度为0,不会有任何输出;
    否则dot依次设为数组、切片、字典或者通道的每一个成员元素并执行T1;
    如果pipeline的值为字典,且键可排序的基本类型,元素也会按键的顺序排序。
{{range pipeline}} T1 {{else}} T0 {{end}}
    pipeline的值必须是数组、切片、字典或者通道。
    如果pipeline的值其长度为0,不改变dot的值并执行T0;否则会修改dot并执行T1。
{{template "name"}}
    执行名为name的模板,提供给模板的参数为nil,如模板不存在输出为""
{{template "name" pipeline}}
    执行名为name的模板,提供给模板的参数为pipeline的值。
{{with pipeline}} T1 {{end}}
    如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1。不修改外面的dot。
{{with pipeline}} T1 {{else}} T0 {{end}}
    如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1。

Arguments

参数代表一个简单的,由下面的某一条表示的值:

- go语法的布尔值、字符串、字符、整数、浮点数、虚数、复数,视为无类型字面常数,字符串不能跨行
- 关键字nil,代表一个go的无类型的nil值
- 字符'.'(句点,用时不加单引号),代表dot的值
- 变量名,以美元符号起始加上(可为空的)字母和数字构成的字符串,如:$piOver2和$;
  执行结果为变量的值,变量参见下面的介绍
- 结构体数据的字段名,以句点起始,如:.Field;
  执行结果为字段的值,支持链式调用:.Field1.Field2;
  字段也可以在变量上使用(包括链式调用):$x.Field1.Field2;
- 字典类型数据的键名;以句点起始,如:.Key;
  执行结果是该键在字典中对应的成员元素的值;
  键也可以和字段配合做链式调用,深度不限:.Field1.Key1.Field2.Key2;
  虽然键也必须是字母和数字构成的标识字符串,但不需要以大写字母起始;
  键也可以用于变量(包括链式调用):$x.key1.key2;
- 数据的无参数方法名,以句点为起始,如:.Method;
  执行结果为dot调用该方法的返回值,dot.Method();
  该方法必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
  如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;
  方法可和字段、键配合做链式调用,深度不限:.Field1.Key1.Method1.Field2.Key2.Method2;
  方法也可以在变量上使用(包括链式调用):$x.Method1.Field;
- 无参数的函数名,如:fun;
  执行结果是调用该函数的返回值fun();对返回值的要求和方法一样;函数和函数名细节参见后面。
- 上面某一条的实例加上括弧(用于分组)
  执行结果可以访问其字段或者键对应的值:
      print (.F1 arg1) (.F2 arg2)
      (.StructValuedMethod "arg").Field

Arguments可以是任何类型:如果是指针,在必要时会自动表示为指针指向的值;如果执行结果生成了一个函数类型的值,如结构体的函数类型字段,该函数不会自动调用,但可以在if等action里视为真。如果要调用它,使用call函数,参见下面。

Pipeline是一个(可能是链状的)command序列。Command可以是一个简单值(argument)或者对函数或者方法的(可以有多个参数的)调用:

Argument
    执行结果是argument的执行结果
.Method [Argument...]
    方法可以独立调用或者位于链式调用的末端,不同于链式调用中间的方法,可以使用参数;
    执行结果是使用给出的参数调用该方法的返回值:dot.Method(Argument1, etc.);
functionName [Argument...]
    执行结果是使用给定的参数调用函数名指定的函数的返回值:function(Argument1, etc.);

Pipelines

pipeline通常是将一个command序列分割开,再使用管道符'|'连接起来(但不使用管道符的command序列也可以视为一个管道)。在一个链式的pipeline里,每个command的结果都作为下一个command的最后一个参数。pipeline最后一个command的输出作为整个管道执行的结果。

command的输出可以是1到2个值,如果是2个后一个必须是error接口类型。如果error类型返回值非nil,模板执行会中止并将该错误返回给执行模板的调用者。

Variables

Action里可以初始化一个变量来捕获管道的执行结果。初始化语法如下:

$variable := pipeline

其中$variable是变量的名字。声明变量的action不会产生任何输出。

如果"range" action初始化了1个变量,该变量设置为迭代器的每一个成员元素,如果初始化了逗号分隔的2个变量:

range $index, $element := pipeline

这时,$index和$element分别设置为数组/切片的索引或者字典的键,以及对应的成员元素。注意这和go range从句只有一个参数时设置为索引/键不同!

一个变量的作用域只到声明它的控制结构("if"、"with"、"range")的"end"为止,如果不是在控制结构里声明会直到模板结束为止。子模板的调用不会从调用它的位置(作用域)继承变量。

模板开始执行时,$会设置为传递给Execute方法的参数,就是说,dot的初始值。

Functions

执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用Funcs方法添加函数到模板里。

预定义的全局函数如下:

and
    函数返回它的第一个empty参数或者最后一个参数;
    就是说"and x y"等价于"if x then y else x";所有参数都会执行;
or
    返回第一个非empty参数或者最后一个参数;
    亦即"or x y"等价于"if x then x else y";所有参数都会执行;
not
    返回它的单个参数的布尔值的否定
len
    返回它的参数的整数类型长度
index
    执行结果为第一个参数以剩下的参数为索引/键指向的值;
    如"index x 1 2 3"返回x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。
print
    即fmt.Sprint
printf
    即fmt.Sprintf
println
    即fmt.Sprintln
html
    返回其参数文本表示的HTML逸码等价表示。
urlquery
    返回其参数文本表示的可嵌入URL查询的逸码等价表示。
js
    返回其参数文本表示的JavaScript逸码等价表示。
call
    执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;
    如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2);
    其中Y是函数类型的字段或者字典的值,或者其他类似情况;
    call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同);
    该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
    如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;

布尔函数会将任何类型的零值视为假,其余视为真。

下面是定义为函数的二元比较运算的集合:

eq      如果arg1 == arg2则返回真
ne      如果arg1 != arg2则返回真
lt      如果arg1 < arg2则返回真
le      如果arg1 <= arg2则返回真
gt      如果arg1 > arg2则返回真
ge      如果arg1 >= arg2则返回真

为了简化多参数相等检测,eq(只有eq)可以接受2个或更多个参数,它会将第一个参数和其余参数依次比较,返回下式的结果:

arg1==arg2 || arg1==arg3 || arg1==arg4 ...

(和go的||不一样,不做惰性运算,所有参数都会执行)

比较函数只适用于基本类型(或重定义的基本类型,如"type Celsius float32")。它们实现了go语言规则的值的比较,但具体的类型和大小会忽略掉,因此任意类型有符号整数值都可以互相比较;任意类型无符号整数值都可以互相比较;等等。但是,整数和浮点数不能互相比较。






留言列表(0)

    留言

    B5net

    人生是场无尽旅途,欢声笑语,踟蹰彷徨,走过的是岁月,路过的是迷茫。向前,是希望极光;回首,是悠长深巷。

    开源项目
    最新评论
    34 :感谢你的开源项目
    奥德赛 on Electron+vue搭建项目或将vue项目转为electron :大声道奥术大师大声道
    cmf :你好 你的B5ThinkCMF下载后有点问题 能帮忙解决下么?
    laravel新手 :您好,laravel9+bootstrap3实现的快速开发后台,下载部署后,刷新加载,F12我看了下,我部署的是240毫秒左右,您部署的测试版本只有50毫秒左右,能辛苦指导下,如何优化lv吗,谢谢
    瀑布 :你好,yii我下载在本地后台,接口请求非常慢,通过debug我发现session_started执行时间很长,想问下这个是需要哪个地方配置吗?
    瀑布 :你好,今天看到你的开源项目,很喜欢,感谢你的开源
    冰舞 on Laravel定时任务的实现 :测试测试测试测试测试测试 测试测试测试测试测试测试测试测试测试测试
    文章分类