なるべく必要最低限のファイル数、
実際に書くような構成で実装してみた。
ファイル構成
main.go
/app
  ├ infrastructure
  │  ├ Config.go
  │  └ Routing.go
  │
  └ interfaces
     └ presenters
        └ index.tmpl
/assets
  ├ css
  │  └ style.css
  │
  └ js
     └ script.js
サンプルコード
main.go
package main
import (
	"github.com/psychedelicnekopunch/xxxxx/app/infrastructure"
)
func main() {
	r := infrastructure.NewRouting()
	r.Run()
}
/app/infrastructure/Config.go
色んな記事でテンプレートや静的ファイル場所を相対パスで指定していた。
supervisor でデーモン化した時に絶対パスじゃないとちゃんと動かなかったので、
Config.go でパス指定できるようにした。
package infrastructure
type Config struct {
	AbsolutePath string
}
func NewConfig() *Config {
	c := new(Config)
	c.AbsolutePath = "/var/www/html/psychedelicnekopunch/xxxxx"
	return c
}
/app/infrastructure/Routing.go
package infrastructure
import (
	"html/template"
	"net/http"
	"github.com/gin-gonic/gin"
	"github.com/microcosm-cc/bluemonday"
	"gopkg.in/russross/blackfriday.v2"
)
type Routing struct {
	AbsolutePath string
}
func NewRouting() *Routing {
	c := NewConfig()
	r := &Routing{
		AbsolutePath: c.AbsolutePath,
	}
	r.loadTemplates()
	r.setRouting()
	return r
}
func (r *Routing) loadTemplates() {
	r.Gin.Static("/css", r.AbsolutePath + "/assets/css")
	r.Gin.Static("/js", r.AbsolutePath + "/assets/js")
	r.Gin.LoadHTMLFiles(
		r.AbsolutePath + "/app/interfaces/presenters/index.tmpl",
	)
}
func (r *Routing) setRouting() {
	r.Gin.GET("/", func (c *gin.Context) {
		c.HTML(http.StatusOK, "index.tmpl", nil)
	})
}
func (r *Routing) Run() {
	r.Gin.Run(":8180")
}
/app/interfaces/presenters/index.tmpl
{{ define "index.tmpl" }}
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>psychedelicnekopunch</title>
	<link rel="stylesheet" href="/css/style.css">
	<script type="text/javascript" src="/js/script.js"></script>
</head>
<body>
	<h1>psychedelicnekopunch</h1>
	index<br>
</body>
</html>
{{ end }}
js ファイルと css ファイル
適当に呼ばれていることがわかるように書く。