render

package
v0.5.4 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2024 License: MIT Imports: 17 Imported by: 1

Documentation

Overview

Package render provides an interface for rendering HTML templates and implementations for loading templates from directories or filesystems. It supports template lookup, reloading, and efficient template handling.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoadTemplateFS

func LoadTemplateFS(_fs fs.FS, baseDir string, patterns ...string) (*template.Template, error)

LoadTemplateFS will load a template from a fs.FS.

func RenderMarkdownTemplateToHTML

func RenderMarkdownTemplateToHTML(t *template.Template, data interface{}) (string, error)

func RenderMarkdownToHTML

func RenderMarkdownToHTML(rendered string) (string, error)

Types

type LookupTemplateFromDirectory

type LookupTemplateFromDirectory struct {
	Directory string
}

LookupTemplateFromDirectory will load a template at runtime. This is useful for testing local changes to templates without having to recompile the app.

Example
lookup := NewLookupTemplateFromDirectory("./templates")
tmpl, err := lookup.Lookup("templates/tests/test.html")
if err != nil {
	fmt.Println("Error:", err)
	return
}
fmt.Println("Template:", tmpl.Name())
Output:

func NewLookupTemplateFromDirectory added in v0.3.0

func NewLookupTemplateFromDirectory(directory string) *LookupTemplateFromDirectory

func (*LookupTemplateFromDirectory) Lookup added in v0.3.0

func (l *LookupTemplateFromDirectory) Lookup(name ...string) (*template.Template, error)

Lookup will load the matching template file from the given Directory. This loads the template file on every lookup, and is thus not very efficient.

The names passed as arguments correspond to the relative paths of the parsed files starting from configured template directory.

TODO(manuel, 2023-05-28) Implement a reloadable LookupTemplateFromDirectory This would distract too much from the current task which is to implement the high-level surface TemplateLookup abstraction and then write up the parka ConfigFile code and documentation.

See https://github.com/go-go-golems/parka/issues/49

func (*LookupTemplateFromDirectory) Reload added in v0.3.0

func (l *LookupTemplateFromDirectory) Reload(_ ...string) error

Reload has an empty implementation, since the lookup happens on every request.

type LookupTemplateFromFS

type LookupTemplateFromFS struct {
	// contains filtered or unexported fields
}

LookupTemplateFromFS will load a template from a fs.FS.

NOTE: this loads the entire template directory into memory on every lookup. This is not great for performance, but it is useful for development.

Per default, this exposes the current directory and uses the *html string pattern to load HTML templates.

Example
lookup := NewLookupTemplateFromFS(
	WithFS(os.DirFS("./templates")),
	WithBaseDir("./templates"),
	WithPatterns("*.html"),
)
tmpl, err := lookup.Lookup("tests/test.html")
if err != nil {
	fmt.Println("Error:", err)
	return
}
fmt.Println("Template:", tmpl.Name())
Output:

func NewLookupTemplateFromFS added in v0.3.0

func NewLookupTemplateFromFS(options ...LookupTemplateFromFSOption) *LookupTemplateFromFS

func (*LookupTemplateFromFS) Lookup added in v0.3.0

func (l *LookupTemplateFromFS) Lookup(name ...string) (*template.Template, error)

Lookup a template by name. If alwaysReload is specific, this will reload the entire template directory on every lookup.

func (*LookupTemplateFromFS) Reload added in v0.3.0

func (l *LookupTemplateFromFS) Reload(name ...string) error

Reload all templates from the fs / basedir. This ignores the partial reload, so depending on your setup, be mindful of the performance impact.

type LookupTemplateFromFSOption added in v0.3.0

type LookupTemplateFromFSOption func(*LookupTemplateFromFS)

func WithAlwaysReload added in v0.3.0

func WithAlwaysReload(alwaysReload bool) LookupTemplateFromFSOption

func WithBaseDir added in v0.3.0

func WithBaseDir(baseDir string) LookupTemplateFromFSOption

func WithFS added in v0.3.0

func WithFS(_fs fs.FS) LookupTemplateFromFSOption

func WithPatterns added in v0.3.0

func WithPatterns(patterns ...string) LookupTemplateFromFSOption

type LookupTemplateFromFile added in v0.3.0

type LookupTemplateFromFile struct {
	File string
	// The templateName to respond to, if empty, all templates request will return the file content.
	TemplateName string
}

LookupTemplateFromFile will load a template from a filesystem. It will always return the content of that file when queried, independent of the actual name requested.

func NewLookupTemplateFromFile added in v0.3.0

func NewLookupTemplateFromFile(file string, path string) *LookupTemplateFromFile

func (*LookupTemplateFromFile) Lookup added in v0.3.0

func (l *LookupTemplateFromFile) Lookup(name ...string) (*template.Template, error)

func (*LookupTemplateFromFile) Reload added in v0.3.0

func (l *LookupTemplateFromFile) Reload(name ...string) error

type NoPageFoundError added in v0.2.28

type NoPageFoundError struct {
	Page string
}

NoPageFoundError is returned by Render if no template was found, in which case the Render is skipped and moves on to the next middleware.

func (*NoPageFoundError) Error added in v0.2.28

func (e *NoPageFoundError) Error() string

type Renderer added in v0.2.28

