Render

Go package for easily rendering JSON, XML, binary data, and HTML templates responses.
Alternatives To Render
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Sheetjs33,5844,3793,8162 months ago170March 24, 2022129apache-2.0JavaScript
📗 SheetJS Spreadsheet Data Toolkit -- New home https://git.sheetjs.com/SheetJS/sheetjs
Yq9,381703 days ago126July 12, 2023100mitGo
yq is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor
Fq8,876
2 days ago104July 07, 202346otherGo
jq for binary formats - tool, language and decoders for working with binary and text formats
Refit7,5021787302 days ago72June 29, 2023166mitC#
The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square's Retrofit library, Refit turns your REST API into a live interface.
Poco7,33512 days ago8November 02, 2022285otherC
The POCO C++ Libraries are powerful cross-platform C++ libraries for building network- and internet-based applications that run on desktop, server, mobile, IoT, and embedded systems.
Structured Text Tools6,743
16 days ago3
A list of command line tools for manipulating structured text data
Rest Assured6,4947,36448116 days ago32June 16, 2023523apache-2.0Java
Java DSL for easy testing of REST services
Countries5,7933991002 days ago21April 04, 202019odbl-1.0PHP
World countries in JSON, CSV, XML and Yaml. Any help is welcome!
Wiremock5,7231,6267942 days ago114June 15, 2023336apache-2.0Java
A tool for mocking HTTP services
Countries States Cities Database5,455
3 days ago66odbl-1.0PHP
🌍 Discover our global repository of countries, states, and cities! 🏙️ Get comprehensive data in JSON, SQL, XML, YAML, and CSV formats. Access ISO2, ISO3 codes, country code, capital, native language, timezones (for countries), and more. #countries #states #cities
Alternatives To Render
Select To Compare


Alternative Project Comparisons
Readme

Render GoDoc Test

Render is a package that provides functionality for easily rendering JSON, XML, text, binary data, and HTML templates.

Usage

Render can be used with pretty much any web framework providing you can access the http.ResponseWriter from your handler. The rendering functions simply wraps Go's existing functionality for marshaling and rendering data.

  • HTML: Uses the html/template package to render HTML templates.
  • JSON: Uses the encoding/json package to marshal data into a JSON-encoded response.
  • XML: Uses the encoding/xml package to marshal data into an XML-encoded response.
  • Binary data: Passes the incoming data straight through to the http.ResponseWriter.
  • Text: Passes the incoming string straight through to the http.ResponseWriter.
// main.go
package main

import (
    "encoding/xml"
    "net/http"

    "github.com/unrolled/render"
)

type ExampleXml struct {
    XMLName xml.Name `xml:"example"`
    One     string   `xml:"one,attr"`
    Two     string   `xml:"two,attr"`
}

func main() {
    r := render.New()
    mux := http.NewServeMux()

    mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        w.Write([]byte("Welcome, visit sub pages now."))
    })

    mux.HandleFunc("/data", func(w http.ResponseWriter, req *http.Request) {
        r.Data(w, http.StatusOK, []byte("Some binary data here."))
    })

    mux.HandleFunc("/text", func(w http.ResponseWriter, req *http.Request) {
        r.Text(w, http.StatusOK, "Plain text here")
    })

    mux.HandleFunc("/json", func(w http.ResponseWriter, req *http.Request) {
        r.JSON(w, http.StatusOK, map[string]string{"hello": "json"})
    })

    mux.HandleFunc("/jsonp", func(w http.ResponseWriter, req *http.Request) {
        r.JSONP(w, http.StatusOK, "callbackName", map[string]string{"hello": "jsonp"})
    })

    mux.HandleFunc("/xml", func(w http.ResponseWriter, req *http.Request) {
        r.XML(w, http.StatusOK, ExampleXml{One: "hello", Two: "xml"})
    })

    mux.HandleFunc("/html", func(w http.ResponseWriter, req *http.Request) {
        // Assumes you have a template in ./templates called "example.tmpl"
        // $ mkdir -p templates && echo "<h1>Hello {{.}}.</h1>" > templates/example.tmpl
        r.HTML(w, http.StatusOK, "example", "World")
    })

    http.ListenAndServe("127.0.0.1:3000", mux)
}
<!-- templates/example.tmpl -->
<h1>Hello {{.}}.</h1>

Available Options

Render comes with a variety of configuration options (Note: these are not the default option values. See the defaults below.):

