all repos — auth-boilerplate @ c9e555264340b6f52d6c26a01bcfa00f5ab72e5b

A simple Go web-app boilerplate.

add a template engine
Marco Andronaco andronacomarco@gmail.com
Fri, 11 Oct 2024 10:06:32 +0200
commit

c9e555264340b6f52d6c26a01bcfa00f5ab72e5b

parent

16d9372b47e836a365f88331d564d1ac0cf8c25f

M go.modgo.mod

@@ -11,6 +11,7 @@ gorm.io/gorm v1.25.12

) require ( + github.com/dannyvankooten/extemplate v0.0.0-20221206123735-ea3f2b2b17ac // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/glebarez/go-sqlite v1.21.2 // indirect github.com/google/uuid v1.3.0 // indirect
M go.sumgo.sum

@@ -2,6 +2,8 @@ github.com/BiRabittoh/myks v0.0.0-20241010070553-ecfcd30b3ca1 h1:Dd9XkQaIIaIS6eTirtJlz0QWzo6Eg4yBt75iR+6Fobk=

github.com/BiRabittoh/myks v0.0.0-20241010070553-ecfcd30b3ca1/go.mod h1:jIJU6HMDJHJZL3LYR/mgOUeA5RTDEhqJNF+HcavHlsM= github.com/birabittoh/myks v0.0.2 h1:EBukMUsAflwiqdNo4LE7o2WQdEvawty5ewCZWY+IXSU= github.com/birabittoh/myks v0.0.2/go.mod h1:klNWaeUWm7TmhnBHBMt9vALwCHW11/Xw1BpCNkCx7hs= +github.com/dannyvankooten/extemplate v0.0.0-20221206123735-ea3f2b2b17ac h1:XYRFfWjEyxK41LxCSMwaWe23gVMM8OoFnBVpPXYmyzA= +github.com/dannyvankooten/extemplate v0.0.0-20221206123735-ea3f2b2b17ac/go.mod h1:64FAo5IpKaWzGExw1bQGujZRd6/55A8QUHuJbZZzOaI= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
M src/app/handlers.gosrc/app/handlers.go

@@ -12,24 +12,24 @@ http.Error(w, "Could not find user in context.", http.StatusInternalServerError)

return } - templates.ExecuteTemplate(w, "example.html", map[string]interface{}{"User": user}) + xt.ExecuteTemplate(w, "example.tmpl", map[string]interface{}{"User": user}) } func getRegisterHandler(w http.ResponseWriter, r *http.Request) { - templates.ExecuteTemplate(w, "register.html", nil) + xt.ExecuteTemplate(w, "register.tmpl", nil) } func getLoginHandler(w http.ResponseWriter, r *http.Request) { _, err := readSessionCookie(r) if err != nil { - templates.ExecuteTemplate(w, "login.html", nil) + xt.ExecuteTemplate(w, "login.tmpl", nil) return } http.Redirect(w, r, "/", http.StatusFound) } func getResetPasswordHandler(w http.ResponseWriter, r *http.Request) { - templates.ExecuteTemplate(w, "reset_password.html", nil) + xt.ExecuteTemplate(w, "reset_password.tmpl", nil) } func postRegisterHandler(w http.ResponseWriter, r *http.Request) {

@@ -127,7 +127,7 @@ http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)

return } - templates.ExecuteTemplate(w, "new_password.html", nil) + xt.ExecuteTemplate(w, "new_password.tmpl", nil) } func postResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
M src/app/init.gosrc/app/init.go

@@ -1,7 +1,6 @@

package app import ( - "html/template" "log" "net/http" "os"

@@ -12,6 +11,7 @@

"github.com/birabittoh/auth-boilerplate/src/auth" "github.com/birabittoh/auth-boilerplate/src/email" "github.com/birabittoh/myks" + "github.com/dannyvankooten/extemplate" "github.com/glebarez/sqlite" "github.com/joho/godotenv" "gorm.io/gorm"

@@ -36,6 +36,7 @@ var (

db *gorm.DB g *auth.Auth m *email.Client + xt *extemplate.Extemplate baseUrl string port string

@@ -44,7 +45,6 @@

ks = myks.New[uint](0) durationDay = 24 * time.Hour durationWeek = 7 * durationDay - templates = template.Must(template.ParseGlob("templates/*.html")) ) const userContextKey key = 0

@@ -85,6 +85,13 @@ log.Fatal(err)

} db.AutoMigrate(&User{}) + + // Init template engine + xt = extemplate.New() + err = xt.ParseDir("templates", []string{".tmpl"}) + if err != nil { + log.Fatal(err) + } // Handle routes http.HandleFunc("GET /", loginRequired(examplePage))
M templates/example.htmltemplates/base.tmpl

@@ -4,15 +4,15 @@

