goweb(下)之模板引擎会话控制客户端(代码片段)

AC_Jobim AC_Jobim     2023-02-04     194

关键词:

GoWeb(下)之模板引擎、会话控制、客户端

一、模板引擎

  • Go 为我们提供了 text/template 库和 html/template 库这两个模板引擎,模板引擎通过将数据和模板组合在一起生成最终的 HTML,而处理器负责调用模板引擎并将引擎生成的 HTMl 返回给客户端。
  • Go 的模板都是文本文档(其中 Web 应用的模板通常都是 HTML),它们都嵌入了一些称为动作的指令。从模板引擎的角度来说,模板就是嵌入了动作的文本(这些文本通常包含在模板文件里面),而模板引擎则通过分析并执行这些文本来生成出另外一些文本。
  • text/template 库用于解析任意类型的文本格式模板,以及 html/template 库用于解析并处理 HTML 格式模板。

1.1 HelloWord

使用 Go 模板引擎通常包括以下两个步骤:

  • 解析文本模板源,可以是表单字符串、或者模板文件,用于创建解析后的模板结构体。
  • 执行解析后的模板,将 ResponseWriter 和模板所需的动态数据传递给模板引擎,被调用的模板引擎会把经过语法分析的模板和传入的数据结合起来,生成出最终的 HTML,并将这些 HTML 传递给 ResponseWriter。

下面就让我们写一个简单的 HelloWorld:

  • 创建模板文件 hello.html:

    <html>
        <head>
            <meta charset="UTF-8"/>
        </head>
        <body>
            后台传过来的数据是:.
        </body>
    </html>
    
  • 在处理器中触发模板引擎:

    func handler(w http.ResponseWriter, r *http.Request) 
    	//解析模板文件,返回Template
    	t, _ := template.ParseFiles("hello.html")
    	//执行模板,并将其传递个 w
    	t.Execute(w, "Hello World!")
    
    
    func main() 
    	http.HandleFunc("/hello", handler)
    	http.ListenAndServe(":8080", nil)
    
    
  • 浏览器的结果:HTML 模板解析渲染成功,对应的 . 也别替换成 Hello World!

1.2 解析模板

  • ParseFiles()方法

    func (t *Template) ParseFiles(filenames ...string) (*Template, error)
    

    ParseFiles()方法解析filenames指定的文件里的模板定义并将解析结果与t关联。如果发生错误,会停止解析并返回nil,否则返回(t, nil)。至少要提供一个文件。

    当我们调用 ParseFiles 函数解析模板文件时,Go 会创建一个新的模板,并将给定的模板文件的名字作为新模板的名字,如果该函数中传入了多个文件名,那么也只会返回一个模板,而且以第一个文件的文件名作为模板的名字,至于其他文件对应的模板则会被放到一个 map 中。

  • ParseGlob()方法

    func (t *Template) ParseGlob(pattern string) (*Template, error)
    

    方法传入的参数是模式匹配串,而不是文件名称

    t, _ := template.ParseFiles("tmpl.html")
    t, _ := template.ParseGlob("*.html")
    
  • Must()方法

    func Must(t *Template, err error) *Template
    

    我们在解析模板时都没有对错误进行处理,Go 提供了一个 Must 函数专门用来处理这个错误。Must 函数可以包裹起一个函数,被包裹的函数会返回一个指向模板的指针和一个错误,如果错误不是 nil,那么 Must 函数将产生一个 panic

    t := template.Must(template.ParseFiles("tmpl.html"))	//如果解析模板过程中出现问题,则抛出 panic
    

1.3 执行模板

  • Execute()方法

    如果只有一个模板文件,调用这个方法总是可行的;但是如果有多个模板文件,调用这个方法只能得到第一个模板,如果要指定其它模板作为入口模板(或者称之为布局模板),需要调用 ExecuteTemplate 方法并将模板名作为第二个参数传递进去

  • ExecuteTemplate()方法

例如:

t, _ := template.ParseFiles("hello.html", "hello2.html")