// ...
r := render.New(render.Options{
    Directory: "templates", // Specify what path to load the templates from.
    FileSystem: &LocalFileSystem{}, // Specify filesystem from where files are loaded.
    Asset: func(name string) ([]byte, error) { // Load from an Asset function instead of file.
      return []byte("template content"), nil
    },
    AssetNames: func() []string { // Return a list of asset names for the Asset function
      return []string{"filename.tmpl"}
    },
    Layout: "layout", // Specify a layout template. Layouts can call {{ yield }} to render the current template or {{ partial "css" }} to render a partial from the current template.
    Extensions: []string{".tmpl", ".html"}, // Specify extensions to load for templates.
    Funcs: []template.FuncMap{AppHelpers}, // Specify helper function maps for templates to access.
    Delims: render.Delims{"{[{", "}]}"}, // Sets delimiters to the specified strings.
    Charset: "UTF-8", // Sets encoding for content-types. Default is "UTF-8".
    DisableCharset: true, // Prevents the charset from being appended to the content type header.
    IndentJSON: true, // Output human readable JSON.
    IndentXML: true, // Output human readable XML.
    PrefixJSON: []byte(")]}',\n"), // Prefixes JSON responses with the given bytes.
    PrefixXML: []byte("<?xml version='1.0' encoding='UTF-8'?>"), // Prefixes XML responses with the given bytes.
    HTMLContentType: "application/xhtml+xml", // Output XHTML content type instead of default "text/html".
    IsDevelopment: true, // Render will now recompile the templates on every HTML response.
    UseMutexLock: true, // Overrides the default no lock implementation and uses the standard `sync.RWMutex` lock.
    UnEscapeHTML: true, // Replace ensure '&<>' are output correctly (JSON only).
    StreamingJSON: true, // Streams the JSON response via json.Encoder.
    HTMLTemplateOption: "missingkey=error", // Sets the option value for HTML templates. See https://pkg.go.dev/html/template#Template.Option for a list of known options.
    RequirePartials: true, // Return an error if a template is missing a partial used in a layout.
    DisableHTTPErrorRendering: true, // Disables automatic rendering of http.StatusInternalServerError when an error occurs.
})
// ...

Default Options

These are the preset options for Render:

r := render.New()

// Is the same as the default configuration options:

r := render.New(render.Options{
    Directory: "templates",
    FileSystem: &LocalFileSystem{},
    Asset: nil,
    AssetNames: nil,
    Layout: "",
    Extensions: []string{".tmpl"},
    Funcs: []template.FuncMap{},
    Delims: render.Delims{"{{", "}}"},
    Charset: "UTF-8",
    DisableCharset: false,
    IndentJSON: false,
    IndentXML: false,
    PrefixJSON: []byte(""),
    PrefixXML: []byte(""),
    BinaryContentType: "application/octet-stream",
    HTMLContentType: "text/html",
    JSONContentType: "application/json",
    JSONPContentType: "application/javascript",
    TextContentType: "text/plain",
    XMLContentType: "application/xhtml+xml",
    IsDevelopment: false,
    UseMutexLock: false,
    UnEscapeHTML: false,
    HTMLTemplateOption: "",
    StreamingJSON: false,
    RequirePartials: false,
    DisableHTTPErrorRendering: false,
    RenderPartialsWithoutPrefix: false,
    BufferPool: GenericBufferPool,
})

JSON vs Streaming JSON

By default, Render does not stream JSON to the http.ResponseWriter. It instead marshalls your object into a byte array, and if no errors occurred, writes that byte array to the http.ResponseWriter. If you would like to use the built it in streaming functionality (json.Encoder), you can set the StreamingJSON setting to true. This will stream the output directly to the http.ResponseWriter. Also note that streaming is only implemented in render.JSON and not render.JSONP.

Loading Templates

By default Render will attempt to load templates with a '.tmpl' extension from the "templates" directory. Templates are found by traversing the templates directory and are named by path and basename. For instance, the following directory structure:

templates/
  |
  |__ admin/
  |      |
  |      |__ index.tmpl
  |      |
  |      |__ edit.tmpl
  |
  |__ home.tmpl

Will provide the following templates:

admin/index
admin/edit
home

Templates can be loaded from an embed.FS.

// ...

//go:embed templates/*.html templates/*.tmpl
var embeddedTemplates embed.FS

// ...