<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Protected page</title> + <title>{{block "title" .}}Page title{{end}}</title> <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"> <link rel="stylesheet" href="/static/style.css"> </head> <body> - <h1>Welcome, <i>{{.User.Username}}</i>!</h1> - <p>This page is only accessible by users who have logged in.</p> - <a href="/logout">Logout</a> + {{block "content" .}} + <h1>Base template</h1> + {{end}} </body> </html>
A templates/example.tmpl

@@ -0,0 +1,9 @@

+{{ extends "base.tmpl" }} + +{{define "title" -}}Protected page{{end}} + +{{define "content" -}} + <h1>Welcome, <i>{{.User.Username}}</i>!</h1> + <p>This page is only accessible by users who have logged in.</p> + <a href="/logout">Logout</a> +{{end}}
M templates/login.htmltemplates/login.tmpl

@@ -1,16 +1,9 @@

-<!DOCTYPE html> -<html lang="en"> +{{ extends "base.tmpl" }} -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Login</title> - <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"> - <link rel="stylesheet" href="/static/style.css"> -</head> +{{define "title" -}}Login{{end}} -<body> - <h1>Login</h1> +{{define "content" -}} + <h1>Login</h1> <form method="post" action="/login"> <label> <span>Username:</span>

@@ -28,6 +21,4 @@ <input type="submit" value="Login">

</form> <a href="/register">Sign up</a> <a href="/reset-password">Reset password</a> -</body> - -</html> +{{end}}
D templates/new_password.html

@@ -1,23 +0,0 @@

-<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Reset password</title> - <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"> - <link rel="stylesheet" href="/static/style.css"> -</head> - -<body> - <h1>Reset password</h1> - <form method="post"> - <label> - <span>New password:</span> - <input type="password" name="password" placeholder="Max 56 chars, ASCII only" required> - </label> - <input type="submit" value="Reset password"> - </form> -</body> - -</html>
A templates/new_password.tmpl

@@ -0,0 +1,14 @@

+{{ extends "base.tmpl" }} + +{{define "title" -}}Reset password{{end}} + +{{define "content" -}} +<h1>Reset password</h1> +<form method="post"> + <label> + <span>New password:</span> + <input type="password" name="password" placeholder="Max 56 chars, ASCII only" required> + </label> + <input type="submit" value="Reset password"> +</form> +{{end}}
D templates/register.html

@@ -1,33 +0,0 @@

-<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Sign up</title> - <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"> - <link rel="stylesheet" href="/static/style.css"> -</head> - -<body> - <h1>Sign up</h1> - <form method="post" action="/register"> - <label> - <span>Username:</span> - <input type="text" name="username" placeholder="^[a-z0-9._-]+$" required> - </label> - <label> - <span>Email:</span> - <input type="email" name="email" placeholder="Email" required> - </label> - <label> - <span>Password:</span> - <input type="password" name="password" placeholder="Max 56 chars, ASCII only" required> - </label> - <input type="submit" value="Sign up"> - </form> - <a href="/login">Login</a> - <a href="/reset-password">Reset password</a> -</body> - -</html>
A templates/register.tmpl

@@ -0,0 +1,25 @@

+{{ extends "base.tmpl" }} + +{{define "title" -}}Sign up{{end}} + +{{define "content" -}} +<h1>Sign up</h1> +<form method="post" action="/register"> + <label> + <span>Username:</span> + <input type="text" name="username" placeholder="^[a-z0-9._-]+$" required> + </label> + <label> + <span>Email:</span> + <input type="email" name="email" placeholder="Email" required> + </label> + <label> + <span>Password:</span> + <input type="password" name="password" placeholder="Max 56 chars, ASCII only" required> + </label> + <input type="submit" value="Sign up"> +</form> +<a href="/login">Login</a> +<a href="/reset-password">Reset password</a> +</form> +{{end}}
D templates/reset_password.html

@@ -1,25 +0,0 @@

-<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Reset password</title> - <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"> - <link rel="stylesheet" href="/static/style.css"> -</head> - -<body> - <h1>Reset password</h1> - <form method="post" action="/reset-password"> - <label> - <span>Email:</span> - <input type="email" name="email" placeholder="Email" required> - </label> - <input type="submit" value="Reset password"> - </form> - <a href="/register">Sign up</a> - <a href="/login">Login</a> -</body> - -</html>
A templates/reset_password.tmpl

@@ -0,0 +1,16 @@

+{{ extends "base.tmpl" }} + +{{define "title" -}}Reset password{{end}} + +{{define "content" -}} +<h1>Reset password</h1> +<form method="post" action="/reset-password"> + <label> + <span>Email:</span> + <input type="email" name="email" placeholder="Email" required> + </label> + <input type="submit" value="Reset password"> +</form> +<a href="/register">Sign up</a> +<a href="/login">Login</a> +{{end}}