Reglue Go

View

tests linux macos windows

Table Of Contents

Introduction

Views separate your application logic from your presentation logic. They are stored in files or directly rendered from strings. View templates are usually written using the Golang templating language. A simple golang template looks like this:

<!-- View stored in templates/greeting.gohtml -->

<!DOCTYPE html>
<html lang="en">
	<body>
		<h1>Hello, 󠁻{{․}}</h1>
		󠁻 {{block "footer" ․}}
		<p>© 2024</p>
		{{end}}
	</body>
</html>

This view is stored at templates/greeting.gohtml and we may compile it like so:

package main

import "github.com/reglue4go/view"

func main() {
	compiled := view.NewFactory("templates").Make("greeting.gohtml", "Jane")

	fmt.Printf("%v\n", compiled)
	/*
	<!DOCTYPE html>
	<html lang="en">
		<body>
			<h1>Hello, Jane</h1>

			<p>© 2024</p>
		</body>
	</html>
	*/
}

View Factory

Rendering views is primarily handled by the view factory. A view factory instance can be reused multiple times for rendering templates.

package main

import "github.com/reglue4go/view"

func main() {
	factory := view.NewFactory("templates")

	greetJane := factory.Make("greeting.gohtml", "Jane")

	fmt.Printf("%v\n", greetJane)
	/*
	<!DOCTYPE html>
	<html lang="en">
		<body>
			<h1>Hello, Jane</h1>

			<p>© 2024</p>
		</body>
	</html>
	*/

	greetBob := factory.Make("greeting.gohtml", "Bob")

	fmt.Printf("%v\n", greetBob)
	/*
	<!DOCTYPE html>
	<html lang="en">
		<body>
			<h1>Hello, Bob</h1>

			<p>© 2024</p>
		</body>
	</html>
	*/
}

View Factory Methods

CompilerViews DefaultLayout Make
MakeUsing Resolver SetDefaultLayout

CompilerViews

The CompilerViews method returns a list of views to be compiled. If the view factory has a default layout, it will be added to the list.

package main

import "github.com/reglue4go/view"

func main() {
	list := view.NewFactory("templates").CompilerViews("greeting.gohtml")

	fmt.Printf("%v\n", list)
	// ["layouts/app.gohtml", "greeting.gohtml"]
}

DefaultLayout

Most applications maintain the same general layout across various pages. Layouts provide a convenient way of defining a single base template and then use it throughout the application. The view factory DefaultLayout method returns the default layout for all views. You can set the default layout by providing an optional template path argument to the DefaultLayout method.

package main

import "github.com/reglue4go/view"

func main() {
	factory := view.NewFactory("templates")

	defaultLayout := factory.DefaultLayout()

	fmt.Printf("%v\n", defaultLayout)
	// "layouts/app"

	factory.DefaultLayout("layouts/blog")

	fmt.Printf("%v\n", factory.DefaultLayout())
	// "layouts/blog"
}

Make

You may render a view by passing a file name with the .gohtml extension to the view factory Make method. The file extension determins the view compiler to be used. If you omit a file name extension, the assumed extension will be gohtml. When using a custom view compiler, the file name and extension must be provided.

package main

import "github.com/reglue4go/view"

func main() {
	factory := view.NewFactory("templates")

	compiled := factory.Make("greeting.gohtml", "Jane")

	compiledAgain := factory.Make("greeting", "Jane")

	fmt.Printf("%v\n", compiled == compiledAgain)
	// true

	fmt.Printf("%v\n", compiled)
	/*
	<!DOCTYPE html>
	<html lang="en">
		<body>
			<h1>Hello, Jane</h1>

			<p>© 2024</p>
		</body>
	</html>
	*/
}

MakeUsing

The MakeUsing method renders the template using a provided layout.

compiled := view.NewFactory("templates").
	MakeUsing("layouts/email", "welcome", map[string]any{
		"address": "jane@gmail.io",
		"to": "jane",
	})

Resolver

The Resolver method returns the view Resolver instance used by the factory.

viewResolver := view.NewFactory("templates").Resolver()

SetDefaultLayout

The SetDefaultLayout method sets the default layout to be used for all views.

factory := view.NewFactory("templates").SetDefaultLayout("layouts/blog")

fmt.Printf("%v\n", factory.DefaultLayout())
// "layouts/blog"

View Resolver

The view Resolver is responsible for locating views and associating them with verious compilers.

View Resolver Methods

AddCompiler AddLocation Compile
Data DefaultCompiler DefaultExtension
DotExtension Exists Files
IsLoaded Load Locations
NormalizeName ResolveCompiler SetDefaultCompiler
SetDefaultExtension SetLocation Share
TagCompiler Tags TemplateCompilers

TemplateCompilers

