Install the frontmatter library
masterTo use this library in your Go project, install it using go get:
go get github.com/adrg/frontmatterrepository·master·Indexed 41 days ago
https://github.com/adrg/frontmatterA Go library to detect and decode front matter formats such as YAML, JSON, and TOML from content files. It provides functions like Parse and MustParse to extract metadata into structs and return the remaining document body, with support for custom delimiters and unmarshaling logic via the Format struct.
To use this library in your Go project, install it using go get:
go get github.com/adrg/frontmatterUse frontmatter.Parse to detect and decode front matter from an io.Reader. The function returns the remaining content (the 'rest' of the document) and an error. You must provide a pointer to a struct where the fields match the front matter keys (using appropriate struct tags like yaml:, json:, or toml:).
If the presence of front matter is mandatory for your application, use frontmatter.MustParse instead, which will panic if no front matter is found.
package main
import (
"fmt"
"strings"
"github.com/adrg/frontmatter"
)
var input = `
---
name: "frontmatter"
tags: ["go", "yaml", "json", "toml"]
---
rest of the content`
func main() {
var matter struct {
Name string ` + "`yaml:" + "`name`" + `
Tags []string ` + "`yaml:" + "`tags`" + `
}
// Parse returns the content after the front matter and an error
rest, err := frontmatter.Parse(strings.NewReader(input), &matter)
if err != nil {
// Handle error
}
fmt.Printf("%+v\n", matter)
fmt.Println(string(rest))
}If the default supported formats are not suitable, you can provide a custom list of *frontmatter.Format objects to the frontmatter.Parse function.
To create a custom format, use frontmatter.NewFormat(prefix, suffix, unmarshalFunc). The unmarshalFunc should be a function compatible with the standard unmarshaling pattern (e.g., yaml.Unmarshal).
package main
import (
"fmt"
"strings"
"github.com/adrg/frontmatter"
"gopkg.in/yaml.v2"
)
var input = `
...
name: "frontmatter"
tags: ["go", "yaml", "json", "toml"]
...
rest of the content`
func main() {
var matter struct {
Name string ` + "`yaml:" + "`name`" + `
Tags []string ` + "`yaml:" + "`tags`" + `
}
// Define custom formats with specific delimiters and an unmarshaler
formats := []*frontmatter.Format{
frontmatter.NewFormat("...", "...", yaml.Unmarshal),
}
// Pass the custom formats as variadic arguments to Parse
rest, err := frontmatter.Parse(strings.NewReader(input), &matter, formats...)
if err != nil {
// Handle error
}
fmt.Printf("%+v\n", matter)
fmt.Println(string(rest))
}The MustParse function behaves like Parse, but it treats the absence of front matter as an error. If no front matter is found in the reader, it returns ErrNotFound.
Use MustParse when your application logic requires that front matter must be present for the content to be valid.
// Example usage of MustParse
// Returns ErrNotFound if no front matter is detected
data, err := frontmatter.MustParse(reader, &myConfigStruct)
if errors.Is(err, frontmatter.ErrNotFound) {
// handle missing front matter
}Use NewFormat to quickly create a Format instance with standard settings. It initializes UnmarshalDelims and RequiresNewLine to false by default.
Signature:
func NewFormat(start, end string, unmarshal UnmarshalFunc) *Format
import (
"encoding/json"
"github.com/adrg/adrg/frontmatter"
)
// Creates a format using '---' as start/end delimiters and JSON unmarshaling
format := frontmatter.NewFormat("---", "---", json.Unmarshal)The Parse function decodes front matter from an io.Reader into the provided interface v and returns the remaining content as a byte slice.
If no front matter is detected, Parse returns the original data unchanged and leaves v untouched. You can specify custom formats by passing *Format arguments; if none are provided, the library uses default supported formats (YAML, TOML, and JSON).
Supported default formats:
--- / --- or ---yaml / ---.+++ / +++ or ---toml / ---.;;; / ;;;, ---json / ---, or a single JSON object followed by an empty line.// Example usage of Parse
// data is the remaining content after the front matter
// err is returned if decoding fails
data, err := frontmatter.Parse(reader, &myConfigStruct)When using MustParse, if the input reader does not contain any detectable front matter, the function returns the ErrNotFound error. You can check for this specific error using errors.Is.
if errors.Is(err, frontmatter.ErrNotFound) {
// The front matter was not found
}The Format struct defines how to detect and decode front matter within a document. You can use it to specify the delimiters and the unmarshaling logic required for a specific format.
Fields:
Start: The starting delimiter (e.g., --- or ---yaml).End: The ending delimiter (e.g., ---).Unmarshal: An UnmarshalFunc used to decode the data once detected.UnmarshalDelims: A boolean indicating if the delimiters themselves should be included in the data passed to the unmarshaler. Usually false.RequiresNewLine: A boolean indicating if an empty line is required immediately after the front matter block. Usually false.import "encoding/json"
// Example of a custom format definition
myFormat := &frontmatter.Format{
Start: "<!--meta-->",
End: "<!--/meta-->",
Unmarshal: json.Unmarshal,
UnmarshalDelims: false,
RequiresNewLine: false,
}The UnmarshalFunc type is a function signature used to decode raw bytes into a provided value. It must match the following signature:
type UnmarshalFunc func(data []byte, v interface{}) error
// Example of a compatible function signature
func myCustomDecoder(data []byte, v interface{}) error {
// custom decoding logic
return nil
}