英文:
Beego Session Not Passing Data to Template Automatically
问题
在使用this.GetSession("session_key")
获取类型为map[string]interface{}
的会话信息后,我必须显式设置上下文并对会话进行类型断言,以便将数据明确传递给模板。
// 获取会话
profile := this.GetSession("profile")
// 必须将数据添加到模板的上下文中
this.Data["nickname"] = profile.(map[string]interface{})["nickname"].(string)
this.Data["picture"] = profile.(map[string]interface{})["picture"].(string)
// 渲染模板
this.TplNames = "user.html"
会话数据(类型为map[string]interface{}
)如下所示:
{"nickname": "joe", "picture": "urltotheimg"}
然而,根据Beego的会话文档,似乎会话会隐式传递,无需进行任何类型断言或上下文传递(模板可以直接访问会话值,例如{{.nickname}}
和{{.picture}}
)。
这是在重定向到/user
之前设置会话的控制器:
// 继承Beego的基础控制器
type MyController struct {
beego.Controller
}
func (this *MyController) Get() {
// 在此处获取令牌的代码
// 获取用户信息
client := conf.Client(oauth2.NoContext, token)
resp, err := client.Get("https://" + domain + "/userinfo")
if err != nil {
this.Redirect("/error", 500)
return
}
// 读取用户信息的主体
raw, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
this.Redirect("/error", 500)
return
}
// 反序列化配置文件的JSON
var profile map[string]interface{}
if err := json.Unmarshal(raw, &profile); err != nil {
this.Redirect("/error", 500)
return
}
// 将信息保存到会话中
this.SetSession("profile", profile)
// 重定向到/user
this.Redirect("/user", 301)
}
这是/user
的控制器:
type UserController struct {
beego.Controller
}
func (this *UserController) Get() {
// 获取保存的会话
profile := this.GetSession("profile")
// 如果不在此处设置模板数据,会话数据将无法在user.html中使用
this.Data["nickname"] = profile.(map[string]interface{})["nickname"].(string)
this.Data["picture"] = profile.(map[string]interface{})["picture"].(string)
this.TplNames = "user.html"
}
只有这样,我才能将模板映射到数据,如下所示:
<img src="{{ .picture }}">
<p>Hello, {{ .nickname }}</p>
我相当确定需要设置模板数据,只是不确定为什么上述文档没有这样做。
如果有任何帮助,将不胜感激。
英文:
Upon getting session information of type map[string]interface{}
with this.GetSession("session_key")
, I did have to explicitly set the context and type assert the session like this in order to explicitly pass the data to the template.
// Get the session
profile := this.GetSession("profile")
// Have to add data to the template's context
this.Data["nickname"] = profile.(map[string]interface{})["nickname"].(string)
this.Data["picture"] = profile.(map[string]interface{})["picture"].(string)
// Render template
this.TplNames = "user.html"
The session data (type map[string]interface{}
) looks like this:
{"nickname": "joe", "picture": "urltotheimg"}
However, according to the Beego's session <a href="http://beego.me/docs/mvc/controller/session.md">doc</a>, it looks like the session is passed implicitly without any need of type assertions or context passing (the template has immediate access to session values i.e. {{.nickname}}
and {{.picture}}
)
This is the controller setting the session before redirecting to /user
// Inherit beego's base controller
type MyController struct {
beego.Controller
}
func (this *MyController) Get() {
// code for getting token here
// Getting the User information
client := conf.Client(oauth2.NoContext, token)
resp, err := client.Get("https://" + domain + "/userinfo")
if err != nil {
this.Redirect("/error", 500)
return
}
// Reading the body for user's information
raw, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
this.Redirect("/error", 500)
return
}
// Unmarshalling the JSON of the Profile
var profile map[string]interface{}
if err := json.Unmarshal(raw, &profile); err != nil {
this.Redirect("/error", 500)
return
}
// Saving the information to the session.
this.SetSession("profile", profile)
// redirect to /user
this.Redirect("/user", 301)
}
This is the controller of "/user"
type UserController struct {
beego.Controller
}
func (this *UserController) Get() {
// get the saved session
profile := this.GetSession("profile")
// without setting the template data here, the session data won't be
// available in user.html
this.Data["nickname"] = profile.(map[string]interface{})["nickname"].(string)
this.Data["picture"] = profile.(map[string]interface{})["picture"].(string)
this.TplNames = "user.html"
}
Only this then I can map the template to the data like this:
<img src="{{ .picture }}">
<p>Hello, {{ .nickname }}</p>
I'm quite sure it's necessary to set the template data. I'm just not sure why the above doc didn't do that.
Any help would be appreciated.
答案1
得分: 1
我刚刚尝试运行了Beego快速入门项目,并成功运行了它。
请确保已安装beego和bee。在使用bee new projectname
创建新项目后,确保编辑projectname/conf/app.conf文件并添加sessionon = true:
appname = quickstart
httpport = 8080
runmode = dev
sessionon = true
我创建了一个重定向控制器:
type RedirectController struct {
beego.Controller
}
func (c *RedirectController) Get() {
profile := make(map[string]interface{})
profile["nickname"] = "用户的昵称"
profile["picture"] = "/path/to/img.jpg"
c.SetSession("profile", profile)
c.Redirect("/", 301)
}
主控制器:
type MainController struct {
beego.Controller
}
func (c *MainController) Get() {
profile := c.GetSession("profile")
c.Data["nickname"] = profile.(map[string]interface{})["nickname"]
c.Data["picture"] = profile.(map[string]interface{})["picture"]
c.TplNames = "index.tpl"
}
我的index.tpl文件:
<p>昵称:{{.nickname}}</p>
<p>图片:{{.picture}}</p>
以及路由器:
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/redirect", &controllers.RedirectController{})
}
我还建议您使用一个结构体来存储配置文件的值,例如:
// 定义结构体。
type Profile struct{
Nickname string
Picture string
}
// 保存用于模板渲染。
this.Data["profile"] = &Profile{Nickname:"astaxie", Picture:"img.jpg"}
// 并像这样渲染它:
昵称:{{.profile.Nickname}}
图片:{{.profile.Picture}}
请确保阅读这个以了解如何进行模板渲染。希望这就是您所询问的内容,如果不是,请编辑您的问题并添加更多有用的信息,我将编辑此答案。
英文:
I just tried running the Beego quickstart project and ran it successfully.
Make sure you have both the beego and bee installed. After creating a new project with bee new projectname
make sure you edit the projectname/conf/app.conf file and add the sessionon = true:
appname = quickstart
httpport = 8080
runmode = dev
sessionon = true
I created a redirect controller like:
type RedirectController struct {
beego.Controller
}
func (c *RedirectController) Get() {
profile := make(map[string]interface{})
profile["nickname"] = "User's Nickname"
profile["picture"] = "/path/to/img.jpg"
c.SetSession("profile", profile)
c.Redirect("/", 301)
}
The main controller:
type MainController struct {
beego.Controller
}
func (c *MainController) Get() {
profile := c.GetSession("profile")
c.Data["nickname"] = profile.(map[string]interface{})["nickname"]
c.Data["picture"] = profile.(map[string]interface{})["picture"]
c.TplNames = "index.tpl"
}
My index.tpl file:
<p>Nickname: {{.nickname}}</p>
<p>Picture: {{.picture}}</p>
And the router:
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/redirect", &controllers.RedirectController{})
}
I would also recommend you to use a structure to store the profile values like:
// Define struct.
type Profile struct{
Nickname string
Picture string
}
// Save it for template rendering.
this.Data["profile"] = &Profile{Nickname:"astaxie", Picture:"img.jpg"}
// And render it like this:
Nickname: {{.profile.Nickname}}
Picture: {{.profile.Picture}}
Make sure to read this to understand how template rendering is done. I hope this is what you were asking for, if not, please edit your question and add more helpful information and I will edit this answer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论