template

package
v0.40.1 Latest Latest
Warning

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

Go to latest
Published: Nov 13, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package template provides the scriptling.template.html and scriptling.template.text extension libraries (Go html/template and text/template).

Index

Constants

View Source
const (
	HTMLLibraryName = "scriptling.template.html"
	TextLibraryName = "scriptling.template.text"
)

Library names.

Variables

View Source
var HTMLLibrary = object.NewLibrary(HTMLLibraryName, map[string]*object.Builtin{
	"Set": {
		Fn: func(ctx context.Context, kwargs object.Kwargs, args ...object.Object) object.Object {
			if err := errors.ExactArgs(args, 0); err != nil {
				return err
			}
			left, errObj := kwargs.GetString("left", "")
			if errObj != nil {
				return errObj
			}
			right, errObj := kwargs.GetString("right", "")
			if errObj != nil {
				return errObj
			}
			t := htmltemplate.New("").Delims(left, right)
			return newSetInstance(&parsedTemplateSet{html: t})
		},
		HelpText: `Set(left="", right="") - Create a new HTML template set (uses html/template with auto-escaping)

Parameters:
  left (str, optional): Left action delimiter, default "{{"
  right (str, optional): Right action delimiter, default "}}"

Returns:
  Set: A template set with add(source) and render([name,] data) methods

Example:
  import scriptling.template.html as html

  # Simple template
  tmpl = html.Set()
  tmpl.add("Hello, {{.Name}}!")
  print(tmpl.render({"Name": "Alice"}))

  # With partials
  tmpl = html.Set()
  tmpl.add('{{define "header"}}<h1>{{.Title}}</h1>{{end}}')
  tmpl.add('{{define "page"}}{{template "header" .}}<p>{{.Body}}</p>{{end}}')
  print(tmpl.render("page", {"Title": "Home", "Body": "Welcome"}))

  # Custom delimiters, e.g. {% %} to avoid clashing with literal {{ }}
  tmpl = html.Set(left="{%", right="%}")
  tmpl.add("<p>{%.Name%}</p>")`,
	},
}, map[string]object.Object{}, "Go html/template rendering with automatic HTML escaping")

HTMLLibrary provides html/template rendering with automatic HTML escaping

View Source
var SetClass = &object.Class{
	Name: "Set",
	Methods: map[string]object.Object{
		"add": &object.Builtin{
			Fn: func(ctx context.Context, kwargs object.Kwargs, args ...object.Object) object.Object {
				if err := errors.ExactArgs(args, 2); err != nil {
					return err
				}
				self, ok := args[0].(*object.Instance)
				if !ok {
					return errors.NewError("add() called on non-Set object")
				}
				src, err := args[1].AsString()
				if err != nil {
					return err
				}
				pt := getTemplateSet(self)
				if pt == nil {
					return errors.NewError("Set not initialised")
				}
				if pt.html != nil {
					if _, parseErr := pt.html.Parse(src); parseErr != nil {
						return errors.NewError("template parse error: %s", parseErr.Error())
					}
				} else {
					if _, parseErr := pt.text.Parse(src); parseErr != nil {
						return errors.NewError("template parse error: %s", parseErr.Error())
					}
				}
				return &object.Null{}
			},
			HelpText: `add(source) - Add a template source to the set

Parameters:
  source (string): Template source, may contain {{define "name"}}...{{end}} blocks

Example:
  tmpl = html.Set()
  tmpl.add('{{define "header"}}<h1>{{.Title}}</h1>{{end}}')
  tmpl.add('{{define "page"}}{{template "header" .}}<p>{{.Body}}</p>{{end}}')`,
		},
		"render": &object.Builtin{
			Fn: func(ctx context.Context, kwargs object.Kwargs, args ...object.Object) object.Object {
				if err := errors.RangeArgs(args, 1, 3); err != nil {
					return err
				}
				self, ok := args[0].(*object.Instance)
				if !ok {
					return errors.NewError("render() called on non-Set object")
				}

				// render(data) or render(name, data)
				var name string
				var data object.Object = &object.Null{}
				switch len(args) {
				case 2:
					data = args[1]
				case 3:
					n, err := args[1].AsString()
					if err != nil {
						return err
					}
					name = n
					data = args[2]
				}

				pt := getTemplateSet(self)
				if pt == nil {
					return errors.NewError("Set not initialised")
				}

				goData, limitErr := conversion.ToGoLimited(data)
				if limitErr != nil {
					return limitErr
				}
				result, execErr := renderTemplateSet(ctx, pt, name, goData)
				if stderrors.Is(execErr, errRenderNoRoom) {
					return object.NewMemoryError("%s: no room for the rendered template", object.ErrMemoryLimitExceeded)
				}
				if stderrors.Is(execErr, errRenderTooLarge) {
					return object.NewMemoryError("rendered template too large: the limit is %d bytes", object.MaxValueBytes())
				}
				if execErr != nil {
					return errors.NewError("template render error: %s", execErr.Error())
				}
				return object.NewString(result)
			},
			HelpText: `render(data) or render(name, data) - Render a template from the set

Parameters:
  name (string, optional): Name of the template to render (from {{define "name"}})
  data (dict): Template data

Returns:
  string: Rendered output

Example:
  # Anonymous / single template
  tmpl.render({"Name": "Alice"})

  # Named template
  tmpl.render("page", {"Title": "Home", "Body": "Welcome"})`,
		},
	},
}

SetClass is the class for Set objects

View Source
var TextLibrary = object.NewLibrary(TextLibraryName, map[string]*object.Builtin{
	"Set": {
		Fn: func(ctx context.Context, kwargs object.Kwargs, args ...object.Object) object.Object {
			if err := errors.ExactArgs(args, 0); err != nil {
				return err
			}
			left, errObj := kwargs.GetString("left", "")
			if errObj != nil {
				return errObj
			}
			right, errObj := kwargs.GetString("right", "")
			if errObj != nil {
				return errObj
			}
			t := texttemplate.New("").Delims(left, right)
			return newSetInstance(&parsedTemplateSet{text: t})
		},
		HelpText: `Set(left="", right="") - Create a new text template set (uses text/template, no HTML escaping)

Parameters:
  left (str, optional): Left action delimiter, default "{{"
  right (str, optional): Right action delimiter, default "}}"

Returns:
  Set: A template set with add(source) and render([name,] data) methods

Example:
  import scriptling.template.text as text

  # Simple template
  tmpl = text.Set()
  tmpl.add("Hello, {{.Name}}!")
  print(tmpl.render({"Name": "Alice"}))

  # With partials
  tmpl = text.Set()
  tmpl.add('{{define "greeting"}}Hello, {{.Name}}!{{end}}')
  tmpl.add('{{define "email"}}{{template "greeting" .}}\n\nYour order is ready.{{end}}')
  print(tmpl.render("email", {"Name": "Alice"}))

  # Custom delimiters, e.g. {% %} to avoid clashing with literal {{ }}
  tmpl = text.Set(left="{%", right="%}")
  tmpl.add("Hello, {%.Name%}!")`,
	},
}, map[string]object.Object{}, "Go text/template rendering with no escaping")

TextLibrary provides text/template rendering with no escaping

Functions

func RegisterHTML

func RegisterHTML(registrar interface{ RegisterLibrary(*object.Library) })

RegisterHTML registers the scriptling.template.html library.

func RegisterText

func RegisterText(registrar interface{ RegisterLibrary(*object.Library) })

RegisterText registers the scriptling.template.text library.

Types

This section is empty.

Jump to

Keyboard shortcuts

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