Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
on:
push:
branches:
- master
- v1
pull_request:
branches:
- "**"
name: Linter
jobs:
golangci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: src/github.com/unrolled/render
- uses: golangci/golangci-lint-action@v6
with:
working-directory: src/github.com/unrolled/render
19 changes: 5 additions & 14 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,17 @@ on:
pull_request:
branches:
- "**"
name: Test
name: Tests
jobs:
tests:
strategy:
matrix:
go-version: [1.18.x, 1.19.x, 1.20.x, 1.21.x]
go-version: [1.18.x, 1.19.x, 1.20.x, 1.21.x, 1.22.x, 1.23.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v2
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Test
run: make ci
golangci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
- run: make ci
51 changes: 21 additions & 30 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -1,41 +1,32 @@
run:
timeout: 10m
modules-download-mode: readonly
allow-parallel-runners: true

issues:
exclude:
- G203

run:
timeout: 5m
exclude-rules:
- path: _test\.go
linters:
- lll
- err113

linters:
enable-all: true
disable:
# Deprecated linters
- varcheck
- exhaustivestruct
- ifshort
- structcheck
- golint
- maligned
- interfacer
- nosnakecase
- deadcode
- scopelint
- rowserrcheck
- sqlclosecheck
- structcheck
- wastedassign
# Ignoring
- lll
- varnamelen
- paralleltest
- testpackage
- goerr113
- copyloopvar
- cyclop
- depguard
- execinquery
- exhaustruct
- nestif
- exportloopref
- funlen
- goconst
- cyclop
- gocyclo
- gocognit
- maintidx
- goconst
- gomnd
- intrange
- paralleltest
- testpackage
- varnamelen
- wrapcheck
- depguard
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ r := render.New(render.Options{
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).
UnEscapeHTML: true, // 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.
Expand Down
2 changes: 1 addition & 1 deletion engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

// Engine is the generic interface for all responses.
type Engine interface {
Render(io.Writer, interface{}) error
Render(w io.Writer, v interface{}) error
}

// Head defines the basic ContentType and Status fields.
Expand Down
2 changes: 1 addition & 1 deletion fs_embed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestEmbedFileSystemHTMLBasic(t *testing.T) {

var err error

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
err = render.HTML(w, http.StatusOK, "hello", "gophers")
})

Expand Down
4 changes: 2 additions & 2 deletions fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestIOFSEmbedHTMLBasic(t *testing.T) {

var err error

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
err = render.HTML(w, http.StatusOK, "hello", "gophers")
})

Expand All @@ -78,7 +78,7 @@ func TestIOFSDirHTMLBasic(t *testing.T) {

var err error

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
err = render.HTML(w, http.StatusOK, "hello", "gophers")
})

Expand Down
2 changes: 1 addition & 1 deletion genericbufferpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import "bytes"
// GenericBufferPool abstracts buffer pool implementations.
type GenericBufferPool interface {
Get() *bytes.Buffer
Put(*bytes.Buffer)
Put(b *bytes.Buffer)
}
11 changes: 8 additions & 3 deletions helpers.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package render

import (
"fmt"
"errors"
"html/template"
)

var (
ErrYieldNoLayoutDefined = errors.New("yield called with no layout defined")
ErrBlockNoLayoutDefined = errors.New("block called with no layout defined")
)

// Included helper functions for use when rendering HTML.
func helperFuncs() template.FuncMap {
return template.FuncMap{
"yield": func() (string, error) {
return "", fmt.Errorf("yield called with no layout defined")
return "", ErrYieldNoLayoutDefined
},
"partial": func() (string, error) {
return "", fmt.Errorf("block called with no layout defined")
return "", ErrBlockNoLayoutDefined
},
"current": func() (string, error) {
return "", nil
Expand Down
6 changes: 3 additions & 3 deletions helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func TestRenderPartial(t *testing.T) {

var renErr error

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
renErr = render.HTML(w, http.StatusOK, "content", "gophers")
})

Expand All @@ -38,7 +38,7 @@ func TestRenderPartialRequirePartialsOff(t *testing.T) {
RequirePartials: false,
})

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_ = render.HTML(w, http.StatusOK, "content-partial", "gophers")
})

Expand All @@ -61,7 +61,7 @@ func TestRenderPartialRequirePartialsOn(t *testing.T) {
RequirePartials: true,
})

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_ = render.HTML(w, http.StatusOK, "content-partial", "gophers")
})

