Convert templates to partials
This commit is contained in:
parent
67f7022b90
commit
77ae9d2dfd
@ -39,5 +39,5 @@ func (h *Handler) accounts(c *gin.Context) {
|
||||
Accounts: accounts,
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "accounts", d)
|
||||
c.HTML(http.StatusOK, "accounts.html", d)
|
||||
}
|
||||
|
@ -48,5 +48,5 @@ func (h *Handler) budget(c *gin.Context) {
|
||||
Transactions: transactions,
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "budget", d)
|
||||
c.HTML(http.StatusOK, "budget.html", d)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ func (h *Handler) dashboard(c *gin.Context) {
|
||||
Token: token,
|
||||
Budgets: budgets,
|
||||
}
|
||||
c.HTML(http.StatusOK, "dashboard", d)
|
||||
c.HTML(http.StatusOK, "dashboard.html", d)
|
||||
}
|
||||
|
||||
type DashboardData struct {
|
||||
|
16
http/http.go
16
http/http.go
@ -6,8 +6,6 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"html/template"
|
||||
|
||||
"git.javil.eu/jacob1123/budgeteer"
|
||||
"git.javil.eu/jacob1123/budgeteer/bcrypt"
|
||||
"git.javil.eu/jacob1123/budgeteer/postgres"
|
||||
@ -34,8 +32,12 @@ const (
|
||||
func (h *Handler) Serve() {
|
||||
router := gin.Default()
|
||||
|
||||
templ := template.Must(template.New("").Funcs(router.FuncMap).ParseFS(web.Templates, "*"))
|
||||
router.SetHTMLTemplate(templ)
|
||||
templates, err := NewTemplates(router.FuncMap)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
router.HTMLRender = templates
|
||||
|
||||
static, err := fs.Sub(web.Static, "static")
|
||||
if err != nil {
|
||||
@ -43,7 +45,7 @@ func (h *Handler) Serve() {
|
||||
}
|
||||
router.StaticFS("/static", http.FS(static))
|
||||
|
||||
router.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "index", nil) })
|
||||
router.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "index.html", nil) })
|
||||
router.GET("/login", h.login)
|
||||
router.GET("/register", h.register)
|
||||
authenticatedFrontend := router.Group("")
|
||||
@ -180,7 +182,7 @@ func (h *Handler) login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "login", nil)
|
||||
c.HTML(http.StatusOK, "login.html", nil)
|
||||
}
|
||||
|
||||
func (h *Handler) register(c *gin.Context) {
|
||||
@ -189,7 +191,7 @@ func (h *Handler) register(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "register", nil)
|
||||
c.HTML(http.StatusOK, "register.html", nil)
|
||||
}
|
||||
|
||||
func logout(c *gin.Context) {
|
||||
|
45
http/templates.go
Normal file
45
http/templates.go
Normal file
@ -0,0 +1,45 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
|
||||
"git.javil.eu/jacob1123/budgeteer/web"
|
||||
"github.com/gin-gonic/gin/render"
|
||||
)
|
||||
|
||||
type Templates struct {
|
||||
templates map[string]*template.Template
|
||||
}
|
||||
|
||||
func NewTemplates(funcMap template.FuncMap) (*Templates, error) {
|
||||
templates, err := fs.Glob(web.Templates, "*.tpl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &Templates{
|
||||
templates: make(map[string]*template.Template, 0),
|
||||
}
|
||||
pages, err := fs.Glob(web.Templates, "*.html")
|
||||
for _, page := range pages {
|
||||
allTemplates := append([]string{page}, templates...)
|
||||
tpl, err := template.New(page).Funcs(funcMap).ParseFS(web.Templates, allTemplates...)
|
||||
fmt.Printf("page: %s, templates: %v\n", page, templates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.templates[page] = tpl
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (tpl *Templates) Instance(name string, obj interface{}) render.Render {
|
||||
return render.HTML{
|
||||
Template: tpl.templates[name],
|
||||
Name: name,
|
||||
Data: obj,
|
||||
}
|
||||
}
|
@ -1,23 +1,17 @@
|
||||
{{define "accounts"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Budgets</title>
|
||||
|
||||
{{template "head"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="head">
|
||||
Budgeteer - {{.Token.GetName}}
|
||||
</div>
|
||||
<div class="container col-lg-12" id="content">
|
||||
{{range .Accounts}}
|
||||
<div class="budget-item">
|
||||
<a href="account/{{.ID}}">{{.Name}}</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}
|
||||
Accounts
|
||||
{{end}}
|
||||
|
||||
{{define "new"}}
|
||||
{{end}}
|
||||
|
||||
{{template "base" .}}
|
||||
|
||||
{{define "main"}}
|
||||
{{range .Accounts}}
|
||||
<div class="budget-item">
|
||||
<a href="account/{{.ID}}">{{.Name}}</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
31
web/base.tpl
Normal file
31
web/base.tpl
Normal file
@ -0,0 +1,31 @@
|
||||
{{define "base"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" />
|
||||
<link href="/static/css/main.css" rel="stylesheet" />
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script src="https://malsup.github.io/jquery.form.js"></script>
|
||||
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
<script src="/static/js/main.js"></script>
|
||||
<title>{{template "title" .}} - Budgeteer</title>
|
||||
|
||||
{{block "more-head" .}}{{end}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="head">
|
||||
{{template "title" .}}
|
||||
</div>
|
||||
<div class="container col-lg-12" id="content">
|
||||
{{template "main" .}}
|
||||
</div>
|
||||
{{block "new" .}}{{end}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@ -1,32 +1,26 @@
|
||||
{{define "budget"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Budgets</title>
|
||||
{{template "base" .}}
|
||||
|
||||
{{template "head"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="head">
|
||||
Budgeteer - {{.Token.GetName}} - {{.Budget.Name}}
|
||||
</div>
|
||||
<div class="container"><a href="/budget/{{.Budget.ID}}/accounts">Go to Accounts</a></div>
|
||||
<div class="budget-item">
|
||||
<a href="#newbudgetmodal" data-toggle="modal" data-target="#newbudgetmodal">New Budget</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
<table class="container col-lg-12" id="content">
|
||||
{{range .Transactions}}
|
||||
<tr>
|
||||
<td>{{.Date}}</td>
|
||||
<td>
|
||||
<a href="transaction/{{.ID}}">{{.Memo.String}}</a>
|
||||
</td>
|
||||
<td>{{.Amount}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
{{template "transaction-new"}}
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}Budget{{end}}
|
||||
|
||||
{{define "new"}}
|
||||
{{template "transaction-new"}}
|
||||
{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
<div class="container"><a href="/budget/{{.Budget.ID}}/accounts">Go to Accounts</a></div>
|
||||
<div class="budget-item">
|
||||
<a href="#newbudgetmodal" data-toggle="modal" data-target="#newbudgetmodal">New Budget</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
<table class="container col-lg-12" id="content">
|
||||
{{range .Transactions}}
|
||||
<tr>
|
||||
<td>{{.Date}}</td>
|
||||
<td>
|
||||
<a href="transaction/{{.ID}}">{{.Memo.String}}</a>
|
||||
</td>
|
||||
<td>{{.Amount}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
{{end}}
|
@ -1,28 +1,22 @@
|
||||
{{define "dashboard"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Budgets</title>
|
||||
|
||||
{{template "head"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="head">
|
||||
Budgeteer - {{.Token.GetName}}
|
||||
</div>
|
||||
<div class="container col-lg-12" id="content">
|
||||
{{range .Budgets}}
|
||||
<div class="budget-item">
|
||||
<a href="budget/{{.ID}}">{{.Name}}</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="budget-item">
|
||||
<a href="#newbudgetmodal" data-toggle="modal" data-target="#newbudgetmodal">New Budget</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
</div>
|
||||
{{template "budget-new"}}
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}
|
||||
Budgets
|
||||
{{end}}
|
||||
|
||||
{{define "new"}}
|
||||
{{template "budget-new"}}
|
||||
{{end}}
|
||||
|
||||
{{template "base" .}}
|
||||
|
||||
{{define "main"}}
|
||||
{{range .Budgets}}
|
||||
<div class="budget-item">
|
||||
<a href="budget/{{.ID}}">{{.Name}}</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="budget-item">
|
||||
<a href="#newbudgetmodal" data-toggle="modal" data-target="#newbudgetmodal">New Budget</a>
|
||||
<span class="time"></span>
|
||||
</div>
|
||||
{{end}}
|
@ -1,13 +0,0 @@
|
||||
{{define "head"}}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" />
|
||||
<link href="/static/css/main.css" rel="stylesheet" />
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script src="https://malsup.github.io/jquery.form.js"></script>
|
||||
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
<script src="/static/js/main.js"></script>
|
||||
{{end}}
|
@ -1,21 +1,17 @@
|
||||
{{define "index"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Budgeteer</title>
|
||||
|
||||
{{template "head"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="head">
|
||||
Budgeteer
|
||||
</div>
|
||||
<div class="container col-md-8 col-ld-8" id="content">
|
||||
Willkommen bei Budgeteer, der neuen App für's Budget!
|
||||
</div>
|
||||
<div class="container col-md-4" id="login">
|
||||
<a href="/login">Login</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}
|
||||
Start
|
||||
{{end}}
|
||||
|
||||
{{define "new"}}
|
||||
{{end}}
|
||||
|
||||
{{template "base" .}}
|
||||
|
||||
{{define "main"}}
|
||||
<div class="container col-md-8 col-ld-8" id="content">
|
||||
Willkommen bei Budgeteer, der neuen App für's Budget!
|
||||
</div>
|
||||
<div class="container col-md-4" id="login">
|
||||
<a href="/login">Login</a> or <a href="/login">register</a>
|
||||
</div>
|
||||
{{end}}
|
@ -1,47 +1,38 @@
|
||||
{{define "login"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Login</title>
|
||||
{{template "base" .}}
|
||||
|
||||
{{template "head"}}
|
||||
{{define "title"}}Login{{end}}
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#invalidCredentials').hide();
|
||||
$('#loginForm').ajaxForm({
|
||||
success: function() {
|
||||
window.location.href = "/dashboard";
|
||||
},
|
||||
error: function() {
|
||||
$('#invalidCredentials').show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="head">
|
||||
Budgeteer
|
||||
</div>
|
||||
<div class="container col-lg-12" id="content">
|
||||
<form id="loginForm" action="/api/v1/user/login" method="POST" class="center-block">
|
||||
<div class="form-group">
|
||||
<label for="username">User</label>
|
||||
<input type="text" name="username" class="form-control" placeholder="User" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" class="form-control" placeholder="Password" />
|
||||
<p id="invalidCredentials">
|
||||
The entered credentials are invalid
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Login" class="btn btn-default" />
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{define "more-head"}}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#invalidCredentials').hide();
|
||||
$('#loginForm').ajaxForm({
|
||||
success: function() {
|
||||
window.location.href = "/dashboard";
|
||||
},
|
||||
error: function() {
|
||||
$('#invalidCredentials').show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
<form id="loginForm" action="/api/v1/user/login" method="POST" class="center-block">
|
||||
<div class="form-group">
|
||||
<label for="username">User</label>
|
||||
<input type="text" name="username" class="form-control" placeholder="User" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" class="form-control" placeholder="Password" />
|
||||
<p id="invalidCredentials">
|
||||
The entered credentials are invalid
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Login" class="btn btn-default" />
|
||||
</form>
|
||||
{{end}}
|
||||
|
@ -1,78 +1,68 @@
|
||||
{{define "register"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Registration</title>
|
||||
{{define "title"}}Register{{end}}
|
||||
|
||||
{{template "head"}}
|
||||
{{template "base" .}}
|
||||
|
||||
<script>
|
||||
function checkPasswordMatchUi() {
|
||||
if(checkPasswordMatch())
|
||||
$("#divCheckPasswordMatch").html("Passwords match.");
|
||||
else
|
||||
$("#divCheckPasswordMatch").html("Passwords do not match!");
|
||||
{{define "more-head"}}
|
||||
<script>
|
||||
function checkPasswordMatchUi() {
|
||||
if(checkPasswordMatch())
|
||||
$("#divCheckPasswordMatch").html("Passwords match.");
|
||||
else
|
||||
$("#divCheckPasswordMatch").html("Passwords do not match!");
|
||||
}
|
||||
|
||||
function checkPasswordMatch() {
|
||||
var password = $("#password").val();
|
||||
var confirmPassword = $("#password_confirm").val();
|
||||
return password == confirmPassword;
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#password, #password_confirm").keyup(checkPasswordMatchUi);
|
||||
$('#invalidCredentials').hide();
|
||||
$('#loginForm').ajaxForm({
|
||||
beforeSubmit: function(a, b, c) {
|
||||
var match = checkPasswordMatch();
|
||||
if(!match){
|
||||
$("#divCheckPasswordMatch").fadeOut(300).fadeIn(300).fadeOut(300).fadeIn(300);
|
||||
}
|
||||
|
||||
function checkPasswordMatch() {
|
||||
var password = $("#password").val();
|
||||
var confirmPassword = $("#password_confirm").val();
|
||||
|
||||
return password == confirmPassword;
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#password, #password_confirm").keyup(checkPasswordMatchUi);
|
||||
$('#invalidCredentials').hide();
|
||||
$('#loginForm').ajaxForm({
|
||||
beforeSubmit: function(a, b, c) {
|
||||
var match = checkPasswordMatch();
|
||||
if(!match){
|
||||
$("#divCheckPasswordMatch").fadeOut(300).fadeIn(300).fadeOut(300).fadeIn(300);
|
||||
}
|
||||
return match;
|
||||
},
|
||||
success: function() {
|
||||
window.location.href = "/dashboard";
|
||||
},
|
||||
error: function() {
|
||||
$('#invalidCredentials').show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="head">
|
||||
Budgeteer
|
||||
</div>
|
||||
<div class="container col-lg-12" id="content">
|
||||
<form id="loginForm" action="/api/v1/user/register" method="POST" class="center-block">
|
||||
<div class="form-group">
|
||||
<label for="email">E-Mail</label>
|
||||
<input type="text" name="email" class="form-control" placeholder="E-Mail" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" placeholder="Name" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" id="password" class="form-control" placeholder="Password" />
|
||||
<input type="password" id="password_confirm" class="form-control" placeholder="Verify password" />
|
||||
</div>
|
||||
|
||||
<div id="divCheckPasswordMatch"></div>
|
||||
|
||||
<div id="invalidCredentials">
|
||||
Username already exists
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Login" class="form-control" />
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
return match;
|
||||
},
|
||||
success: function() {
|
||||
window.location.href = "/dashboard";
|
||||
},
|
||||
error: function() {
|
||||
$('#invalidCredentials').show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
<form id="loginForm" action="/api/v1/user/register" method="POST" class="center-block">
|
||||
<div class="form-group">
|
||||
<label for="email">E-Mail</label>
|
||||
<input type="text" name="email" class="form-control" placeholder="E-Mail" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" placeholder="Name" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" id="password" class="form-control" placeholder="Password" />
|
||||
<input type="password" id="password_confirm" class="form-control" placeholder="Verify password" />
|
||||
</div>
|
||||
|
||||
<div id="divCheckPasswordMatch"></div>
|
||||
|
||||
<div id="invalidCredentials">
|
||||
Username already exists
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Login" class="form-control" />
|
||||
</form>
|
||||
{{end}}
|
@ -2,7 +2,7 @@ package web
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed *.html
|
||||
//go:embed *.html *.tpl
|
||||
var Templates embed.FS
|
||||
|
||||
//go:embed static
|
||||
|
Loading…
x
Reference in New Issue
Block a user