github.com/Jeffail/benthos/v3@v3.65.0/internal/docs/field_template.go (about) 1 package docs 2 3 import ( 4 "strings" 5 6 "github.com/Jeffail/benthos/v3/lib/util/config" 7 "github.com/Jeffail/gabs/v2" 8 ) 9 10 // FieldSpecCtx provides a field spec and rendered extras for documentation 11 // templates to use. 12 type FieldSpecCtx struct { 13 Spec FieldSpec 14 15 // FullName describes the full dot path name of the field relative to 16 // the root of the documented component. 17 FullName string 18 19 // ExamplesMarshalled is a list of examples marshalled into YAML format. 20 ExamplesMarshalled []string 21 22 // DefaultMarshalled is a marshalled string of the default value, if there is one. 23 DefaultMarshalled string 24 } 25 26 // FieldsTemplate returns a Go template for rendering markdown field 27 // documentation. The context should have a field `.Fields` of the type 28 // `[]FieldSpecCtx`. 29 func FieldsTemplate(lintableExamples bool) string { 30 exampleHint := "yml" 31 if lintableExamples { 32 exampleHint = "yaml" 33 } 34 return `{{define "field_docs" -}} 35 {{range $i, $field := .Fields -}} 36 ### ` + "`{{$field.FullName}}`" + ` 37 38 {{$field.Spec.Description}} 39 {{if $field.Spec.Interpolated -}} 40 This field supports [interpolation functions](/docs/configuration/interpolation#bloblang-queries). 41 {{end}} 42 43 Type: {{if eq $field.Spec.Kind "array"}}list of {{end}}{{if eq $field.Spec.Kind "map"}}map of {{end}}` + "`{{$field.Spec.Type}}`" + ` 44 {{if gt (len $field.DefaultMarshalled) 0}}Default: ` + "`{{$field.DefaultMarshalled}}`" + ` 45 {{end -}} 46 {{if gt (len $field.Spec.Version) 0}}Requires version {{$field.Spec.Version}} or newer 47 {{end -}} 48 {{if gt (len $field.Spec.AnnotatedOptions) 0}} 49 | Option | Summary | 50 |---|---| 51 {{range $j, $option := $field.Spec.AnnotatedOptions -}}` + "| `" + `{{index $option 0}}` + "` |" + ` {{index $option 1}} | 52 {{end}} 53 {{else if gt (len $field.Spec.Options) 0}}Options: {{range $j, $option := $field.Spec.Options -}} 54 {{if ne $j 0}}, {{end}}` + "`" + `{{$option}}` + "`" + `{{end}}. 55 {{end}} 56 {{if gt (len $field.Spec.Examples) 0 -}} 57 ` + "```" + exampleHint + ` 58 # Examples 59 60 {{range $j, $example := $field.ExamplesMarshalled -}} 61 {{if ne $j 0}} 62 {{end}}{{$example}}{{end -}} 63 ` + "```" + ` 64 65 {{end -}} 66 {{end -}} 67 {{end -}}` 68 } 69 70 // FlattenChildrenForDocs converts the children of a field into a flat list, 71 // where the names contain hints as to their position in a structured hierarchy. 72 // This makes it easier to list the fields in documentation. 73 func (f FieldSpec) FlattenChildrenForDocs() []FieldSpecCtx { 74 flattenedFields := []FieldSpecCtx{} 75 var walkFields func(path string, f FieldSpecs) 76 walkFields = func(path string, f FieldSpecs) { 77 for _, v := range f { 78 if v.IsDeprecated { 79 continue 80 } 81 newV := FieldSpecCtx{ 82 Spec: v, 83 } 84 newV.FullName = newV.Spec.Name 85 if len(path) > 0 { 86 newV.FullName = path + newV.Spec.Name 87 } 88 if len(v.Examples) > 0 { 89 newV.ExamplesMarshalled = make([]string, len(v.Examples)) 90 for i, e := range v.Examples { 91 exampleBytes, err := config.MarshalYAML(map[string]interface{}{ 92 v.Name: e, 93 }) 94 if err == nil { 95 newV.ExamplesMarshalled[i] = string(exampleBytes) 96 } 97 } 98 } 99 if v.Default != nil { 100 newV.DefaultMarshalled = gabs.Wrap(*v.Default).String() 101 } 102 newV.Spec.Description = strings.TrimSpace(v.Description) 103 if newV.Spec.Description == "" { 104 newV.Spec.Description = "Sorry! This field is missing documentation." 105 } 106 107 flattenedFields = append(flattenedFields, newV) 108 if len(v.Children) > 0 { 109 newPath := path + v.Name 110 switch newV.Spec.Kind { 111 case KindArray: 112 newPath += "[]" 113 case Kind2DArray: 114 newPath += "[][]" 115 case KindMap: 116 newPath += ".<name>" 117 } 118 walkFields(newPath+".", v.Children) 119 } 120 } 121 } 122 rootPath := "" 123 switch f.Kind { 124 case KindArray: 125 rootPath = "[]." 126 case KindMap: 127 rootPath = "<name>." 128 } 129 walkFields(rootPath, f.Children) 130 return flattenedFields 131 }