变量 t 就是一个包含了两个模板的模板集合,第一个模板的名字是hello.html,第二个模板的名字是 hello2.html,如果直接调用 Execute 方法,则只有模板 hello.html 会被执行,如何想要执行模板 hello2.html,则需要调用 ExecuteTemplate 方法

t.ExecuteTemplate(w, "hello2.html", "我要在 hello2.html 中显示")

1.4 引入静态资源

对于 HTML 页面中的 css 以及 js 等静态文件,需要使用使用 net/http 包下的以下方法来处理

  • StripPrefix()函数

  • FileServer()函数

    • type FileSystem

    • type Dir该类型实现了FileSystem接口的方法

http.StripPrefix()处理静态资源示例:

  • 项目的静态文件的目录结构

  • index.html模板文件中引入的css样式的地址

    <link type="text/css" rel="stylesheet" href="static/css/style.css" >
    
  • 对静态文件的处理

    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("views/static/"))))
    

    说明:/static/会匹配以 /static/开头的路径,当浏览器请求index.html页面中的style.css文件时,static前缀会被替换为views/static,然后去 views/static/css目录下查找style.css文件

    package main
    
    import (
    	"html/template"
    	"net/http"
    )
    
    // IndexHandler  去首页
    func IndexHandler(w http.ResponseWriter, r *http.Request)  
    	//解析模板
    	t := template.Must(template.ParseFiles("views/index.html"))
    	//执行
    	t.Execute(w, "")
    
    func main() 
    	//设置处理静态资源
    	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("views/static/"))))
    	http.Handle("/pages/", http.StripPrefix("/pages/", http.FileServer(http.Dir("views/pages/"))))
    	http.HandleFunc("/", IndexHandler)
    	http.ListenAndServe(":8080", nil)
    
    

http.FileServer()处理静态资源示例:

http.FileServer()接受一个http.FileSystem接口类型的变量

传入http.Dir类型变量,注意http.Dir是一个类型,其底层类型为string,并不是方法。因而http.Dir("")只是一个类型转换,而非方法调用

http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("./public"))))

这时,请求localhost:8080/static/hello.html将会返回./public/hello.html文件。路径/static/index.html经过处理器http.StripPrefix去掉了前缀/static得到/index.html,然后又加上了http.Dir的起始目录./public得到文件最终路径./public/hello.html

1.5 动作

Go 模板的动作就是一些嵌入到模板里面的命令,这些命令在模板中需要放到两个大括号里 动作 ,之前我们已经用过一个很重要的动作:点(.),它代表了传递给模板的数据。

1.5.1 .

模板语法都包含在中间,其中.中的点表示当前对象。

当我们传入一个结构体对象时,我们可以根据.来访问结构体的对应字段。例如:

package main

import (
	"html/template"
	"log"
	"net/http"
)
type Address struct 
	Province string
	City     string

type User struct 
	Name string
	Age  int
	Addr Address


func index(w http.ResponseWriter, r *http.Request) 
	//解析指定文件生成模板对象
	tmpl, err := template.ParseFiles("./public/index.html")
	if err != nil 
		log.Fatal(err)
	
	user := User
		Name: "彭于晏",
		Age:  28,
		Addr: AddressProvince: "台湾省", City: "澎湖县",
	
	//利用给定数据渲染模板,并将结果写入
	err = tmpl.Execute(w, user)
	if err != nil 
		log.Fatal(err)
	


func main() 

	//1.注册给定模式的处理器函数到DefaultServeMux
	http.HandleFunc("/index", index)

	//2.设置监听的TCP地址并启动服务
	//参数1:TCP地址(IP+Port)
	//参数2:当设置为nil时表示使用DefaultServeMux
	err := http.ListenAndServe("127.0.0.1:8080", nil)
	log.Fatal(err)

模板文件index.html内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index页面</title>
</head>
<body>
    <p>姓名:.Name</p>
    <p>年龄:.Age</p>
    <p>地址:.Addr.Province-.Addr.City</p>
    <p>你好呀/* 这是注释 */,彭于晏</p>
</body>
</html>

显示效果如下图所示:

移除空格:

