Сессия Beego не передает данные в шаблон автоматически

После получения информации о сеансе типа map[string]interface{} с помощью this.GetSession("session_key") мне пришлось явно установить контекст и тип assert для сеанса, как это, чтобы явно передать данные в шаблон.

// 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"

Данные сеанса (тип map[string]interface{}) выглядят так:

{"nickname": "joe", "picture": "urltotheimg"}

Однако, согласно doc сеанса Beego, похоже, что сеанс передается неявно без каких-либо утверждений типа или передачи контекста (шаблон имеет немедленный доступ к значениям сеанса, т.е. {{.nickname}} и {{.picture}})

Это контроллер, который устанавливает сеанс перед перенаправлением на /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)
}

Это контроллер "/ 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"
}

Только тогда я могу сопоставить шаблон с данными следующим образом:

<img src="{{ .picture }}">
<p>Hello, {{ .nickname }}</p>

Я совершенно уверен, что необходимо установить данные шаблона. Я просто не уверен, почему вышеуказанный документ этого не сделал.

Любая помощь будет оценена по достоинству.


person Pie 'Oh' Pah    schedule 08.12.2015    source источник
comment
Извините, какой у вас вопрос?   -  person icza    schedule 11.12.2015
comment
Я не понимаю, нужно ли мне вводить assert сеанса профиля и назначать карту данных для ссылки на данные в контексте шаблона. Несколько примеров, которые я видел, просто получают сеанс и визуализируют шаблон, а данные доступны в контексте.   -  person Pie 'Oh' Pah    schedule 11.12.2015
comment
@ pie-o-pah У меня тоже возникли проблемы с чтением того, что вы ожидаете отобразить в шаблоне. Что отображается в вашем шаблоне? Поскольку я вижу, что в вашем <img src={{ .picture }} отсутствует . Кроме того, вы читаете эти значения из Auth0Controller. Вы уверены, что эти значения установлены правильно? Что произойдет, если вы просто жестко закодируете значения в UserController, например: this.Data["nickname"] = "User's Nickname" и this.Data["picture"] = "/path/to/img.jpg"   -  person abm    schedule 12.12.2015
comment
@ pie-o-pah Кроме того, не могли бы вы добавить к своему вопросу, как вы настраиваете begoo и как выглядит структура файлов и папок вашего проекта?   -  person abm    schedule 12.12.2015


Ответы (1)


Я просто попробовал запустить проект Beego quickstart и успешно его выполнил.

Убедитесь, что у вас есть как 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"] = "User's 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: {{.nickname}}</p>
<p>Picture: {{.picture}}</p>

И роутер:

func init() {
    beego.Router("/", &controllers.MainController{})
    beego.Router("/redirect", &controllers.RedirectController{})
}

Я также рекомендую вам использовать структуру для хранения значений профиля, например:

// 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}}

Обязательно прочтите это, чтобы понять, как выполняется отрисовка шаблона. Я надеюсь, что это именно то, о чем вы просили, если нет, пожалуйста, отредактируйте свой вопрос и добавьте дополнительную полезную информацию, и я отредактирую этот ответ.

person abm    schedule 12.12.2015
comment
Спасибо, я полностью пропустил ту часть, что Beego всегда нужно устанавливать данные шаблона с помощью this.Data[], в то время как в vanilla Go данные можно передавать в метод RenderTemplate. Тем не менее, спасибо, что указали! - person Pie 'Oh' Pah; 14.12.2015