feat(template): introduce template package for variable substitution

- Add new template package to handle variable substitution with {{variable}} syntax
- Move substitution logic from patterns to centralized template system
- Update patterns.go to use template package for variable processing
- Support special {{input}} handling for pattern content
- Update chatter.go and rest API to pass input parameter
- Enable multiple passes to handle nested variables
- Report errors for missing required variables

This change sets up a foundation for future templating features like front matter
and plugin support while keeping the substitution logic centralized.
This commit is contained in:
Matt Joyce
2024-11-19 16:57:14 +11:00
parent 1f07ea25a2
commit d475e7b568
3 changed files with 29 additions and 12 deletions

View File

@@ -102,7 +102,8 @@ func (o *Chatter) BuildSession(request *common.ChatRequest, raw bool) (session *
var patternContent string
if request.PatternName != "" {
pattern, err := o.db.Patterns.GetApplyVariables(request.PatternName, request.PatternVariables)
pattern, err := o.db.Patterns.GetApplyVariables(request.PatternName, request.PatternVariables, request.Message.Content)
if err != nil {
return nil, fmt.Errorf("could not get pattern %s: %v", request.PatternName, err)
}

View File

@@ -5,6 +5,8 @@ import (
"os"
"path/filepath"
"strings"
"github.com/danielmiessler/fabric/plugins/template"
)
type PatternsEntity struct {
@@ -21,7 +23,7 @@ type Pattern struct {
}
// main entry point for getting patterns from any source
func (o *PatternsEntity) GetApplyVariables(source string, variables map[string]string) (*Pattern, error) {
func (o *PatternsEntity) GetApplyVariables(source string, variables map[string]string, input string) (*Pattern, error) {
var pattern *Pattern
var err error
@@ -41,17 +43,29 @@ func (o *PatternsEntity) GetApplyVariables(source string, variables map[string]s
return nil, err
}
return o.applyVariables(pattern, variables), nil
pattern, err = o.applyVariables(pattern, variables, input)
if err != nil {
return nil, err // Return the error if applyVariables failed
}
return pattern, nil
}
// handles all variable substitution
func (o *PatternsEntity) applyVariables(pattern *Pattern, variables map[string]string) *Pattern {
if variables != nil && len(variables) > 0 {
for variableName, value := range variables {
pattern.Pattern = strings.ReplaceAll(pattern.Pattern, variableName, value)
func (o *PatternsEntity) applyVariables(pattern *Pattern, variables map[string]string, input string) (*Pattern, error) {
// If {{input}} isn't in pattern, append it on new line
if !strings.Contains(pattern.Pattern, "{{input}}") {
if !strings.HasSuffix(pattern.Pattern, "\n") {
pattern.Pattern += "\n"
}
pattern.Pattern += "{{input}}"
}
return pattern
result, err := template.ApplyTemplate(pattern.Pattern, variables, input)
if err != nil {
return nil, err
}
pattern.Pattern = result
return pattern, nil
}
// retrieves a pattern from the database by name
@@ -113,5 +127,5 @@ func (o *PatternsEntity) getFromFile(pathStr string) (*Pattern, error) {
// Get required for Storage interface
func (o *PatternsEntity) Get(name string) (*Pattern, error) {
// Use GetPattern with no variables
return o.GetApplyVariables(name, nil)
return o.GetApplyVariables(name, nil, "")
}

View File

@@ -1,9 +1,10 @@
package restapi
import (
"net/http"
"github.com/danielmiessler/fabric/plugins/db/fsdb"
"github.com/gin-gonic/gin"
"net/http"
)
// PatternsHandler defines the handler for patterns-related operations
@@ -26,7 +27,8 @@ func NewPatternsHandler(r *gin.Engine, patterns *fsdb.PatternsEntity) (ret *Patt
func (h *PatternsHandler) Get(c *gin.Context) {
name := c.Param("name")
variables := make(map[string]string) // Assuming variables are passed somehow
pattern, err := h.patterns.GetApplyVariables(name, variables)
input := "" // Assuming input is passed somehow
pattern, err := h.patterns.GetApplyVariables(name, variables, input)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
return