Expand Down
24 changes: 16 additions & 8 deletions render.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ type Options struct {
Layout string
// Extensions to parse template files from. Defaults to [".tmpl"].
Extensions []string
// Funcs is a slice of FuncMaps to apply to the template upon compilation. This is useful for helper functions. Defaults to empty map.
// Funcs is a slice of FuncMaps to apply to the template upon compilation.
// This is useful for helper functions. Defaults to empty map.
Funcs []template.FuncMap
// Delims sets the action delimiters to the specified strings in the Delims struct.
Delims Delims
// Appends the given character set to the Content-Type header. Default is "UTF-8".
Charset string
// If DisableCharset is set to true, it will not append the above Charset value to the Content-Type header. Default is false.
// If DisableCharset is set to true, it will not append the above Charset value to the Content-Type header.
// Default is false.
DisableCharset bool
// Outputs human readable JSON.
IndentJSON bool
Expand All @@ -97,23 +99,27 @@ type Options struct {
XMLContentType string
// If IsDevelopment is set to true, this will recompile the templates on every request. Default is false.
IsDevelopment bool
// If UseMutexLock is set to true, the standard `sync.RWMutex` lock will be used instead of the lock free implementation. Default is false.
// Note that when `IsDevelopment` is true, the standard `sync.RWMutex` lock is always used. Lock free is only a production feature.
// If UseMutexLock is set to true, the standard `sync.RWMutex` lock will be used instead of the lock free
// implementation. Default is false. Note that when `IsDevelopment` is true, the standard `sync.RWMutex`
// lock is always used. Lock free is only a production feature.
UseMutexLock bool
// Unescape HTML characters "&<>" to their original values. Default is false.
UnEscapeHTML bool
// Sets the `Option` value for HTML templates. Defaults to blank ("").
HTMLTemplateOption string
// Streams JSON responses instead of marshalling prior to sending. Default is false.
StreamingJSON bool
// Require that all partials executed in the layout are implemented in all templates using the layout. Default is false.
// Require that all partials executed in the layout are implemented in all templates using the layout.
// Default is false.
RequirePartials bool
// Deprecated: Use the above `RequirePartials` instead of this. As of Go 1.6, blocks are built in. Default is false.
RequireBlocks bool
// Disables automatic rendering of http.StatusInternalServerError when an error occurs. Default is false.
DisableHTTPErrorRendering bool
// Enables using partials without the current filename suffix which allows use of the same template in multiple files. e.g {{ partial "carosuel" }} inside the home template will match carosel-home or carosel.
// ***NOTE*** - This option should be named RenderPartialsWithoutSuffix as that is what it does. "Prefix" is a typo. Maintaining the existing name for backwards compatibility.
// Enables using partials without the current filename suffix which allows use of the same template in
// multiple files. e.g {{ partial "carousel" }} inside the home template will match carousel-home or carousel.
// ***NOTE*** - This option should be named RenderPartialsWithoutSuffix as that is what it does.
// "Prefix" is a typo. Maintaining the existing name for backwards compatibility.
RenderPartialsWithoutPrefix bool
// BufferPool to use when rendering HTML templates. If none is supplied
// defaults to SizedBufferPool of size 32 with 512KiB buffers.
Expand Down Expand Up @@ -247,7 +253,8 @@ func (r *Render) compileTemplatesFromDir() {

watcher, err = fsnotify.NewWatcher()
if err != nil {
log.Printf("Unable to create new watcher for template files. Templates will be recompiled on every render. Error: %v\n", err)
log.Printf("Unable to create new watcher for template files. "+
"Templates will be recompiled on every render. Error: %v\n", err)
}
}

Expand All @@ -260,6 +267,7 @@ func (r *Render) compileTemplatesFromDir() {
if info != nil && watcher != nil {
_ = watcher.Add(path)
}

if info == nil || info.IsDir() {
return nil
}
Expand Down
6 changes: 3 additions & 3 deletions render_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func TestDataBinaryBasic(t *testing.T) {

var err error

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
err = render.Data(w, 299, []byte("hello there"))
})

Expand All @@ -34,7 +34,7 @@ func TestDataCustomMimeType(t *testing.T) {

var err error

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set(ContentType, "image/jpeg")
err = render.Data(w, http.StatusOK, []byte("..jpeg data.."))
})
Expand All @@ -56,7 +56,7 @@ func TestDataCustomContentType(t *testing.T) {

var err error

h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
err = render.Data(w, http.StatusOK, []byte("..png data.."))
})

Expand Down
Loading