67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package fs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/fs"
|
|
|
|
"github.com/adrg/frontmatter"
|
|
"golang.org/x/text/language"
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"source.toby3d.me/toby3d/home/internal/domain"
|
|
"source.toby3d.me/toby3d/home/internal/page"
|
|
)
|
|
|
|
type (
|
|
Page struct {
|
|
Title string `yaml:"title"`
|
|
Params map[string]any `yaml:",inline"`
|
|
Content []byte `yaml:"-"`
|
|
}
|
|
|
|
fileSystemPageRepository struct {
|
|
dir fs.FS
|
|
rootPath string
|
|
}
|
|
)
|
|
|
|
var FrontMatterFormats = []*frontmatter.Format{
|
|
frontmatter.NewFormat(`---`, `---`, yaml.Unmarshal),
|
|
}
|
|
|
|
func NewFileSystemPageRepository(rootDir fs.FS) page.Repository {
|
|
return &fileSystemPageRepository{
|
|
dir: rootDir,
|
|
}
|
|
}
|
|
|
|
func (repo *fileSystemPageRepository) Get(ctx context.Context, lang language.Tag, p string) (*domain.Page, error) {
|
|
ext := ".md"
|
|
if lang != language.Und {
|
|
base, _ := lang.Base()
|
|
ext = "." + base.String() + ext
|
|
}
|
|
|
|
index := p + ext
|
|
|
|
f, err := repo.dir.Open(index)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot open '%s' page file: %w", index, err)
|
|
}
|
|
defer f.Close()
|
|
|
|
data := new(Page)
|
|
if data.Content, err = frontmatter.Parse(f, data, FrontMatterFormats...); err != nil {
|
|
return nil, fmt.Errorf("cannot parse page content as FrontMatter: %w", err)
|
|
}
|
|
|
|
return &domain.Page{
|
|
Language: lang,
|
|
Title: data.Title,
|
|
Content: data.Content,
|
|
Params: data.Params,
|
|
Files: make([]*domain.File, 0),
|
|
}, nil
|
|
}
|