Golang模板无法渲染HTML。

huangapple go评论93阅读模式
英文:

Golang template does not render html

问题

我在我的网站根目录下创建了一个名为'views'的子文件夹。在Views文件夹中,我有一个包含CSS和JS文件的static文件夹。
当我将HTML文件放在网站根目录中时,它们可以正常渲染。但是,当我将它们放在views文件夹中时,它们无法渲染。我在代码中使用了template.ParseGlob来解析文件,并使用ExecuteTemplate来进行渲染。

为什么当我将HTML文件放在名为'views'的子目录中时,它们无法正常工作?唯一改变的是parseGlob的参数。

英文:

I created a subfolder called 'views' in my web root directory. Within the View folder, I have the static folder which contains the css and js files.
The html pages are rendered when I have the html files in the web root. However they do not render when placed within the views folder. I am using template.ParseGlob to parse the file and ExecuteTemplate to render.

package main

import (
	"html/template"
	"net/http"

	"github.com/gorilla/mux"
)

var router = mux.NewRouter()

var tmpl *template.Template

func init() {
	tmpl = template.Must(template.ParseGlob("view/*.html"))
}
func indexPage(w http.ResponseWriter, r *http.Request) {
	err := tmpl.ExecuteTemplate(w, "signin", nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func main() {
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("view/"))))
	router.HandleFunc("/", indexPage)
	http.ListenAndServe(":8091", router)
}

HTML files: Have defined the header and footer in index.html which I refernce in the signin.html file

 {{ define "header"}}
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>User Sign in</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/static/css/main.css">

<script src="/static/js/vendor/modernizr-2.8.3-respond-1.4.2.min.js"></script>
</head>
<body>
{{end}}

{{define "footer"}}
<footer class="panel-footer"><p>© Company 2016</p></footer>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.2.min.js"><\/script>')</script>

<script src="/static/js/vendor/bootstrap.min.js"></script>

<script src="/static/js/main.js"></script>

<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
<script>
            (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
            function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
            e=o.createElement(i);r=o.getElementsByTagName(i)[0];
            e.src='//www.google-analytics.com/analytics.js';
            r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
            ga('create','UA-XXXXX-X','auto');ga('send','pageview');
</script>
</body>
</html>
{{end}}

signin.html file:

    {{define "signin"}}
{{template "header" .}}
<h1 class="alert alert-info">Login</h1>
<div class="container">
    {{with .Errors.message}}
    <div class="alert alert-danger">
        {{.}}
    </div>
    {{end}}
    <form method="POST" action="/">
        <label class="form-control" for="uname">User Name</label>
        <input class="form-control" type="text" id="uname" name="uname">
        <label class="form-control" for="password">Password</label>
        <input class="form-control" type="password" id="password" name="password">
        <button class="btn btn-info" type="submit">Submit</button>
    </form>

{{template "footer" .}}
{{end}}

Why is it that this doesn't work when I place the html files in the sub-directory 'views'. The only thing that changes is the argument to parseGlob.

答案1

得分: 0

我相信你只需要删除这一行代码:

router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("view/")))))

对我来说有效。不过你还需要清理一下你的HTML代码——我至少看到一个缺少的</div>

模板是在服务器上处理的,不需要通过互联网提供。与此同时,这个路由条目与下面的一个冲突(indexPage),它为相同的路由条目("/")定义了另一个处理程序。所以当你在浏览器中打开它时,服务器只是将模板文件通过互联网发送出去。而indexPage处理程序从未被调用,因为目录处理程序首先匹配。

另外,你提到了"views"文件夹,但你的代码中写的是"view"(末尾没有's')。可能是另一个简单的原因。

英文:

I believe all you need to do is remove this line:

router.PathPrefix(&quot;/&quot;).Handler(http.StripPrefix(&quot;/&quot;, http.FileServer(http.Dir(&quot;view/&quot;))))

Works for me. Though you need to clean up your html a bit too - I see at least a missing &lt;/div&gt;.

Templates are processed on the server and do not need to be served over internet. At the same time this route entry conflicts with the following one (indexPage) which defines another handler for the same route entry ("/"). So when you open it in a browser, server just send template files over internet. While indexPage handler is never called as directory handler is matched first.

Also you talking about "views" folder, but you code says "view" (without 's' at the end). Could be another simple reason.

huangapple
  • 本文由 发表于 2017年1月20日 03:54:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/41750534.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定