Package esi provides functions for parsing and processing ESI from arbitrary inputs.
To parse ESI from arbitrary io.Reader, first create a new esi.Parser using esi.NewParser.
parser := esi.NewParser(reader)It is also possible to initialize or re-use a parser from an existing instance, using Parser.Reset:
var parser esi.Parser
parser.Reset(reader)
Once the parser has been created, either use Parser.Next to read each node from the input, or, use Parser.All to directly iterate over the stream of nodes:
for node, err := parser.All {
if err != nil {
panic(err)
}
}Once the input is parsed, it can be used processed using the esiproc package.
To do this first create a esiproc.Processor using esiproc.New and configure it to fetch data for ESI includes.
The esihttp package implements a custom type that can be used to resolve includes via HTTP.
proc := esiproc.New(
esiproc.WithClient(&esihttp.Client{}),
esiproc.WithClientConcurrency(4))Once created the processor can be used to process multiple sets of nodes, both sequentially and concurrently.
To actually process some data, call the Processor.Process method. The method takes a context.Context, an
io.Writer that will be written to and a sequence of ESI nodes.
Assuming the variable parser contains a esi.Parser, one could process its nodes like this:
var buf bytes.Buffer
if err := proc.Process(ctx, &buf, parser.All); err != nil {
panic(err)
}
// Output the processed content
fmt.Println(buf.Bytes())By default, <esi:when/> elements will result in an error. To fix this, an esiproc.EvalFunc must be configured and
passed to the esiproc.Processor using the esiproc.WithEvalFunc function.
Similarly, variables in the alt or src attributes of <esi:include/> tags are not interpolated by default. This can
be enabled by providing an esiproc.InterpolateFunc using esiproc.WithInterpolateFunc.
The esiexpr package implements an Env type that provides methods for evaluating ESI expressions for use with
<esi:when/> elements as well as the interpolation of variable in arbitrary strings.
Once an Env has been created its method can be used with esiproc.WithEvalFunc and esiproc.WithInterpolateFunc to
configure ann esiproc.Proc like this:
myEnv := &esiproc.Env{
LookupVar: func(ctx context.Context, name string, key *string) (ast.Value, error) {
// ...lookup name and return the value
return val, nil
},
}
proc := esiproc.New(
esiproc.WithEvalFunc(myEnv.Eval),
esiproc.WithInterpolateFunc(myEnv.Interpolate))Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.