Consider the following interaction:
This is the root page You have visited 1 time. 0:foo 1:bar $ 1 Please visit foo first. Any input to return. $ x This is the root page. You have visited 2 times. 0:foo 1:bar $ 0 Welcome to page foo. Please write seomthing. $ blah blah blah This is the root page. You have visited 3 times. 0:foo 1:bar $ 1 Thanks for visiting foo and bar. You have written: blah blah blah
The simple interface above involves four different menu nodes.
In order to engineer these using vise, three types of components are involved:
The nodes are:
rootThe first page.
fooThe "foo" page.
barThe "bar" page after "foo" has been visited.
ouchThe "bar" page before "foo" has been visited.
Each page has a template that may or may not contain dynamic elements.
In this example the root and bar nodes contains dynamic content.
This is the root page
You have visited {{.count}}.
Welcome to page foo. Please write something.
Thanks for visiting foo and bar.
You wrote "{{.something}}" in foo.
Please visit foo first. Any input to return.
The scripts are responsible for defining menus, handling navigation flow control, and triggering external code handlers.
LOAD count 8 # trigger external code handler "count" LOAD something 0 # trigger external code handler "something" RELOAD count # explicitly trigger "count" every time this code is executed. MAP count # make the result from "count" available to the template renderer MOUT foo 0 # menu item MOUT bar 1 # menu item HALT # render template and wait for input INCMP foo 0 # match menu selection 0, move to node "foo" on match INCMP bar 1 # match menu selection 1, move to node "bar" on match
HALT			# render template and wait for input
RELOAD something    	# pass input to the "something" external code handler.
                    	# The input will be appended to the stored value. 
                    	# The "HAVESOMETHING" flag (8) will be set.
MOVE _			# move up one level
CATCH ouch 8 0 # if the "HAVESOMETHING" (8) flag has NOT (0) been set, move to "ouch" MNEXT next 11 # menu choice to display for advancing one page MPREV back 22 # menu choice to display for going back to the previous page MAP something # make the result from "something" available to the template renderer HALT # render template and wait for input INCMP > 11 # handle the "next" menu choice INCMP < 22 # handle to "back" menu choice INCMP _ * # move to the root node on any input
HALT # render template and wait for input INCMP ^ * # move to the root node on any input
The script code contains LOAD instructions for two different methods. 
import (
	"context"
	"fmt"
	"path"
	"strings"
	testdataloader "github.com/peteole/testdata-loader"
	"git.defalsify.org/vise.git/state"
	"git.defalsify.org/vise.git/resource"
)
const (
	USERFLAG_HAVESOMETHING = iota + state.FLAG_USERSTART
)
var (
	baseDir = testdataloader.GetBasePath()
	scriptDir = path.Join(baseDir, "examples", "intro")
)
type introResource struct {
	*resource.FsResource 
	c int64
	v []string
}
func newintroResource() introResource {
	fs := resource.NewFsResource(scriptDir)
	return introResource{fs, 0, []string{}}
}
// increment counter.
// return a string representing the current value of the counter.
func(c *introResource) count(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	s := "%v time"
	if c.c != 1 {
		s += "s"
	}
	r := resource.Result{
		Content: fmt.Sprintf(s, c.c),
	}
	c.c += 1 
	return  r, nil
}
// if input is suppled, append it to the stored string vector and set the HAVESOMETHING flag.
// return the stored string vector value, one string per line.
func(c *introResource) something(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	c.v = append(c.v, string(input))
	r := resource.Result{
		Content: strings.Join(c.v, "\n"),
	}
	if len(input) > 0 {
		r.FlagSet = []uint32{USERFLAG_HAVESOMETHING}
	}
	return r, nil
}
In the above example, the more times the foo page is supplied with a value, the longer the vector of values that need to be displayed by the bar page will be.
A core feature of vise is to magically create browseable pages from these values, from a pre-defined maximum output capacity for each page. 
Consider the case where the contents of the something symbol has become:
foo bar baz bazbaz inky pinky blinky clyde
Given a size constaint of 90 characters, the display will be split into two pages:
Thanks for visiting foo and bar. You have written: foo bar baz bazbaz 11:next
Thanks for visiting foo and bar. You have written: inky pinky blinky clyde 22:back
In the source code repository, a full working example of this menu can be found in examples/intro.
To run it:
make -B intro go run ./examples/intro
Use go run -tags logtrace ... to peek at what is going on under the hood.
To play the Long Values case above, limit the output size by adding -s 90.