template引擎在进行替换的时候,是完全按照文本格式进行替换的。除了需要评估和替换的地方,所有的行分隔符、空格等等空白都原样保留。所以,对于要解析的内容,不要随意缩进、随意换行

有时候我们在使用模板语法的时候会不可避免的引入一下空格或者换行符,这样模板最终渲染出来的内容可能就和我们想的不一样,这个时候可以使用-语法去除模板内容左侧的所有空白符号, 使用-去除模板内容右侧的所有空白符号。

注意-要紧挨,同时与模板值之间需要使用空格分隔。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index页面</title>
</head>
<body>
    <div align="center">
        <p>姓名:- .Name - -king</p> <!-- 彭于晏-king -->
        <p>姓名: .Name  -king</p> <!-- 彭于晏 -king -->
        <img src="./img/pyy.jpeg" style="width: 10%" alt="彭于晏">
    </div>
</body>
</html>

变量:

我们还可以在模板中声明变量,用来保存传入模板的数据或其他语句生成的结果。具体语法如下:

$obj := .

其中$obj是变量的名字,在后续的代码中就可以使用该变量了。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index页面</title>
</head>
<body>
    <div align="center">
        $obj := .Name
        <p>姓名: $obj </p>
    </div>
</body>
</html>

1.5.2 条件动作

Go模板语法中的条件判断有以下几种:

if pipeline T1 end

if pipeline T1 else T0 end

if pipeline T1 else if pipeline T0 end

注意:pipeline为false的情况是各种数据对象的0值:数值0,指针或接口是nil,数组、slice、map或string则是len为0。

示例:

<!-- 由于.Name不是空字符串,所以可以渲染出彭于晏 -->
<p>
    姓名:if .Name 
    	彭于晏
    eles
    	没有加载到数据!!!
    end
</p>

1.5.3 迭代动作

Go的模板语法中使用range关键字进行遍历,有以下两种写法,其中pipeline的值必须是数组、切片、map或者channel。

range pipeline 
T1 
end
<!-- 如果pipeline的值其长度为0,不会有任何输出 -->

range pipeline 
T1 
else 
T0 
end
<!-- 如果pipeline的值其长度为0,则会执行T0。 -->
  • 注意:range的参数部分是pipeline,所以在迭代的过程中是可以进行赋值的。但有两种赋值情况:

    range $value := .
    range $key,$value := .
    

    如果range中只赋值给一个变量,则这个变量是当前正在迭代元素的值。如果赋值给两个变量,则第一个变量是索引值(数组/切片是数值,map是key),第二个变量是当前正在迭代元素的值。

  • 如果迭代之后是一个个的结构体,获取结构体中的字段值使用 .字段名 方式获取

    range . 
    	获取结构体的 Name 字段名  .Name 
     end 
    
    <!-- 也可以这样写,结构体不能为nil -->
    range .Name 
    	获取结构体的 Name 字段名  .
     end 
    

    注意:range 后面的点代表被遍历的元素;要显示的内容里面的点代表遍历到的元素

示例:

  • 模板文件

    <html>
        <head>
            <title>模板文件</title>
            <meta charset="utf-8" />
        </head>
        <body>
            <!-- 嵌入动作,range 后面的点代表被遍历的元素;要显示的内容里面的点代表遍历到的元素 -->
            range .
            <a href="#">
                .
            </a>
            else
            没有遍历到任何内容
            end
        </body>
    </html>
    
  • 处理器端代码:

    func handler(w http.ResponseWriter, r *http.Request) 
    	//解析模板文件
    	t := template.Must(template.ParseFiles("hello.html"))
    	//声明一个字符串切片
    	stars := []string"马蓉", "李小璐", "白百何"
    	//执行模板
    	t.Execute(w, stars)
    
    
  • 浏览器中的结果:

1.5.4 设置动作

通过with指令设置动作允许在指定的范围内对点(.)设置值

格式一:在 with arg end 之间的 . 会被设置为 arg

 with arg 
为传过来的数据设置的新值是 . 
 end 

格式二:

 with arg 
为传过来的数据设置的新值是 . 
 else 
传过来的数据仍然是 . 
 end 

