Actions must return a revel.Result, which handles the HTTP response generation and adheres to the simple interface:

type Result interface {
	Apply(req *Request, resp *Response)
}

revel.Controller provides a few methods to produce different results:

NOTE: From v0.14, the following changes:
  • `RenderJson` is now `RenderJSON`
  • `RenderJsonP` is now `RenderJSONP`
  • `RenderXml` is now `RenderXML`
  • Render(), RenderTemplate()
    • render a template, passing arguments.
  • RenderJSON(), RenderXML()
    • serialize a structure to json or xml.
  • RenderText()
    • return a plaintext response.
  • Redirect()
    • redirect to another action or URL
  • RenderFile()
    • return a file, generally to be downloaded as an attachment.
  • RenderError()
    • return a 500 response that renders the errors/500.html template.
  • NotFound()
    • return a 404 response that renders the errors/404.html template.
  • Todo()
    • return a stub response (500)

Additionally, the developer may define a result with CustomResult and return that.

Setting the Status Code / Content Type

Each built-in Result has a default HTTP Status Code and Content Type. To override those defaults, simply set those properties on the response:

func (c App) Action() revel.Result {
	c.Response.Status = http.StatusTeapot
	c.Response.ContentType = "application/dishware"
	return c.Render()
}

You can override the default status code by setting one yourself:

func (c *App) CreateEntity() revel.Result {
    c.Response.Status = 201
    return c.Render()
}

Render()

Called within an action (e.g. “Controller.Action”), Controller.Render() does two things:

  1. Adds all arguments to the controller’s ViewArgs, using their local identifier as the key.
  2. Executes the template “views/Controller/Action.html”, passing in the controller’s ViewArgs as the data map.

If unsuccessful (e.g. it could not find the template), an ErrorResult is returned instead.

This allows the developer to write:

func (c MyApp) Action() revel.Result {
	myValue := calculateValue()
	return c.Render(myValue)
}

and to use myValue in their template. This is usually more convenient than constructing an explicit map, since in many cases the data will need to be handled as a local variable anyway.

Note: Revel looks at the calling method name to determine the Template path and to look up the argument names. Therefore, `c.Render()` may only be called from Actions.
// Example using mix of render args and variables
// This renders the `views/MyController/showSutuff.html` template as
// eg <pre>foo={{.foo}} bar={{.bar}} abc={{.abc}} xyz={{.xyz}}</pre>
func (c MyController) ShowStuff() revel.Result {
    c.ViewArgs["foo"] = "bar"
    c.ViewArgs["bar"] = 1
    abc := "abc"
    xyz := "xyz"
    return c.Render(xyz, abc)
}

// Example renders the `views/Foo/boo.xhtml` tempate
func (c MyController) XTemp() revel.Result {
    c.ViewArgs["foo"] = "bar"
    c.ViewArgs["bar"] = 1
    return c.RenderTemplate("Foo/boo.xhtml")
}

RenderJSON() / RenderXML()

The application may call RenderJSON, RenderJSONP or RenderXML and pass in any Go type, usually a struct. Revel will serialize it using json.Marshal or xml.Marshal.

If results.pretty=true in conf/app.conf then serialization will be done using MarshalIndent instead, to produce nicely indented output for human consumption.

// Simple example

type Stuff struct {
    Foo string ` json:"foo" xml:"foo" `
    Bar int ` json:"bar" xml:"bar" `
}

func (c MyController) MyAction() revel.Result {
    data := make(map[string]interface{})
    data["error"] = nil
    stuff := Stuff{Foo: "xyz", Bar: 999}
    data["stuff"] = stuff
    return c.RenderJSON(data)
    //return c.RenderXML(data)
}

Redirect()

  • A helper function for generating HTTP redirects.
  • It may be used in two ways and both return a 302 Temporary Redirect HTTP status code.

Redirect to an action with no arguments:

    return c.Redirect(Hotels.Settings)
  • This form is useful as it provides a degree of type safety and independence from the routing and generates the URL automatically.

Redirect to a formatted string:

return c.Redirect("/hotels/%d/settings", hotelId)
  • This form is necessary to pass arguments.
  • It returns a 302 Temporary Redirect status code.

Custom Result

Below is a simple example of creating a custom revel.Result.

Create this type:

import ("net/http")

type MyHtml string

func (r MyHtml) Apply(req *revel.Request, resp *revel.Response) {
	resp.WriteHeader(http.StatusOK, "text/html")
	resp.Out.Write([]byte(r))
}

Then use it in an action:

func (c *MyApp) Action() revel.Result {
	return MyHtml("<html><body>Hello Result</body></html>")
}
GitHub Labels