Compare commits
7 Commits
7730257cce
...
pongo-temp
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a7584d628 | |||
| c1997aaab5 | |||
| e92a56c393 | |||
| 45f6f19441 | |||
| 2b13292e3b | |||
| da3deedb0c | |||
| 7024cd0de9 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
/.vscode
|
/.vscode
|
||||||
/__debug*
|
/__debug*
|
||||||
|
/build
|
||||||
/tmp
|
/tmp
|
||||||
/config.yaml
|
/config.yaml
|
||||||
|
|||||||
6
Makefile
6
Makefile
@ -1,2 +1,8 @@
|
|||||||
|
EXEC=iris-test
|
||||||
|
|
||||||
run:
|
run:
|
||||||
@air
|
@air
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build:
|
||||||
|
@go build -ldflags "-s -w" -o ./build/${EXEC} ./app/main.go
|
||||||
|
|||||||
45
README.md
45
README.md
@ -11,3 +11,48 @@
|
|||||||
- [Source](https://github.com/CloudyKit/jet)
|
- [Source](https://github.com/CloudyKit/jet)
|
||||||
- [Syntax reference](https://github.com/CloudyKit/jet/blob/master/docs/syntax.md)
|
- [Syntax reference](https://github.com/CloudyKit/jet/blob/master/docs/syntax.md)
|
||||||
|
|
||||||
|
## Howto
|
||||||
|
|
||||||
|
- [Password Hashing (bcrypt)](https://gowebexamples.com/password-hashing/)
|
||||||
|
|
||||||
|
|
||||||
|
## Bombardier benchmark
|
||||||
|
|
||||||
|
Pandora - Jet templating engine
|
||||||
|
|
||||||
|
```
|
||||||
|
eden@pandora:[~/apps/sandbox/golang/iris-web-framework]: bombardier -c 100 -d 10s -l http://localhost:8000 ±[A1][main]
|
||||||
|
Bombarding http://localhost:8000 for 10s using 100 connection(s)
|
||||||
|
Done!
|
||||||
|
Statistics Avg Stdev Max
|
||||||
|
Reqs/sec 10542.16 2631.23 17296.86
|
||||||
|
Latency 9.50ms 3.22ms 42.93ms
|
||||||
|
Latency Distribution
|
||||||
|
50% 8.77ms
|
||||||
|
75% 11.86ms
|
||||||
|
90% 15.31ms
|
||||||
|
95% 17.86ms
|
||||||
|
99% 23.90ms
|
||||||
|
HTTP codes:
|
||||||
|
1xx - 0, 2xx - 105258, 3xx - 0, 4xx - 0, 5xx - 0
|
||||||
|
others - 0
|
||||||
|
Throughput: 28.08MB/s
|
||||||
|
```
|
||||||
|
```
|
||||||
|
eden@pandora:[~/apps/sandbox/golang/iris-web-framework]: bombardier -c 100 -d 10s -l http://localhost:8000/users ±[A1][main]
|
||||||
|
Bombarding http://localhost:8000/users for 10s using 100 connection(s)
|
||||||
|
Done!
|
||||||
|
Statistics Avg Stdev Max
|
||||||
|
Reqs/sec 1096.26 427.09 3211.54
|
||||||
|
Latency 91.08ms 80.06ms 471.41ms
|
||||||
|
Latency Distribution
|
||||||
|
50% 78.37ms
|
||||||
|
75% 156.58ms
|
||||||
|
90% 191.60ms
|
||||||
|
95% 223.49ms
|
||||||
|
99% 309.59ms
|
||||||
|
HTTP codes:
|
||||||
|
1xx - 0, 2xx - 11060, 3xx - 0, 4xx - 0, 5xx - 0
|
||||||
|
others - 0
|
||||||
|
Throughput: 19.91MB/s
|
||||||
|
```
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
27
app/main.go
27
app/main.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"iris-test/app/common"
|
||||||
"iris-test/app/views"
|
"iris-test/app/views"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@ -15,32 +16,32 @@ import (
|
|||||||
var redisDB *redis.Database
|
var redisDB *redis.Database
|
||||||
|
|
||||||
func createSessionEngine() *sessions.Sessions {
|
func createSessionEngine() *sessions.Sessions {
|
||||||
redisAddr := fmt.Sprintf("%s:%d", Config.Redis.Host, Config.Redis.Port)
|
redisAddr := fmt.Sprintf("%s:%d", common.Config.Redis.Host, common.Config.Redis.Port)
|
||||||
|
|
||||||
redisDB = redis.New(redis.Config{
|
redisDB = redis.New(redis.Config{
|
||||||
Network: "tcp",
|
Network: "tcp",
|
||||||
Addr: redisAddr,
|
Addr: redisAddr,
|
||||||
Timeout: time.Duration(30) * time.Second,
|
Timeout: time.Duration(30) * time.Second,
|
||||||
MaxActive: 10,
|
MaxActive: 10,
|
||||||
Username: Config.Redis.Username,
|
Username: common.Config.Redis.Username,
|
||||||
Password: Config.Redis.Password,
|
Password: common.Config.Redis.Password,
|
||||||
Database: Config.Redis.Database,
|
Database: common.Config.Redis.Database,
|
||||||
Prefix: Config.Redis.Prefix,
|
Prefix: common.Config.Redis.Prefix,
|
||||||
Driver: redis.GoRedis(), // defaults to this driver.
|
Driver: redis.GoRedis(), // defaults to this driver.
|
||||||
// To set a custom, existing go-redis client, use the "SetClient" method:
|
// To set a custom, existing go-redis client, use the "SetClient" method:
|
||||||
// Driver: redis.GoRedis().SetClient(customGoRedisClient)
|
// Driver: redis.GoRedis().SetClient(customGoRedisClient)
|
||||||
})
|
})
|
||||||
|
|
||||||
sessions_engine := sessions.New(sessions.Config{
|
sessionsEngine := sessions.New(sessions.Config{
|
||||||
Cookie: "_session_id",
|
Cookie: "_session_id",
|
||||||
Expires: 0, // defaults to 0: unlimited life. Another good value is: 45 * time.Minute,
|
Expires: 0, // defaults to 0: unlimited life. Another good value is: 45 * time.Minute,
|
||||||
AllowReclaim: true,
|
AllowReclaim: true,
|
||||||
CookieSecureTLS: true,
|
CookieSecureTLS: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
sessions_engine.UseDatabase(redisDB)
|
sessionsEngine.UseDatabase(redisDB)
|
||||||
|
|
||||||
return sessions_engine
|
return sessionsEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
func createAccessLog() *accesslog.AccessLog {
|
func createAccessLog() *accesslog.AccessLog {
|
||||||
@ -83,18 +84,18 @@ func createApp() *iris.Application {
|
|||||||
accessLog := createAccessLog()
|
accessLog := createAccessLog()
|
||||||
|
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
app.Logger().SetLevel(Config.Application.LogLevel)
|
app.Logger().SetLevel(common.Config.Application.LogLevel)
|
||||||
app.Use(sessionsEngine.Handler())
|
app.Use(sessionsEngine.Handler())
|
||||||
app.UseRouter(accessLog.Handler)
|
app.UseRouter(accessLog.Handler)
|
||||||
app.RegisterView(iris.Jet("./app/templates", ".jet").Reload(true))
|
app.RegisterView(iris.Django("./app/templates", ".html").Reload(true))
|
||||||
views.CreateRouter(app)
|
views.CreateRouter(app)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
InitCfg()
|
common.InitCfg()
|
||||||
InitLogging()
|
common.InitLogging()
|
||||||
InitDB()
|
common.InitDB()
|
||||||
|
|
||||||
app := createApp()
|
app := createApp()
|
||||||
defer redisDB.Close()
|
defer redisDB.Close()
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Id string `gorm:"type(uuid);unique"`
|
Id string `gorm:"type(uuid);unique"`
|
||||||
@ -16,3 +18,9 @@ type User struct {
|
|||||||
func (u *User) TableName() string {
|
func (u *User) TableName() string {
|
||||||
return "users"
|
return "users"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (u *User) SetPassword(password string) (string, error) {
|
||||||
|
// secretKey := Config.Application.SecretKey
|
||||||
|
// bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||||
|
// return string(bytes), err
|
||||||
|
// }
|
||||||
|
|||||||
@ -12,6 +12,7 @@ type UsersRepository struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserFilter struct {
|
type UserFilter struct {
|
||||||
|
Id *string
|
||||||
IsActive *bool
|
IsActive *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,9 +23,14 @@ func CreateUsersRepository(db *gorm.DB) *UsersRepository {
|
|||||||
func applyFilter(db *gorm.DB, filter *UserFilter) *gorm.DB {
|
func applyFilter(db *gorm.DB, filter *UserFilter) *gorm.DB {
|
||||||
query := db
|
query := db
|
||||||
|
|
||||||
// if filter.State != "" {
|
if filter.Id != nil {
|
||||||
// query = query.Where("state = ?", filter.State)
|
query = query.Where("id = ?", filter.Id)
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
if filter.IsActive != nil {
|
||||||
|
query = query.Where(map[string]interface{}{"is_active": filter.IsActive})
|
||||||
|
}
|
||||||
|
|
||||||
// if filter.SendAt_lt != nil {
|
// if filter.SendAt_lt != nil {
|
||||||
// query = query.Where("send_at < ?", filter.SendAt_lt)
|
// query = query.Where("send_at < ?", filter.SendAt_lt)
|
||||||
// }
|
// }
|
||||||
@ -69,3 +75,18 @@ func (repository *UsersRepository) List(filter *UserFilter, pagination *Paginati
|
|||||||
|
|
||||||
return &users
|
return &users
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repository *UsersRepository) Get(filter *UserFilter) *models.User {
|
||||||
|
var user models.User
|
||||||
|
|
||||||
|
query := repository.db.Model(&models.User{})
|
||||||
|
query = applyFilter(query, filter)
|
||||||
|
query.First(&user)
|
||||||
|
|
||||||
|
return &user
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *UsersRepository) Save(user *models.User) *models.User {
|
||||||
|
repository.db.Save(user)
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|||||||
33
app/templates/base/base.html
Normal file
33
app/templates/base/base.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{% set title = "Hello world" %}
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container mt-3">
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
<ul class="nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="/" class="nav-link">Frontpage</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="/users" class="nav-link">Users</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="/about" class="nav-link">About</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
{% block mainContent %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1,27 +0,0 @@
|
|||||||
{{ title := "Hello world" }}
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Document</title>
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>{{ title }}</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="/">Frontpage</a>
|
|
||||||
<a href="/users">Users</a>
|
|
||||||
<a href="/about">About</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
{{ yield mainContent() }}
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
24
app/templates/components/table_component.html
Normal file
24
app/templates/components/table_component.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{% macro usersTable(users) %}
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>First name</th>
|
||||||
|
<th>Last name</th>
|
||||||
|
<th>Email</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for user in users %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="/users/{{ user.Id }}">{{ user.Id }}</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ user.FirstName }}</td>
|
||||||
|
<td>{{ user.LastName }}</td>
|
||||||
|
<td>{{ user.Email }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endmacro %}
|
||||||
@ -1,15 +0,0 @@
|
|||||||
{{ block usersTable(users) }}
|
|
||||||
<p>blablabla</p>
|
|
||||||
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
{{ range users }}
|
|
||||||
<tr>
|
|
||||||
<td>{{ .FirstName }}</td>
|
|
||||||
<td>{{ .LastName }}</td>
|
|
||||||
<td>{{ .Email }}</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{{ end }}
|
|
||||||
28
app/templates/pages/index.html
Normal file
28
app/templates/pages/index.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{% extends "/base/base.html" %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block mainContent %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<form class="mb-5 col-4 ms-auto me-auto" method="post" action="/">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Email address</label>
|
||||||
|
<input type="email" name="email" class="form-control" value="edkirin@gmail.com">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Password</label>
|
||||||
|
<input type="text" name="password" class="form-control" value="tralala">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-success">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="lead">
|
||||||
|
<p>Bacon ipsum dolor amet leberkas kevin meatball pork loin beef ribs prosciutto, turducken bacon bresaola tri-tip. Strip steak flank shankle, sirloin short ribs shoulder meatball pork chop kevin ribeye jowl ham pork belly turducken jerky. Flank tongue short loin ham hock brisket turducken tail filet mignon cupim. Pork capicola buffalo kevin jowl chicken. Filet mignon brisket pig, landjaeger sausage cow fatback drumstick chicken buffalo tenderloin spare ribs.</p>
|
||||||
|
<p>Swine shankle porchetta pancetta. Buffalo chicken turducken ground round kevin shoulder, salami pig t-bone beef ribs tri-tip tongue pork belly doner. Landjaeger meatloaf short loin biltong. Alcatra tongue shankle, tri-tip pancetta porchetta tenderloin corned beef pastrami rump. Bresaola chislic beef kielbasa sausage, ball tip burgdoggen boudin capicola short loin tenderloin buffalo landjaeger.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{{ extends "/base/base.jet" }}
|
{{ extends "/base/base.html" }}
|
||||||
{{ import "/components/table_component.jet" }}
|
{{ import "/components/table_component.html" }}
|
||||||
|
|
||||||
|
|
||||||
{{ block mainContent() }}
|
{{ block mainContent() }}
|
||||||
35
app/templates/pages/user-edit.jet
Normal file
35
app/templates/pages/user-edit.jet
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{{ extends "/base/base.jet" }}
|
||||||
|
{{ import "/components/table_component.jet" }}
|
||||||
|
|
||||||
|
|
||||||
|
{{ block mainContent() }}
|
||||||
|
<h3>Edit user</h3>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<form class="mb-5 col-4 ms-auto me-auto" method="post" action="{{ .currentPath }}">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">First name</label>
|
||||||
|
<input type="text" name="first-name" class="form-control" value="{{ user.FirstName }}" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Last name</label>
|
||||||
|
<input type="text" name="last-name" class="form-control" value="{{ user.LastName }}" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Email</label>
|
||||||
|
<input type="email" name="email" class="form-control" value="{{ user.Email }}" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex">
|
||||||
|
<a href="/users" class="btn btn-outline-secondary ms-auto me-2">
|
||||||
|
Cancel
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-success">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
@ -3,13 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
{{ block mainContent() }}
|
{{ block mainContent() }}
|
||||||
<ul>
|
<h3>Users</h3>
|
||||||
{{ range params1 }}
|
|
||||||
<li>{{ . }}</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>{{ title }}</h3>
|
|
||||||
|
|
||||||
{{ yield usersTable(users=users) }}
|
{{ yield usersTable(users=users) }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func GetIndexPage(ctx iris.Context) {
|
func GetIndexPage(ctx iris.Context) {
|
||||||
if err := ctx.View("pages/index.jet"); err != nil {
|
if err := ctx.View("pages/index.html"); err != nil {
|
||||||
showError(ctx, err)
|
showError(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,5 +7,8 @@ func CreateRouter(app *iris.Application) {
|
|||||||
app.Post("/", PostIndexPage)
|
app.Post("/", PostIndexPage)
|
||||||
|
|
||||||
app.Get("/users", GetUsersPage)
|
app.Get("/users", GetUsersPage)
|
||||||
|
app.Get("/users/{userId:uuid}", EditUserPage)
|
||||||
|
app.Post("/users/{userId:uuid}", SaveUserPage)
|
||||||
|
|
||||||
app.Get("/about", GetAboutPage)
|
app.Get("/about", GetAboutPage)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,10 +6,13 @@ import (
|
|||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetUsersPage(ctx iris.Context) {
|
type editUserForm struct {
|
||||||
params1 := []string{"param 1", "param 2", "param 3"}
|
FirstName string `form:"first-name"`
|
||||||
ctx.ViewData("params1", params1)
|
LastName string `form:"last-name"`
|
||||||
|
Email string `form:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUsersPage(ctx iris.Context) {
|
||||||
userRepository := repository.Dao.UsersRepository
|
userRepository := repository.Dao.UsersRepository
|
||||||
|
|
||||||
pagination := repository.NewPagination()
|
pagination := repository.NewPagination()
|
||||||
@ -18,7 +21,8 @@ func GetUsersPage(ctx iris.Context) {
|
|||||||
repository.NewOrdering("last_name", repository.ORDERING_ASC),
|
repository.NewOrdering("last_name", repository.ORDERING_ASC),
|
||||||
}
|
}
|
||||||
|
|
||||||
users := userRepository.List(&repository.UserFilter{}, &pagination, &ordering)
|
isActive := true
|
||||||
|
users := userRepository.List(&repository.UserFilter{IsActive: &isActive}, &pagination, &ordering)
|
||||||
|
|
||||||
ctx.ViewData("users", users)
|
ctx.ViewData("users", users)
|
||||||
|
|
||||||
@ -27,3 +31,42 @@ func GetUsersPage(ctx iris.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EditUserPage(ctx iris.Context) {
|
||||||
|
userId := ctx.Params().Get("userId")
|
||||||
|
userRepository := repository.Dao.UsersRepository
|
||||||
|
|
||||||
|
filter := repository.UserFilter{Id: &userId}
|
||||||
|
user := userRepository.Get(&filter)
|
||||||
|
|
||||||
|
ctx.ViewData("user", user)
|
||||||
|
ctx.ViewData("currentPath", ctx.Path())
|
||||||
|
|
||||||
|
if err := ctx.View("pages/user-edit.jet"); err != nil {
|
||||||
|
showError(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SaveUserPage(ctx iris.Context) {
|
||||||
|
var form editUserForm
|
||||||
|
err := ctx.ReadForm(&form)
|
||||||
|
if err != nil {
|
||||||
|
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userId := ctx.Params().Get("userId")
|
||||||
|
userRepository := repository.Dao.UsersRepository
|
||||||
|
|
||||||
|
filter := repository.UserFilter{Id: &userId}
|
||||||
|
user := userRepository.Get(&filter)
|
||||||
|
|
||||||
|
user.FirstName = form.FirstName
|
||||||
|
user.LastName = form.LastName
|
||||||
|
user.Email = form.Email
|
||||||
|
|
||||||
|
userRepository.Save(user)
|
||||||
|
|
||||||
|
ctx.Redirect("/users")
|
||||||
|
}
|
||||||
|
|||||||
1
go.mod
1
go.mod
@ -23,6 +23,7 @@ require (
|
|||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/fatih/structs v1.1.0 // indirect
|
github.com/fatih/structs v1.1.0 // indirect
|
||||||
github.com/flosch/pongo2/v4 v4.0.2 // indirect
|
github.com/flosch/pongo2/v4 v4.0.2 // indirect
|
||||||
|
github.com/flosch/pongo2/v6 v6.0.0 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 // indirect
|
github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 // indirect
|
||||||
github.com/google/uuid v1.3.1 // indirect
|
github.com/google/uuid v1.3.1 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@ -30,6 +30,8 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
|||||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw=
|
github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw=
|
||||||
github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
|
github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
|
||||||
|
github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU=
|
||||||
|
github.com/flosch/pongo2/v6 v6.0.0/go.mod h1:CuDpFm47R0uGGE7z13/tTlt1Y6zdxvr2RLT5LJhsHEU=
|
||||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
|||||||
Reference in New Issue
Block a user