2017-07-07 18:10:03 +02:00
|
|
|
package frontmatter
|
|
|
|
|
|
|
|
import (
|
2017-08-20 22:51:26 +02:00
|
|
|
"fmt"
|
2017-07-07 18:10:03 +02:00
|
|
|
"reflect"
|
|
|
|
"sort"
|
|
|
|
"strings"
|
|
|
|
|
2022-01-29 20:17:23 +01:00
|
|
|
"github.com/danog/liquid/evaluator"
|
2017-07-07 18:10:03 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// FrontMatter wraps a map to provide interface functions
|
|
|
|
type FrontMatter map[string]interface{}
|
|
|
|
|
2017-08-20 21:05:07 +02:00
|
|
|
// Bool returns m[k] if it's a bool; else defaultValue.
|
|
|
|
func (fm FrontMatter) Bool(k string, defaultValue bool) bool {
|
|
|
|
if val, found := fm[k]; found {
|
|
|
|
if v, ok := val.(bool); ok {
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return defaultValue
|
|
|
|
}
|
2017-07-07 18:10:03 +02:00
|
|
|
|
2017-08-20 22:51:26 +02:00
|
|
|
// Get returns m[k] if present; else defaultValue.
|
|
|
|
func (fm FrontMatter) Get(k string, defaultValue interface{}) interface{} {
|
|
|
|
if val, found := fm[k]; found {
|
|
|
|
return val
|
|
|
|
}
|
|
|
|
return defaultValue
|
|
|
|
}
|
|
|
|
|
|
|
|
// String returns m[k] if it's a string or can be stringified; else defaultValue.
|
2017-08-20 21:05:07 +02:00
|
|
|
func (fm FrontMatter) String(k string, defaultValue string) string {
|
|
|
|
if val, found := fm[k]; found {
|
2017-08-20 22:51:26 +02:00
|
|
|
switch v := val.(type) {
|
|
|
|
case string:
|
2017-08-20 21:05:07 +02:00
|
|
|
return v
|
2017-08-20 22:51:26 +02:00
|
|
|
case fmt.Stringer:
|
|
|
|
return v.String()
|
2017-08-20 21:05:07 +02:00
|
|
|
}
|
2017-07-07 18:10:03 +02:00
|
|
|
}
|
2017-08-20 21:05:07 +02:00
|
|
|
return defaultValue
|
2017-07-07 18:10:03 +02:00
|
|
|
}
|
|
|
|
|
2017-09-03 19:18:26 +02:00
|
|
|
// StringArray returns m[k] if it's a []string or string array
|
|
|
|
func (fm FrontMatter) StringArray(k string) []string {
|
|
|
|
if value, ok := fm[k]; ok {
|
|
|
|
switch value := value.(type) {
|
|
|
|
case []string:
|
|
|
|
return value
|
|
|
|
case []interface{}:
|
|
|
|
a := make([]string, len(value))
|
|
|
|
for i, item := range value {
|
|
|
|
a[i] = fmt.Sprintf("%s", item)
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
case string:
|
|
|
|
return []string{value}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-07-07 18:10:03 +02:00
|
|
|
// SortedStringArray returns a sorts list of strings from a
|
|
|
|
// frontmatter variable that is either a string (in which case it
|
|
|
|
// is a ws-separated list of words), or a list of strings.
|
|
|
|
//
|
|
|
|
// This is the format for page categories and tags.
|
|
|
|
func (fm FrontMatter) SortedStringArray(key string) []string {
|
2017-09-02 20:09:04 +02:00
|
|
|
var result []string
|
|
|
|
switch v := fm[key].(type) {
|
2017-07-07 18:10:03 +02:00
|
|
|
case string:
|
2017-09-02 20:09:04 +02:00
|
|
|
result = strings.Fields(v)
|
2017-07-07 18:10:03 +02:00
|
|
|
case []interface{}:
|
2017-09-02 20:09:04 +02:00
|
|
|
if c, e := evaluator.Convert(v, reflect.TypeOf(result)); e == nil {
|
|
|
|
result = c.([]string)
|
2017-07-07 18:10:03 +02:00
|
|
|
}
|
|
|
|
case []string:
|
2017-09-02 20:09:04 +02:00
|
|
|
result = v
|
2017-07-07 18:10:03 +02:00
|
|
|
}
|
2017-09-02 20:09:04 +02:00
|
|
|
sort.Strings(result)
|
|
|
|
return result
|
2017-07-07 18:10:03 +02:00
|
|
|
}
|
2017-08-20 21:05:07 +02:00
|
|
|
|
|
|
|
// Merge creates a new FrontMatter that merges its arguments,
|
|
|
|
// from first to last.
|
|
|
|
func Merge(fms ...FrontMatter) FrontMatter {
|
|
|
|
result := FrontMatter{}
|
|
|
|
for _, fm := range fms {
|
|
|
|
for k, v := range fm {
|
|
|
|
result[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merged returns a new FrontMatter.
|
|
|
|
func (fm FrontMatter) Merged(fms ...FrontMatter) FrontMatter {
|
|
|
|
return Merge(append([]FrontMatter{fm}, fms...)...)
|
|
|
|
}
|