render

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2024 License: MIT Imports: 15 Imported by: 0

README

simple-render

This is a simple render library designed to simplify the rendering of JSON and HTML responses in web applications. Additionally, it provides a set of custom template functions that enhance the flexibility and power of your HTML templates.

Currently, the following formats are supported:

  • HTML
  • JSON

By leveraging the "html/template" package's Funcs() method, this library extends the default template functionality with a variety of useful custom functions. These functions are detailed in the Functions section below. Below are examples and explanations on how to use the library effectively, including the available custom template functions.

Installation

To install the package, use the following command:

go get github.com/WhiteRaven777/simple-render

How To Use

JSON

The following example demonstrates how to use the render.JSON function to send JSON responses.

type Data struct {
Date string
Msg  string
}

data := Data {
Date: time.Now().Format("2006-01-02"),
Msg:  "message",
}

--- or ---

data := map[string]string{
"Date": time.Now().Format("2006-01-02"),
"Msg":  "message",
}

To send this data as a JSON response:

func Sample(w http.ResponseWriter, r *http.Request) {
render.JSON(w, http.StatusOK, data)
}

This will produce the following JSON output:

{
  "Date": "2019-01-17",
  "Msg": "message"
}

HTML

The following example demonstrates how to use the Template struct and its HTML method to render HTML responses using templates.

layout.html

The layout template defines the overall structure of the HTML document.

{{- define "layout" }}
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>{{ template "title" . }}</title>
</head>
<body>
<div class="content">
{{ template "body" . }}
</div>
</body>
</html>
{{- end }}
view.html

The view template defines the specific content for a particular page.

{{ define "title" }}{{ .Title }}{{ end }}

{{ define "body" }}
<h1>{{ .Title }}</h1>
<article>
{{ .Body | safeHTML }}
</article>
<li><a href="{{ .Url | safeURL }}">{{ .Title }}</a></li>
{{ end }}

To render this template with data using the Template struct:

func Sample(w http.ResponseWriter, r *http.Request) {
    tmpl := Template{
        Layout: "layout",
        Data: map[string]string{
            "Title": "title text",
            "Body":  "body text",
            "Url":   "https://github.com/WhiteRaven777/simple-render",
        },
        ExtraFuncMap: template.FuncMap{
            "customFunc": func() string { return "Custom Function" },
        },
    }
    tmpl.HTML(w, http.StatusOK)
}

In this example, the Template struct's HTML method renders the view.html template within the layout.html template, passing the Data map to populate the template variables. The ExtraFuncMap allows for the inclusion of custom functions within the template.

Functions

This section provides a list of custom functions available for use within templates. Each function is designed to simplify template logic and enhance the flexibility of your templates.

● day

Returns the current day of the month (UTC).

Syntax
day
Example
# Assuming today is 2019-02-14 17:18:19 (UTC)

{{ day }}
-> 14
● date

Returns the current date in YYYY-MM-DD format (UTC).

Syntax
date
Example
# Assuming today is 2019-02-14 17:18:19 (UTC)

{{ date }}
-> 2019-02-14
● datetime

Returns the current date and time in RFC3339 format (UTC).

Syntax
datetime
Example
# Assuming today is 2019-02-14 17:18:19 (UTC)

{{ datetime }}
-> 2019-02-14T17:18:19Z
● default

Returns the input value if it is non-empty; otherwise, returns the default value.

Syntax
default DEFAULT_VALUE INPUT
Example
{{ default 2 1 }}
-> 1

{{ default "default" "" }}
-> default

{{ default 42 0 }}
-> 42
● dict

Creates a dictionary (map) from a list of key-value pairs.

Syntax
dict [KEY VALUE]...
Example
{{ dict 0 "aaa" 1 "bbb" 2 "ccc" }}
-> map[0:"aaa", 1:"bbb", 2:"ccc"]

{{ dict "name" "John" "age" 30 }}
-> map["name":"John", "age":30]

Note: The dict function requires an even number of arguments.

● dtemplate

Executes a dynamically selected template within another template.

Syntax
dtemplate TEMPLATE_NAME DATA
Example
{{ define "content1" }}
Content 1: {{ .Content }}
{{ end }}

{{ define "content2" }}
Content 2: {{ .Content }}
{{ end }}

