如何使用Revel / Golang从控制器设置一个持久的全局模板变量?

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

How do I set a persistent global template variable from the controller using Revel / Golang

问题

我是新手学习 Golang,正在从 Node.js 服务器切换到 Golang 服务器,我正在尝试重写之前用 Node.js 编写的应用程序。

我想在用户登录时设置模板变量,但我不确定如何做,是的,我已经尝试过搜索了。

这是我的注册用户控制器:

func (c User) RegisterUser(user_email, user_password,
	user_password_confirmation, user_first_name,
	user_last_name string) revel.Result {

	// 验证邮箱
	c.Validation.Required(user_email).Message("用户名是必填项")
	c.Validation.Email(user_email).Message("邮箱格式不正确")
	c.Validation.MinSize(user_email, 5).Message("邮箱长度必须大于5个字符")
	// 验证密码
	c.Validation.Required(user_password).Message("密码是必填项")
	c.Validation.MinSize(user_password, 5).Message("密码长度必须大于5个字符")
	// 验证密码确认
	c.Validation.Required(user_password_confirmation).Message("密码确认是必填项")
	c.Validation.MinSize(user_password_confirmation, 5).Message("密码长度必须大于5个字符")
	c.Validation.Required(user_password == user_password_confirmation).Message("密码不匹配")
	// 验证名字
	c.Validation.Required(user_first_name).Message("名字是必填项")
	c.Validation.MinSize(user_first_name, 3).Message("名字长度必须大于3个字符")
	// 验证姓氏
	c.Validation.Required(user_last_name).Message("姓氏是必填项")
	c.Validation.MinSize(user_last_name, 3).Message("姓氏长度必须大于3个字符")

	// 如果有任何错误,设置 flash 并向用户显示错误
	if c.Validation.HasErrors() {
		c.Validation.Keep()
		c.FlashParams()
		return c.Redirect(User.Register)
	}

	// 对用户密码进行哈希处理
	password := []byte(user_password_confirmation)
	hashedPassword, err := bcrypt.GenerateFromPassword(password, 10)
	if err != nil {
		c.Flash.Error("用户名或密码组合无效")
		return c.Redirect(User.Register)
	}

	// 连接数据库
	db, err := sql.Open("mysql", "root:******@/WebRTC")
	if err != nil {
		c.Flash.Error("无法连接到数据库,请稍后再试!")
		return c.Redirect(User.Register)
	}
	defer db.Close()

	// 检查数据库连接是否正常
	err = db.Ping()
	if err != nil {
		c.Flash.Error("无法连接到数据库,请稍后再试!")
		return c.Redirect(User.Register)
	}

	// 准备 SQL 语句以确保安全性
	stmtIns, err := db.Prepare("INSERT INTO users (user_email, user_first_name, user_last_name, " +
		"user_password_hash, user_created_at, user_created_ip, user_last_ip) VALUES (?, ?, ?, ?, ?, ?, ?)")

	if err != nil {
		c.Flash.Error("无法注册,请稍后再试")
		return c.Redirect(User.Register)
	}
	defer stmtIns.Close()

	// 将数据插入数据库
	_, err = stmtIns.Exec(user_email, user_first_name, user_last_name, hashedPassword,
		time.Now().Local(), c.Request.RemoteAddr, c.Request.RemoteAddr)
	if err != nil {
		c.Flash.Error("无法注册,请稍后再试")
		return c.Redirect(User.Register)
	}
	
	// 在这里我想添加全局模板变量
	return c.Redirect(User.Register)
}

我已经阅读了关于 c.RenderArgs 的内容,但它似乎不能实现我想要的功能。

我想能够设置用户的用户名,以便在导航栏中显示,让他们知道他们已经登录。

英文:

I'm new to Golang and I'm switching over from Node.js server to a Golang server, I'm trying to rewrite an app I had previously written for Node.

I want to set Template variables when a user is signed in, but I'm not sure how and yes, I've tried googling it.

This is my register user controller:

func (c User) RegisterUser(user_email, user_password,
user_password_confirmation, user_first_name,
user_last_name string) revel.Result {
// Validate Email
c.Validation.Required(user_email).Message("Username is required")
c.Validation.Email(user_email).Message("Email is not a valid email")
c.Validation.MinSize(user_email, 5).Message("Email must be greater than 5 characters")
// Validate Password
c.Validation.Required(user_password).Message("Password is required")
c.Validation.MinSize(user_password, 5).Message("Password must be greater than 5 characters.")
// Validate Password Confirmation
c.Validation.Required(user_password_confirmation).Message("Password Confirmation is required")
c.Validation.MinSize(user_password_confirmation, 5).Message("Password must be greater than 5 characters.")
c.Validation.Required(user_password == user_password_confirmation).Message("Your passwords do not match")
// Validate First Name
c.Validation.Required(user_first_name).Message("First Name is required")
c.Validation.MinSize(user_first_name, 3).Message("Your First Name must be greater than 3 characters")
// Validate Last Name
c.Validation.Required(user_last_name).Message("Last Name is required")
c.Validation.MinSize(user_last_name, 3).Message("Your Last Name must be greater than 3 characters")
// If anything wasn't right, set flash and display errors to user
if c.Validation.HasErrors() {
c.Validation.Keep()
c.FlashParams()
return c.Redirect(User.Register)
}
// Hash The Users Password
password := []byte(user_password_confirmation)
hashedPassword, err := bcrypt.GenerateFromPassword(password, 10)
if err != nil {
c.Flash.Error("Invalid Username or Password Combination")
return c.Redirect(User.Register)
}
// Connect to database
db, err := sql.Open("mysql", "root:******@/WebRTC")
if err != nil {
c.Flash.Error("Unable to connect to database. Try again later!")
return c.Redirect(User.Register)
}
defer db.Close()
// Ping the database, ensure there is a connection
err = db.Ping()
if err != nil {
c.Flash.Error("Unable to connect to database. Try again later!")
return c.Redirect(User.Register)
}
// Prepare SQL Statement for Security
stmtIns, err := db.Prepare("INSERT INTO users (user_email, user_first_name, user_last_name, " +
"user_password_hash, user_created_at, user_created_ip, user_last_ip) VALUES (?, ?, ?, ?, ?, ?, ?)")
if err != nil {
c.Flash.Error("Unable to Register you. Please try again later")
return c.Redirect(User.Register)
}
defer stmtIns.Close()
// Insert Data into Database
_, err = stmtIns.Exec(user_email, user_first_name, user_last_name, hashedPassword,
time.Now().Local(), c.Request.RemoteAddr, c.Request.RemoteAddr)
if err != nil {
c.Flash.Error("Unable to register you. Please try again later")
return c.Redirect(User.Register)
}
// Here I want to add the global template variable
return c.Redirect(User.Register)
}

I've read about c.RenderArgs but it doesn't seem to do what I want it to.

I want to be able to set the users' username, so that I can display it in the navbar so that they know they're logged in.

答案1

得分: 1

如果你正在使用c.RenderArgs,那么你就在正确的轨道上,除非我误解了你的意图。

以下是一个示例(或者说是一个演示),展示了如何使用它(取自Revel的booking示例应用程序):

  1. init.go: 注册一个拦截器,在执行操作之前添加用户信息(AddUser将在Render之前触发)。

  2. app.go: 检查用户是否已连接,如果是,则将用户数据存储在RenderArgs映射中,如下所示:

    c.RenderArgs["user"] = user

  3. 第31行处理模型

  4. header.html: 传递用户名模板变量。

希望这可以帮到你。

编辑:我可能应该补充一下,用户的用户名在登录时存储在会话中。它用于检索更多信息

英文:

You are on the right track if you are using c.RenderArgs unless I have misunderstood your intentions.

Here's an example (or rather, a walkthrough) of how you may use it (taken from Revel's booking sample app):

  1. init.go: Register an interceptor to add the user's information before an action is taken (AddUser will be fired before Render).

  2. app.go: Check if the user is connected and if so, store the user's data in the RenderArgs map like so:

c.RenderArgs["user"] = user

  1. Line 31 deals with the model.

  2. header.html: Pass the username template variable in.

I hope this helps.

EDIT: I should probably add that the user's username is stored in a session upon login. It's used to retrieve more information.

huangapple
  • 本文由 发表于 2015年1月12日 07:30:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/27893339.html
匿名

发表评论

匿名网友

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

确定