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.
I believe all you need to do is remove this line:
router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("view/"))))
Works for me. Though you need to clean up your html a bit too - I see at least a missing </div>
.
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.