The TemplateCompilers method returns a map of registered extensions and their corresponding compilers.

Tags

The Tags method returns a map of registered tags and their corresponding aliases.

tags := view.NewFactory("templates").Resolver().Tags()

fmt.Printf("%v\n", tags)
// map[htm:gohtml html:gohtml]

TagCompiler

Tags are aliases to existing view compilers. They are used to associate extensions with compilers. If you wish to use an HTML compiler for compiling files with .htm extension, simply tag the html compiler with an htm extension by calling the TagCompiler method.

Share

The Share method adds a piece of shared data to the environment. Unlike the Data method, it can be chained.

compiled := view.NewFactory("templates").Resolver().Share("Jane").Compile("greeting.gohtml")

SetLocation

The SetLocation method registers view locations and returns the Resolver instance.

resolver := view.NewFactory().Resolver().SetLocation("templates", "themes/dark")

SetDefaultExtension

The SetDefaultExtension registers a default view file extension.

resolver := view.NewFactory("templates").Resolver().SetDefaultExtension("amber")

SetDefaultCompiler

The SetDefaultCompiler registers a default template compiler callback. Whenever a compiler for an extension cannot be resolved, the default compiler will be used.

ResolveCompiler

The ResolveCompiler gets the compiler for a given extension.

NormalizeName

The NormalizeName method ensures an extension is included in the given view name.

resolver := view.NewFactory("templates").Resolver()

extension := resolver.NormalizeName("greeting")

fmt.Printf("%v\n", extension == "greeting.gohtml")
// true

extension2 := resolver.NormalizeName("greeting.gohtml")

fmt.Printf("%v\n", extension2 == "greeting.gohtml")
// true

Locations

The Locations method returns a list of registered view locations. If you provide a list of locations as arguments, they will be registered.

resolver := view.NewFactory("templates").Resolver()

list := resolver.Locations("themes/default")

fmt.Printf("%v\n", list)
// ["templates" "themes/default"]

Load

The Load method locates and maps view files from the provided paths.

IsLoaded

The IsLoaded method determines if view files have been located.

Files

The Files method returns a list of located views.

Exists

The Exists method determines if a given view exists.

resolver := view.NewFactory("templates").Resolver()

found := resolver.Exists("greeting")

fmt.Printf("%v\n", found)
// true

DotExtension

The DotExtension method prefixes a dot in the given extension.

resolver := view.NewFactory("templates").Resolver()

extension := resolver.DotExtension("gohtml")

fmt.Printf("%v\n", extension == ".gohtml")
// true

extension2 := resolver.DotExtension(".gohtml")

fmt.Printf("%v\n", extension2 == ".gohtml")
// true

DefaultExtension

The DefaultExtension method sets and returns the default view extension.

resolver := view.NewFactory("templates").Resolver()

extension := resolver.DefaultExtension("amber")

fmt.Printf("%v\n", extension == "amber")
// true

DefaultCompiler

The DefaultCompiler method sets and returns the default view compiler callback.

Data

The Data method returns a piece of shared data from the environment. You can optionally share a piece of data as an argument.

resolver := view.NewFactory("templates").Resolver()
resolver.Data("Jane")
compiled := resolver.Compile("greeting.gohtml")

Compile

The Compile method compiles a list of views and returns a string.

resolver := view.NewFactory("templates").Resolver()
compiled := resolver.Compile("layouts/app.gohtml", "home.gohtml")

AddLocation

The AddLocation adds directories where view template files are located.

resolver := view.NewFactory("templates").Resolver().
	AddLocation("themes/light", "themes/dark").
	AddLocation("themes/default")

AddCompiler

The AddCompiler method registers a view extension and its compiler. Template compilers are view handler callbacks functions. The first argument to the AddCompiler method is a view extension while second argument is a callback function.

package main

import (
	"bytes"
 	"github.com/eknkc/amber"
 	"github.com/reglue4go/view"
 )

func main() {
	resolver := NewFactory("templates").Resolver()
	// register a view compiler for amber file extension
	resolver.AddCompiler("amber", func(resolver *view.Resolver, paths ...string) string {
		if len(paths) > 0 {
			name := resolver.NormalizeName(paths[0])
			file := resolver.Load().Files()[name]
			compiler := amber.New()
			if err := compiler.ParseFile(file); err == nil {
				if temp, err := compiler.Compile(); err == nil {
					var value bytes.Buffer
					temp.Execute(&value, resolver.Data())
					return value.String()
				}
			}
		}
		return ""
		},
	)

	compiled := resolver.Share("Jane").Compile("greeting.amber")
}

Unit Tests Matrix

This package has been tested on the following platforms.

golang ubuntu macos windows
1.18.x
1.20.x
1.22.x
Go logo