{{ $data := dict "Content" "Hello, World!" }}
{{ range (slice 1 2)
{{ template (printf "content%d" .) $data }}
{{ end }}
-> Content 1: Hello, World!
   Content 2: Hello, World!

Note: The dtemplate function allows for dynamic selection of templates based on the data provided, ensuring flexibility in rendering different templates within a single base template.

Security Considerations

When using the dtemplate function for dynamic template rendering, be aware of the following potential security risks:

  1. Code Injection:
    Dynamic template names can introduce the risk of code injection if user input is directly used without validation. Always ensure that template names are not directly influenced by user input.
  2. Template Injection:
    Avoid using untrusted user input directly as template names. Only use dynamic content for template names when the input can be fully controlled and trusted, such as internally generated names or predefined static values.

To safely use the dtemplate function, ensure that all dynamic elements are controlled and validated. Using predefined or internally generated template names helps mitigate these risks and ensures secure template rendering.

● eval

Evaluates a mathematical or logical expression and returns the result.

Syntax
eval FORMULAS
Example
{{ eval "1 + 1" }}
-> 2

{{ eval "1 - 1 + 1" }}
-> 1

# Errors in the evaluation will return nil.

{{ eval "invalid expression" }}
-> nil
● findRE

Finds all matches of a regular expression in the input string.

Syntax
findRE PATTERN INPUT [LIMIT]
Example
{{ findRE `/hoge/(\d+)` "/hoge/1234567890/hoge/987654321/abcdefghijk"   }}
-> [/hoge/1234567890 /hoge/987654321]

{{ findRE `/hoge/(\d+)` "/hoge/1234567890/hoge/987654321/abcdefghijk" 1 }}
-> [/hoge/1234567890]
● in

Checks if the item is present within the set.

Syntax
in SET ITEM
Example
{{ if in "/example/aaa" "/example" }}True{{ else }}False{{ end }}
-> True

{{ if in "/sample/aaa" "/example" }}True{{ else }}False{{ end }}
-> False
● index

Returns the element at the specified index or key from a collection (array, slice, or map).

Syntax
index COLLECTION (INDEX|KEY)
Example
{{ index (slice 3 4 5) 0 }}
-> 3

{{ index (dict 0 "aaa" 1 "bbb" 2 "ccc") 0 }}
-> aaa
● len

Returns the length of the input. Supports arrays, maps, slices, and strings.

Syntax
len INPUT
Example
{{ if gt (len .Notification) 0 }}<div id="notification">
<div class="success">
<p>{{ .Notification | safeHTML }}</p>
</div>
</div>{{ end }}
● lower

Converts the input string(s) to lowercase.

Syntax
lower INPUT
Example
{{ $arr := slice "A" "B" "C" }}
{{ range $arr }}{{ lower . }}{{ end }}
-> a b c
● map

Creates a map from a list of key-value pairs.

Syntax
map KEY VALUE [KEY VALUE]...
Example
{{ $m := map "key1" 100 "key2" 200 "key3" 300 }}
{{ printf "%#v" $m }}
-> map[string]interface {}{"key1":100, "key2":200, "key3":300}

{{ $m := map "key1" 100 "key2" 200 "key3" 300 "key4"}}
{{ printf "%#v" $m }}
-> 
● month

Returns the current month as an integer (UTC).

Syntax
month
Example
# Assuming today is 2019-02-14 17:18:19 (UTC)

{{ month }}
-> 2
● replace

Replaces all occurrences of the old substring with the new substring in the input string.

Syntax
replace INPUT OLD NEW
Example
<span>{{ replace "Is this an apple?" "an apple" "a pen" }}</span>
-> <span>Is this a pen?</span>
● replaceRE

Replaces all matches of the regular expression pattern with the replacement string in the input string.

Syntax
replaceRE PATTERN REPLACEMENT INPUT
Example
{{ replaceRE "^https?://([^/]+).*" "$1" "https://github.com/WhiteRaven777/simple-render" }}
-> github.com

{{ "https://github.com/WhiteRaven777/simple-render" | replaceRE "^https?://([^/]+).*" "$1" }}
-> github.com
● safeCSS

Marks the input as safe CSS content to prevent escaping.

Syntax
safeCSS INPUT
Example

<p style="{{ .Style }}">...</p>
-> <p style="ZgotmplZ">...</p>

<p style="{{ .Style | safeCSS }}">...</p>
-> <p style="color: red;">...</p>
● safeHTML

Marks the input as safe HTML content to prevent escaping.

Syntax
safeHTML INPUT
Example
# Link = `<a href="https://example.com">sample</a>`

{{ .Link }}
-> &lt;a href=&#34;https://example.com&#34;&gt;sample&#34;/a&gt;

{{ .Link | safeHTML }}
-> <a href="https://example.com">sample</a>
● safeHTMLAttr

Marks the input as a safe HTML attribute to prevent escaping.

Syntax
safeHTMLAttr INPUT
Example
Url = "https://example.com"

<a href="{{ .Url }}">
-> <a href="#ZgotmplZ">

<a {{ printf "href=%q" .Url | safeHTMLAttr }}>
-> <a href="https://example.com">
● safeJS

Marks the input as safe JavaScript content to prevent escaping.

Syntax
safeJS INPUT
Example
Hash = "abc123"

<script>var form_{{ .Params.hash }}</script>
-> <script>var form_"abc123"</script>

<script>var form_{{ .Params.hash | safeJS }}</script>
-> <script>var form_abc123</script>
● safeURL

Marks the input as a safe URL to prevent escaping.

Syntax
safeURL INPUT
Example
Url = "https://example.com"

<a href="{{ .Url }}">
-> <a href="#ZgotmplZ">

<a href="{{ .Url | safeURL }}">
-> <a href="https://example.com">
● slice

Creates a slice from the input elements.

Syntax
slice ITEM...
Example
{{ print (slice 0 1 2) }}
-> [0 1 2]
● split

Splits the input string by the specified delimiter and returns a slice of substrings.

Syntax
split STRING DELIMITER
Example
{{ split "SAMPLE-TEXT" "-" }}
-> [SAMPLE TEXT]

{{ split "AAA+BBB-CCC+DDD" "+" }}
-> [AAA BBB-CCC DDD]
● time

Returns the current time in HH:MM:SS format (UTC).

Syntax
time
Example

Assuming the current time is 17:18:19 (UTC)
{{ time }}
-> 17:18:19
● trim

Trims the specified characters from both ends of the input string. If no characters are specified, it trims whitespace by default.

Syntax
trim [CHARACTERS]
Example
{{ trim "!!?? abcdef ??!!" "!?" }}
-> " abcdef "

{{ trim " abcdef " }}
-> "abcdef"
● trimLeft

Trims the specified characters from the left side of the input string. If no characters are specified, it trims whitespace by default.

Syntax
trimLeft [CHARACTERS]
Example
{{ trimLeft "!!?? abcdef ??!!" "!?" }}
-> " abcdef ??!!"

{{ trimLeft " abcdef " }}
-> "abcdef "
● trimRight

Trims the specified characters from the right side of the input string. If no characters are specified, it trims whitespace by default.

Syntax
trimRight [CHARACTERS]
Example
{{ trimRight "!!?? abcdef ??!!" "!?" }}
-> "!!?? abcdef "

{{ trimRight " abcdef " }}
-> " abcdef"
● upper

Converts the input string(s) to uppercase.

Syntax
upper INPUT
Example
{{ $arr := slice "a" "b" "c" }}
{{ range $arr }}{{ upper . }}{{ end }}
-> A B C
● year

Returns the current year as an integer (UTC).

Syntax
year
Example
# Assuming today is 2019-02-14 17:18:19 (UTC)

{{ year }}
-> 2019

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HTML deprecated

func HTML(w io.Writer, status int, data any, layout string, ext ...string)

HTML renders the template as HTML to the provided io.Writer.

Deprecated: Use Template.HTML method instead.

func JSON

func JSON(w io.Writer, status int, data any)

JSON encodes the provided data as JSON and writes it to the provided io.Writer.

This method takes an io.Writer (typically an http.ResponseWriter), an HTTP status code, and the data to be encoded as JSON. It writes the JSON-encoded data to the writer and sets the HTTP status code on the http.ResponseWriter.

Parameters: - w: io.Writer to which the JSON-encoded data will be written. This is usually an http.ResponseWriter. - status: HTTP status code to set on the http.ResponseWriter. - data: The data to be JSON-encoded and written to the writer.

Example usage:

func handler(w http.ResponseWriter, r *http.Request) {
    data := map[string]string{
        "message": "Hello, World!",
    }
    JSON(w, http.StatusOK, data)
}

Types

type Template added in v0.1.5

type Template struct {
	OsFiles      []*os.File
	HttpFiles    []http.File
	Layout       string
	Data         any
	ExtraFuncMap template.FuncMap
}

Template represents a web template that includes references to OS files, embedded files, a layout, data, and additional functions.

This structure holds the necessary components to render a web page, including references to OS files, embedded files (using http.File from an embed.FS), a layout template, data to be rendered, and additional template functions.

Fields:

  • OsFiles: A slice of pointers to os.File objects representing files to be read from the filesystem.
  • HttpFiles: A slice of http.File objects representing embedded files accessible via the http package.
  • Layout: The name of the layout template to be used with html/template.ExecuteTemplate for rendering.
  • Data: The data to be passed to the template for rendering.
  • ExtraFuncMap: A map of additional functions to be used in the template, extending the default template functionality.

Example usage:

tmpl := Template{
    OsFiles: []*os.File{file1, file2},
    HttpFiles: []http.File{httpFile1, httpFile2},
    Layout: "layout",  // This is the name of the layout template, not a file name.
    Data: myData,
    ExtraFuncMap: template.FuncMap{
        "customFunc": func() string { return "Custom Function" },
    },
}

This structure allows for flexible and powerful rendering of web pages, supporting a wide range of use cases including the inclusion of both local and embedded files, custom data, and additional template functions.

func (Template) HTML added in v0.1.5

func (t Template) HTML(w io.Writer, status int)

HTML renders the template as HTML to the provided io.Writer.

This method takes an io.Writer (typically an http.ResponseWriter) and an HTTP status code. It renders the template with the given data and writes the resulting HTML to the writer. The HTTP status code is set on the http.ResponseWriter to indicate the response status.

Parameters: - w: io.Writer to which the rendered HTML will be written. This is usually an http.ResponseWriter. - status: HTTP status code to set on the http.ResponseWriter.

Example usage:

func handler(w http.ResponseWriter, r *http.Request) {
    tmpl := Template{
        Layout: "layout.html",
        Data:   myData,
    }
    tmpl.HTML(w, http.StatusOK)
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL