add support for data files

This commit is contained in:
facundoolano 2024-02-15 16:01:35 -03:00
parent 180a5c7ac1
commit ed258fddc4
4 changed files with 91 additions and 16 deletions

View file

@ -10,6 +10,7 @@ import (
const SRC_DIR = "src"
const TARGET_DIR = "target"
const LAYOUTS_DIR = "layouts"
const DATA_DIR = "data"
func Init() error {
// get working directory
@ -35,8 +36,9 @@ func Build(root string) error {
src := filepath.Join(root, SRC_DIR)
target := filepath.Join(root, TARGET_DIR)
layouts := filepath.Join(root, LAYOUTS_DIR)
data := filepath.Join(root, DATA_DIR)
site, err := site.Load(src, layouts)
site, err := site.Load(src, layouts, data)
if err != nil {
return err
}

View file

@ -35,7 +35,7 @@ func Serve() error {
}
func rebuild() error {
site, err := site.Load(SRC_DIR, LAYOUTS_DIR)
site, err := site.Load(SRC_DIR, LAYOUTS_DIR, DATA_DIR)
if err != nil {
return err
}

View file

@ -12,6 +12,7 @@ import (
"time"
"github.com/facundoolano/blorg/templates"
"gopkg.in/yaml.v3"
)
const FILE_RW_MODE = 0777
@ -22,21 +23,27 @@ type Site struct {
posts []map[string]interface{}
pages []map[string]interface{}
tags map[string][]map[string]interface{}
data map[string]interface{}
templateEngine *templates.Engine
templates map[string]*templates.Template
}
func Load(srcDir string, layoutsDir string) (*Site, error) {
func Load(srcDir string, layoutsDir string, dataDir string) (*Site, error) {
// TODO load config from config.yml
site := Site{
layouts: make(map[string]templates.Template),
templates: make(map[string]*templates.Template),
config: make(map[string]string),
tags: make(map[string][]map[string]interface{}),
data: make(map[string]interface{}),
templateEngine: templates.NewEngine(),
}
if err := site.loadDataFiles(dataDir); err != nil {
return nil, err
}
if err := site.loadLayouts(layoutsDir); err != nil {
return nil, err
}
@ -74,6 +81,38 @@ func (site *Site) loadLayouts(layoutsDir string) error {
return nil
}
func (site *Site) loadDataFiles(dataDir string) error {
files, err := os.ReadDir(dataDir)
if os.IsNotExist(err) {
return nil
} else if err != nil {
return err
}
for _, entry := range files {
if !entry.IsDir() {
filename := entry.Name()
path := filepath.Join(dataDir, filename)
yamlContent, err := os.ReadFile(path)
if err != nil {
return err
}
var data interface{}
err = yaml.Unmarshal(yamlContent, &data)
if err != nil {
return err
}
data_name := strings.TrimSuffix(filename, filepath.Ext(filename))
site.data[data_name] = data
}
}
return nil
}
func (site *Site) loadTemplates(srcDir string) error {
_, err := os.ReadDir(srcDir)
if os.IsNotExist(err) {
@ -206,6 +245,7 @@ func (site Site) render(templ *templates.Template) ([]byte, error) {
"posts": site.posts,
"tags": site.tags,
"pages": site.pages,
"data": site.data,
},
}

View file

@ -7,7 +7,7 @@ import (
)
func TestLoadAndRenderTemplates(t *testing.T) {
root, layouts, src := newProject()
root, layouts, src, data := newProject()
defer os.RemoveAll(root)
// add two layouts
@ -68,7 +68,7 @@ title: about
content = `go away!`
file = newFile(src, "robots.txt", content)
site, err := Load(src, layouts)
site, err := Load(src, layouts, data)
assertEqual(t, err, nil)
@ -115,7 +115,7 @@ title: about
}
func TestRenderArchive(t *testing.T) {
root, layouts, src := newProject()
root, layouts, src, data := newProject()
defer os.RemoveAll(root)
content := `---
@ -152,7 +152,7 @@ date: 2023-01-01
file = newFile(src, "about.html", content)
defer os.Remove(file.Name())
site, err := Load(src, layouts)
site, err := Load(src, layouts, data)
output, err := site.render(site.templates[file.Name()])
assertEqual(t, err, nil)
assertEqual(t, string(output), `<ul>
@ -163,7 +163,7 @@ date: 2023-01-01
}
func TestRenderTags(t *testing.T) {
root, layouts, src := newProject()
root, layouts, src, data := newProject()
defer os.RemoveAll(root)
content := `---
@ -205,7 +205,7 @@ tags: [software]
file = newFile(src, "about.html", content)
defer os.Remove(file.Name())
site, err := Load(src, layouts)
site, err := Load(src, layouts, data)
output, err := site.render(site.templates[file.Name()])
assertEqual(t, err, nil)
assertEqual(t, string(output), `<h1>software</h1>
@ -222,7 +222,7 @@ hello world!
}
func TestRenderPagesInDir(t *testing.T) {
root, layouts, src := newProject()
root, layouts, src, data := newProject()
defer os.RemoveAll(root)
content := `---
@ -256,7 +256,7 @@ title: "2. an oldie!"
file = newFile(src, "index.html", content)
defer os.Remove(file.Name())
site, err := Load(src, layouts)
site, err := Load(src, layouts, data)
output, err := site.render(site.templates[file.Name()])
assertEqual(t, err, nil)
assertEqual(t, string(output), `<ul>
@ -271,24 +271,57 @@ func TestRenderArchiveWithExcerpts(t *testing.T) {
}
func TestRenderDataFile(t *testing.T) {
// TODO
root, layouts, src, data := newProject()
defer os.RemoveAll(root)
content := `
- name: feedi
url: https://github.com/facundoolano/feedi
- name: blorg
url: https://github.com/facundoolano/blorg
`
file := newFile(data, "projects.yml", content)
defer os.Remove(file.Name())
// add a page (no date)
content = `---
---
<ul>{% for project in site.data.projects %}
<li><a href="{{ project.url }}">{{project.name}}</a></li>{%endfor%}
</ul>`
file = newFile(src, "projects.html", content)
defer os.Remove(file.Name())
site, err := Load(src, layouts, data)
output, err := site.render(site.templates[file.Name()])
assertEqual(t, err, nil)
assertEqual(t, string(output), `<ul>
<li><a href="https://github.com/facundoolano/feedi">feedi</a></li>
<li><a href="https://github.com/facundoolano/blorg">blorg</a></li>
</ul>`)
}
// ------ HELPERS --------
func newProject() (string, string, string) {
func newProject() (string, string, string, string) {
projectDir, _ := os.MkdirTemp("", "root")
layoutsDir := filepath.Join(projectDir, "layouts")
srcDir := filepath.Join(projectDir, "src")
dataDir := filepath.Join(projectDir, "data")
os.Mkdir(layoutsDir, 0777)
os.Mkdir(filepath.Join(projectDir, "src"), 0777)
os.Mkdir(srcDir, 0777)
os.Mkdir(dataDir, 0777)
return projectDir, layoutsDir, srcDir
return projectDir, layoutsDir, srcDir, dataDir
}
func newFile(dir string, filename string, contents string) *os.File {
path := filepath.Join(dir, filename)
file, _ := os.Create(path)
file, err := os.Create(path)
if err != nil {
panic(err)
}
file.WriteString(contents)
return file
}