代码示例:

  • 模板文件:

    <html>
        <head>
            <title>模板文件</title>
            <meta charset="utf-8" />
        </head>
    
        <body>
            <!-- 嵌入动作 -->
            <div>得到的数据是:.</div>
            with "太子"
            <div>替换之后的数据是:.</div>
            end
    
            <hr />
    
            with ""
            <div>看一下现在的数据是:.</div>
            else
            <div>数据没有被替换,还是:.</div>
            end
        </body>
    </html>
    
  • 处理器端代码:

    func handler(w http.ResponseWriter, r *http.Request) 
    	//解析模板文件
    	t := template.Must(template.ParseFiles("hello.html"))
    	//执行模板
    	t.Execute(w, "狸猫")
    
    
  • 浏览器中的结果:

1.5.5 定义、嵌套模板

我们可以在template中嵌套其他的template。这个template可以是单独的文件,也可以是通过define定义的template。

嵌套模板:

  • 格式一:

     template “name” 
    

    name 为被包含的模板的名字

  • 格式二:

     template “name” arg 
    

    arg 是用户想要传递给被嵌套模板的数据

定义模板:

  • 对于一些网页中相同的部分,比如导航栏、版权信息、联系方式等。这些相同的布局我们可以通过定义动作在模板文件中定义模板来实现。定义模板的格式是:

     define “layout” 
    	模板文件的一些内容
     end 
    

