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()


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)


  • 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")

Then use it in an action:

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