This is the 11th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021

Based on the previous article, this paper continues to study the integration of static resource files, mainly in the integration of web servers.

basis

There are many web service frameworks in Golang, and GIN is chosen for this article. Gin is convenient for implementing a Web service in just a few lines of code. But some improvements are needed to accommodate more complex projects. For easy management, put the latter in the static directory — as in the previous article — and put the former in the templates directory. Render it using GIN’s HTML templates. Gin also supports custom template files, which are just right for our scenario.

practice

Resource file

The resource files used in this article are as follows:

$ tree static/ static/ |-- css | |-- bootstrap.min.css | |-- font-awesome.min.css | `-- main.css |-- favicon.ico `-- js | - the bootstrap. Min. Js | - jquery - 1.8.3. Min. Js | - jquery - 2.0.0. Min. Js ` -- main. Js 2 directories, 8 files $ tree templates/ templates/ |-- about.html |-- about.js |-- index.html |-- login.html |-- login.js `-- nav.js 0  directories, 6 filesCopy the code

General way

To facilitate comparison, the general GIN framework is first presented, with the main code as follows:

Func webServerFile() {fmt.println ("gin test...") Router. LoadHTMLGlob("templates/*") // Prefix the actual directory with a different prefix. Easy to reference CSS js files // some self-implemented with HTML files or JS files, with HTML prefix. router.StaticFS("/js", http.Dir("static/js")) router.StaticFS("/css", http.Dir("static/css")) router.StaticFS("/html", http.Dir("templates")) router.GET("/", HandleIndex) router.GET("/index", HandleIndex) router.GET("/about", HandleAbout) router.GET("/login", HandleLogin) router.Run(":8081") }Copy the code

LoadHTMLGlob is used to load an HTML template file, StaticFS specifies a static resource, and takes two parameters, the first specifying the prefix name (the path used when referenced in an HTML or JS file) and the second specifying the real path (relative to the directory where the Web program resides). The GET function is used to respond to the corresponding page. Since the response function is not the focus of this paper, it is simply listed as follows:

func HandleIndex(ctx *gin.Context) {
    file := path.Join(gPrefix, "index.html")
    ctx.HTML(http.StatusOK, file, gin.H{
        "title":  "Main website",
    })
}
Copy the code

Note: gPrefix will be mentioned below.

Integrated way

Using bindata is essentially the same as the example above, except that you need to manually set the template loading rules and specify static resource files differently. The main code is as follows:

Func webServerBindata() {fmt.println ("gin test....." ) router := gin.Default() t, err := loadTemplate() if err ! = nil {panic(err)} router.sethtmlTemplate (t) // The following is a static resource file, does not respond to get/post address FSJS := assetfs.assetfs {Asset: bindata.Asset, AssetDir: bindata.AssetDir, AssetInfo: bindata.AssetInfo, Prefix: "static/js", Fallback: "index.html", } router.StaticFS("/js", &fsjs) fscss := assetfs.AssetFS{ Asset: bindata.Asset, AssetDir: bindata.AssetDir, AssetInfo: bindata.AssetInfo, Prefix: "static/css", Fallback: "index.html", } router.StaticFS("/css", &fscss) fshtml := assetfs.AssetFS{ Asset: bindata.Asset, AssetDir: bindata.AssetDir, AssetInfo: bindata.AssetInfo, Prefix: "templates", Fallback: "Index. HTML ",} router.StaticFS("/ HTML ", &fshtml) router. The HTML path loaded by the loadTemplate contains a path prefix, so add // if manually deleted, Router. GET("/index", HandleIndex) router.GET("/index", HandleIndex) router.GET("/about", HandleAbout) router.GET("/login", HandleLogin) router.Run(":8081") }Copy the code

Custom template loading functions are as follows:

func loadTemplate() (*template.Template, error) { fmt.Println("load my template") t := template.New("") filenames := bindata.AssetNames() for _, name := range filenames { if ! strings.HasSuffix(name, ".tmpl") && ! strings.HasSuffix(name, ".html") && ! strings.HasSuffix(name, ".css") && ! strings.HasSuffix(name, ".js") && ! strings.HasSuffix(name, ".ico") { continue } //fmt.Println("got html file: ", name) content, err := bindata.Asset(name) if err ! = nil { return nil, err } t, err = t.New(name).Parse(string(content)) if err ! = nil { return nil, err } } return t, nil }Copy the code

Since there are two directories specified when bindata.go is generated and only one prefix can be specified with the -prefix option, this parameter is not added at all. Therefore, the generated code also shows the corresponding directory for the prefix, which is why the code uses gPrefix = “templates” to specify the prefix manually. Later, manually remove the prefix from the generated code with the following command:

sed -i 's/templates///g' bindata/bindata.go
sed -i 's/static///g' bindata/bindata.go
Copy the code

The two key code pairs are shown below (note: code with undeleted prefixes is on the left).

The author read the Go-bindata-assetFS code and tried to add parameters to achieve the goal, but failed, and still implemented according to its mechanism.

reference

Jaycechant. Info / 2020 / go – bin… Blog.hotsun168.com/index.php/a… Version 1.16 new way: www.flysnow.org/2021/02/28/…