代码示例:

  • hello.html模板文件:

    <html>
        <head>
            <title>模板文件</title>
            <meta charset="utf-8" />
        </head>
        <body>
            <!-- 嵌入动作 -->
            <div>从后台得到的数据是:.</div>
    
            <hr />
    
            <!-- 包含 hello2.html 模板 -->
            <div>hello2.html模板:</div>
             template "hello2.html"
            
            <hr />
    
            <div>将 hello.html 模板文件中的数据传递给 hello2.html模板文件:</div>
             template "hello2.html" . 
    
            <hr />
    
            <div>嵌套自己定义的content模板:</div>
             template "content"
        </body>
    </html>
    
    
     define "content"
        <div style="background-color: yellow;">我是自己定义的content模板文件中的内容</div>
     end 
    
  • hello2.html模板文件

    <html>
        <head>
            <title>hello2 模板文件</title>
            <meta charset="utf-8" />
        </head>
    
        <body>
            <!-- 嵌入动作 -->
            <div>hello2.html 模板文件中的数据是:.</div>
        </body>
    </html>
    
  • 处理器端代码:

    func 查看详情  

    goweb编程实战(10)----模板引擎库text/template包的使用(代码片段)

    目录前言模板引擎定义模板文件解析模板文件渲染模板实战使用模板创建.tmpl文件创建文件用于解析与渲染模板前言在Go语言中,模板引擎库text/template包主要用于处理任意格式的文本内容,同时还提供了html/template包,... 查看详情

    goweb开发之url路由设计(代码片段)

    ...址栏总有规律可循,可以让我们开发的网站更容易让搜索引擎收录,可以让我们开发者更加方便的MVC.我们在使用其他web开发框架的时候,url路由肯定也会作为框架的一个重点功能或者说是一个宣传”卖点”.所以说,一个web框架中url路... 查看详情

    springboot2之web开发(下)——数据响应模板引擎拦截器文件上传和异常处理(未完成)(代码片段)

    SpringBoot2之web开发(下)——数据响应、模板引擎、拦截器、文件上传和异常处理一、数据响应和内容协商1.1响应json数据1.2内容协商(待写)二、模板引擎(Thymeleaf)2.1模板引擎介绍2.2Thymeleaf语法2.2.1常用t... 查看详情

    理解node的模板引擎(代码片段)

    ...中通过调用res.render()渲染模块,并将其产生的页面返回给客户端。它 查看详情

    vue系列之概念

    ...板引擎通常出现在应用层,即服务器端(MVC层中的view)客户端HTTP请求->应用层的控制器(Controller)->应用层的服务层(Service,访问数据库)->封装到模型层(Model)->跳转到视图层(View,模板引擎)->生成HTML代码->返... 查看详情

    flask之视图,会话模板(代码片段)

    一、视图1、route(1)路由:  将从客户端发送过来的请求分发到指定函数上(2)语法:@app.route(‘/rule/’)defhello():return‘HelloWorld!’@app.route(‘/rule/<id>/’)defhello(id):return‘Hello’.format(id)(3)route规... 查看详情

    重学springboot系列之整合静态资源与模板引擎(代码片段)

    重学SpringBoot系列之整合静态资源与模板引擎webjars与静态资源springboot静态资源favicon.ico图标欢迎页面使用WebJars管理css&js1.pom中引入依赖2.访问引入的js文件自动检测依赖的版本测试模板引擎选型与未来趋势javaweb开发经历的几个... 查看详情

    26模板引擎thymeleaf(代码片段)

    ...到模板中,产生最终的HTML页面。模板引擎主要分两种:客户端引擎和服务端引擎。 客户端渲染: 模板和数据分别传送到客户端,在客户端由JavaScript模板引擎渲染出最终的HTML视图。将模板渲染放置在客户端做,可以降低... 查看详情

    26模板引擎thymeleaf(代码片段)

    ...到模板中,产生最终的HTML页面。模板引擎主要分两种:客户端引擎和服务端引擎。客户端渲染:?模板和数据分别传送到客户端,在客户端由JavaScript模板引擎渲染出最终的HTML视图。将模板渲染放置在客户端做,可以降低服务端... 查看详情

    pythonflask之模板引擎(代码片段)

    一、模板介绍1.1视图函数视图函数的主要作用是生成请求的响应,实际上视图函数有两个作用:处理业务逻辑返回响应内容在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本1.2模板... 查看详情

    pythonflask之模板引擎(代码片段)

    一、模板介绍1.1视图函数视图函数的主要作用是生成请求的响应,实际上视图函数有两个作用:处理业务逻辑返回响应内容在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本1.2模板... 查看详情

    goweb---web服务器(代码片段)

    ...http是比tcp更高层的协议,它描述了网页服务器如何与客户端浏览器进行通信。Go提供了net/http包,我们马上就来看下。我们引入了http包并启动了网页服务器,和之前的net.Listen( 查看详情

    goweb(上)之服务端处理请求请求响应(代码片段)

    GoWeb(上)之服务端、处理请求、请求响应一、服务端1.1构建服务器1.2处理器和处理器函数1.2.1处理器1.2.2处理器函数1.3多路复用器二、处理请求2.1获取请求URL2.2获取请求头中的信息2.3获取请求体中的信息2.4获取请求参数2.... 查看详情

    goweb(上)之服务端处理请求请求响应(代码片段)

    ...服务端Go语言标准库内建提供了net/http包,涵盖了HTTP客户端和服务端的具体实现。1.1构建服务器首先,我们编写一个最简单的Web服务器。编写这个Web服务只需要两步:注册一个处理器函数(注册到DefaultServeMux);设置监听... 查看详情

    会话跟踪之session(代码片段)

      Session是服务端使用记录客户端状态的一种机制,Session使用简单,但是和Cookie相比,增加了服务器的存储压力【因为为了追求速度,服务器将Session放置在了内存中】。Cookie是保存在客户端的,然而Session是保存在服务器上的... 查看详情

    模板引擎thymeleaf介绍及使用(代码片段)

    文章目录1.服务器生成动态页面的方式1.1客户端渲染(前后端分离)1.2服务器渲染(使用模板引擎)2.模板引擎2.1模板引擎介绍2.2模板引擎的作用2.3常见的模板引擎3.Thymeleaf3.1Thymeleaf介绍3.2Thymeleaf语法规则3.2.1标准... 查看详情

    模板引擎thymeleaf介绍及使用(代码片段)

    文章目录1.服务器生成动态页面的方式1.1客户端渲染(前后端分离)1.2服务器渲染(使用模板引擎)2.模板引擎2.1模板引擎介绍2.2模板引擎的作用2.3常见的模板引擎3.Thymeleaf3.1Thymeleaf介绍3.2Thymeleaf语法规则3.2.1标准... 查看详情