type Renderer struct {
	Data            map[string]interface{}
	TemplateLookups []TemplateLookup

	// MarkdownBaseTemplateName is used to wrap markdown that was rendered into HTML into a top-level page
	// NOTE(manuel, 2023-05-26) Maybe this should be a templateLookup that always returns the same template?
	MarkdownBaseTemplateName string

	IndexTemplateName string
}

Renderer is a struct that is able to lookup a page name and render it. It can handle a variety of formats: - static HTML - static markdown - templated HTML - templated markdown - base HTML template to render markdown into - index page templates

It is an early replacement for what used to be the templateLookup approach in parka.Server.

NOTE(manuel, 2023-05-26) Some notes on the implementation rationale

Driven by the needs for richer handling of templates mixing commands and content when building reports pages with sqleton, the templateLookup approach of server, which was confusing from the start, was breaking down.

In order to more easily to configure the reports page, which would expose different command repositories with manually overloaded rendering templates (datatables.tmpl.html) as well as static content (index page, documentation pages), I refactored the haphazard templatelookup concept to be configured from a config file and split it into different "modules" that could be "mounted" under different paths: - static file - static dir - single command - command dir - template file - template dir

It is while implementing the template dir that I realized that a more generic "render paths based on configured templates directories and data" as a common building block. In a way it is what I was originally searching for with the template lookups pattern, but I mixed it with the concerns of serving files in parka, instead of just focusing on "render pages".

func NewRenderer added in v0.2.28

func NewRenderer(opts ...RendererOption) (*Renderer, error)

func (*Renderer) Handle added in v0.2.28

func (r *Renderer) Handle(data map[string]interface{}) gin.HandlerFunc

func (*Renderer) HandleWithTemplate added in v0.2.28

func (r *Renderer) HandleWithTemplate(
	templateName string,
	data map[string]interface{},
) gin.HandlerFunc

func (*Renderer) HandleWithTrimPrefix added in v0.2.28

func (r *Renderer) HandleWithTrimPrefix(prefix string, data map[string]interface{}) gin.HandlerFunc

func (*Renderer) LookupTemplate added in v0.2.28

func (r *Renderer) LookupTemplate(name ...string) (*template.Template, error)

LookupTemplate will iterate through the template lookups until it finds one of the templates given in name.

func (*Renderer) Render added in v0.2.28

func (r *Renderer) Render(
	c *gin.Context,
	page string,
	data map[string]interface{},
) error

Render a given page with the given data.

It first looks for a markdown file or template called either page.md or page.tmpl.md, and render it as a template, passing it the given data. It will use base.tmpl.html as the base template for serving the resulting markdown HTML. page.md is rendered as a plain markdown file, while page.tmpl.md is rendered as a template.

If no markdown file or template is found, it will look for a HTML file or template called either page.html or page.tmpl.html and serve it as a template, passing it the given data. page.html is served as a plain HTML file, while page.tmpl.html is served as a template.

NOTE(manuel, 2023-06-21) Render renders directly into the http.ResponseWriter, which means that an error in the template rendering will not be able to update the headers, as those will have already been sent. This could lead to partial writes with an error code of 200 if there is an error rendering the template, not sure if that's exactly what we want.

type RendererOption added in v0.2.28

type RendererOption func(r *Renderer) error

func WithAppendTemplateLookups added in v0.2.28

func WithAppendTemplateLookups(lookups ...TemplateLookup) RendererOption

WithAppendTemplateLookups will append the given template lookups to the list of lookups, but they will be found after whatever templates might already be in the list. This is great for providing fallback templates.

func WithIndexTemplateName added in v0.2.28

func WithIndexTemplateName(name string) RendererOption

func WithMarkdownBaseTemplateName added in v0.2.28

func WithMarkdownBaseTemplateName(name string) RendererOption

WithMarkdownBaseTemplateName will set the name of the template to use as the base template when rendering the HTML coming out of markdown rendering into HTML.

func WithMergeData added in v0.2.28

func WithMergeData(data map[string]interface{}) RendererOption

WithMergeData will merge the given data into the renderer's data.

func WithPrependTemplateLookups added in v0.2.28

func WithPrependTemplateLookups(lookups ...TemplateLookup) RendererOption

WithPrependTemplateLookups will prepend the given template lookups to the list of lookups, ensuring that they will be found before whatever templates might already be in the list.

func WithReplaceData added in v0.2.28

func WithReplaceData(data map[string]interface{}) RendererOption

WithReplaceData will replace the data the renderer uses to render out templates with the passed in data.

func WithReplaceTemplateLookups added in v0.2.28

func WithReplaceTemplateLookups(lookups ...TemplateLookup) RendererOption

WithReplaceTemplateLookups will replace any existing template lookups with the given ones.

type TemplateLookup

type TemplateLookup interface {
	// Lookup returns a template by name. If there are multiple names given,
	// implementations may choose how to handle them.
	Lookup(name ...string) (*template.Template, error)

	// Reload reloads all or partial templates (necessary to render the given templates).
	// `name` can easily be ignored if the implementation doesn'Template support partial reloading.
	// This is useful for example to have server expose a specific route that reloads
	// all templates in case new files get uploaded, without having to restart the server.
	// This is also useful for development, where partial reloading is probably less important
	// and performance is not paramount, and as such a full reload on every request could be configured.
	Reload(name ...string) error
}

TemplateLookup is an interface for objects that can lookup a template by name. It is use as an interface to allow different ways of loading templates to be provided to a parka application.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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