r := render.New(render.Options{
    Directory: "templates",
    FileSystem: &render.EmbedFileSystem{
        FS: embeddedTemplates,
    },
    Extensions: []string{".html", ".tmpl"},
})
// ...

You can also load templates from memory by providing the Asset and AssetNames options, e.g. when generating an asset file using go-bindata.

Layouts

Render provides yield and partial functions for layouts to access:

// ...
r := render.New(render.Options{
    Layout: "layout",
})
// ...
<!-- templates/layout.tmpl -->
<html>
  <head>
    <title>My Layout</title>
    <!-- Render the partial template called `css-$current_template` here -->
    {{ partial "css" }}
  </head>
  <body>
    <!-- render the partial template called `header-$current_template` here -->
    {{ partial "header" }}
    <!-- Render the current template here -->
    {{ yield }}
    <!-- render the partial template called `footer-$current_template` here -->
    {{ partial "footer" }}
  </body>
</html>

current can also be called to get the current template being rendered.

<!-- templates/layout.tmpl -->
<html>
  <head>
    <title>My Layout</title>
  </head>
  <body>
    This is the {{ current }} page.
  </body>
</html>

Partials are defined by individual templates as seen below. The partial template's name needs to be defined as "{partial name}-{template name}".

<!-- templates/home.tmpl -->
{{ define "header-home" }}
<h1>Home</h1>
{{ end }}

{{ define "footer-home"}}
<p>The End</p>
{{ end }}

By default, the template is not required to define all partials referenced in the layout. If you want an error to be returned when a template does not define a partial, set Options.RequirePartials = true.

Character Encodings

Render will automatically set the proper Content-Type header based on which function you call. See below for an example of what the default settings would output (note that UTF-8 is the default, and binary data does not output the charset):

// main.go
package main

import (
    "encoding/xml"
    "net/http"

    "github.com/unrolled/render"
)

type ExampleXml struct {
    XMLName xml.Name `xml:"example"`
    One     string   `xml:"one,attr"`
    Two     string   `xml:"two,attr"`
}

func main() {
    r := render.New(render.Options{})
    mux := http.NewServeMux()

    // This will set the Content-Type header to "application/octet-stream".
    // Note that this does not receive a charset value.
    mux.HandleFunc("/data", func(w http.ResponseWriter, req *http.Request) {
        r.Data(w, http.StatusOK, []byte("Some binary data here."))
    })

    // This will set the Content-Type header to "application/json; charset=UTF-8".
    mux.HandleFunc("/json", func(w http.ResponseWriter, req *http.Request) {
        r.JSON(w, http.StatusOK, map[string]string{"hello": "json"})
    })

    // This will set the Content-Type header to "text/xml; charset=UTF-8".
    mux.HandleFunc("/xml", func(w http.ResponseWriter, req *http.Request) {
        r.XML(w, http.StatusOK, ExampleXml{One: "hello", Two: "xml"})
    })

    // This will set the Content-Type header to "text/plain; charset=UTF-8".
    mux.HandleFunc("/text", func(w http.ResponseWriter, req *http.Request) {
        r.Text(w, http.StatusOK, "Plain text here")
    })

    // This will set the Content-Type header to "text/html; charset=UTF-8".
    mux.HandleFunc("/html", func(w http.ResponseWriter, req *http.Request) {
        // Assumes you have a template in ./templates called "example.tmpl"
        // $ mkdir -p templates && echo "<h1>Hello {{.}}.</h1>" > templates/example.tmpl
        r.HTML(w, http.StatusOK, "example", "World")
    })

    http.ListenAndServe("127.0.0.1:3000", mux)
}

In order to change the charset, you can set the Charset within the render.Options to your encoding value:

// main.go
package main

import (
    "encoding/xml"
    "net/http"

    "github.com/unrolled/render"
)

type ExampleXml struct {
    XMLName xml.Name `xml:"example"`
    One     string   `xml:"one,attr"`
    Two     string   `xml:"two,attr"`
}

func main() {
    r := render.New(render.Options{
        Charset: "ISO-8859-1",
    })
    mux := http.NewServeMux()

    // This will set the Content-Type header to "application/octet-stream".
    // Note that this does not receive a charset value.
    mux.HandleFunc("/data", func(w http.ResponseWriter, req *http.Request) {
        r.Data(w, http.StatusOK, []byte("Some binary data here."))
    })

    // This will set the Content-Type header to "application/json; charset=ISO-8859-1".
    mux.HandleFunc("/json", func(w http.ResponseWriter, req *http.Request) {
        r.JSON(w, http.StatusOK, map[string]string{"hello": "json"})
    })

    // This will set the Content-Type header to "text/xml; charset=ISO-8859-1".
    mux.HandleFunc("/xml", func(w http.ResponseWriter, req *http.Request) {
        r.XML(w, http.StatusOK, ExampleXml{One: "hello", Two: "xml"})
    })

    // This will set the Content-Type header to "text/plain; charset=ISO-8859-1".
    mux.HandleFunc("/text", func(w http.ResponseWriter, req *http.Request) {
        r.Text(w, http.StatusOK, "Plain text here")
    })

    // This will set the Content-Type header to "text/html; charset=ISO-8859-1".
    mux.HandleFunc("/html", func(w http.ResponseWriter, req *http.Request) {
        // Assumes you have a template in ./templates called "example.tmpl"
        // $ mkdir -p templates && echo "<h1>Hello {{.}}.</h1>" > templates/example.tmpl
        r.HTML(w, http.StatusOK, "example", "World")
    })

    http.ListenAndServe("127.0.0.1:3000", mux)
}

Error Handling

The rendering functions return any errors from the rendering engine. By default, they will also write the error to the HTTP response and set the status code to 500. You can disable this behavior so that you can handle errors yourself by setting Options.DisableHTTPErrorRendering: true.

r := render.New(render.Options{
  DisableHTTPErrorRendering: true,
})

//...

err := r.HTML(w, http.StatusOK, "example", "World")
if err != nil{
  http.Redirect(w, r, "/my-custom-500", http.StatusFound)
}

Integration Examples

Echo

// main.go
package main

import (
    "io"
    "net/http"

    "github.com/labstack/echo"
    "github.com/unrolled/render"
)

type RenderWrapper struct { // We need to wrap the renderer because we need a different signature for echo.
    rnd *render.Render
}

func (r *RenderWrapper) Render(w io.Writer, name string, data interface{},c echo.Context) error {
    return r.rnd.HTML(w, 0, name, data) // The zero status code is overwritten by echo.
}

func main() {
    r := &RenderWrapper{render.New()}

    e := echo.New()

    e.Renderer = r

    e.GET("/", func(c echo.Context) error {
        return c.Render(http.StatusOK, "TemplateName", "TemplateData")
    })

    e.Logger.Fatal(e.Start("127.0.0.1:8080"))
}

Gin

// main.go
package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/unrolled/render"
)

func main() {
    r := render.New(render.Options{
        IndentJSON: true,
    })

    router := gin.Default()

    router.GET("/", func(c *gin.Context) {
        r.JSON(c.Writer, http.StatusOK, map[string]string{"welcome": "This is rendered JSON!"})
    })

    router.Run("127.0.0.1:8080")
}

Goji

// main.go
package main

import (
    "net/http"

    "github.com/zenazn/goji"
    "github.com/zenazn/goji/web"
    "github.com/unrolled/render"
)

func main() {
    r := render.New(render.Options{
        IndentJSON: true,
    })

    goji.Get("/", func(c web.C, w http.ResponseWriter, req *http.Request) {
        r.JSON(w, http.StatusOK, map[string]string{"welcome": "This is rendered JSON!"})
    })
    goji.Serve()  // Defaults to ":8000".
}

Negroni

// main.go
package main

import (
    "net/http"

    "github.com/urfave/negroni"
    "github.com/unrolled/render"
)

func main() {
    r := render.New(render.Options{
        IndentJSON: true,
    })
    mux := http.NewServeMux()

    mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        r.JSON(w, http.StatusOK, map[string]string{"welcome": "This is rendered JSON!"})
    })

    n := negroni.Classic()
    n.UseHandler(mux)
    n.Run("127.0.0.1:8080")
}

Traffic

// main.go
package main

import (
    "net/http"

    "github.com/pilu/traffic"
    "github.com/unrolled/render"
)

func main() {
    r := render.New(render.Options{
        IndentJSON: true,
    })

    router := traffic.New()
    router.Get("/", func(w traffic.ResponseWriter, req *traffic.Request) {
        r.JSON(w, http.StatusOK, map[string]string{"welcome": "This is rendered JSON!"})
    })

    router.Run()  // Defaults to "127.0.0.1:3000".
}
Popular Xml Projects
Popular Json Projects
Popular Data Formats Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Html
Go
Golang
Json
Xml
Streaming
Rendering
Encoding
Jsonp