storing metadata in markdown file

This commit is contained in:
Niko Abeler 2022-07-21 19:44:07 +02:00
parent 4a0b7d8db6
commit d93f96f6da
10 changed files with 124 additions and 32 deletions

6
go.mod
View File

@ -2,4 +2,8 @@ module h4kor/kiss-social
go 1.18 go 1.18
require github.com/yuin/goldmark v1.4.13 // indirect require (
github.com/yuin/goldmark v1.4.13 // indirect
github.com/yuin/goldmark-meta v1.1.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)

5
go.sum
View File

@ -1,2 +1,7 @@
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

9
kiss_test.go Normal file
View File

@ -0,0 +1,9 @@
package kiss_test
import "h4kor/kiss-social"
func getTestUser() kiss.User {
repo, _ := kiss.CreateRepository(testRepoName())
user, _ := repo.CreateUser(randomUserName())
return user
}

32
post.go
View File

@ -1,19 +1,29 @@
package kiss package kiss
import ( import (
"bytes"
"io/ioutil" "io/ioutil"
"path" "path"
"github.com/yuin/goldmark"
meta "github.com/yuin/goldmark-meta"
"github.com/yuin/goldmark/parser"
) )
type Post struct { type Post struct {
user User user User
id string id string
title string
} }
func (post Post) Dir() string { func (post Post) Dir() string {
return path.Join(post.user.Dir(), "public", post.id) return path.Join(post.user.Dir(), "public", post.id)
} }
func (post Post) Title() string {
return post.title
}
func (post Post) ContentFile() string { func (post Post) ContentFile() string {
return path.Join(post.Dir(), "index.md") return path.Join(post.Dir(), "index.md")
} }
@ -23,3 +33,21 @@ func (post Post) Content() []byte {
data, _ := ioutil.ReadFile(post.ContentFile()) data, _ := ioutil.ReadFile(post.ContentFile())
return data return data
} }
func (post Post) MarkdownData() (bytes.Buffer, map[string]interface{}) {
data := post.Content()
markdown := goldmark.New(
goldmark.WithExtensions(
meta.Meta,
),
)
var buf bytes.Buffer
context := parser.NewContext()
if err := markdown.Convert(data, &buf, parser.WithContext(context)); err != nil {
panic(err)
}
metaData := meta.Get(context)
return buf, metaData
}

12
post_test.go Normal file
View File

@ -0,0 +1,12 @@
package kiss_test
import "testing"
func TestCanGetPostTitle(t *testing.T) {
user := getTestUser()
post, _ := user.CreateNewPost("testpost")
result := post.Title()
if result != "testpost" {
t.Error("Wrong Title. Got: " + result)
}
}

View File

@ -1,16 +1,11 @@
package kiss package kiss
import ( import "strings"
"bytes"
"github.com/yuin/goldmark" func RenderPost(post Post) (string, error) {
) template, _ := post.user.Template()
buf, _ := post.MarkdownData()
func RenderPost(post Post) string { postHtml := "<h1>" + post.Title() + "</h1>\n"
postHtml += buf.String()
var buf bytes.Buffer return strings.Replace(template, "{{content}}", postHtml, -1), nil
if err := goldmark.Convert(post.Content(), &buf); err != nil {
panic(err)
}
return buf.String()
} }

View File

@ -6,18 +6,21 @@ import (
"testing" "testing"
) )
func getTestUser() kiss.User {
repo, _ := kiss.CreateRepository(testRepoName())
user, _ := repo.CreateUser(randomUserName())
return user
}
func TestCanRenderPost(t *testing.T) { func TestCanRenderPost(t *testing.T) {
user := getTestUser() user := getTestUser()
post, _ := user.CreateNewPost("testpost") post, _ := user.CreateNewPost("testpost")
result := kiss.RenderPost(post) result, _ := kiss.RenderPost(post)
if !strings.Contains(result, "<h1>testpost</h1>") { if !strings.Contains(result, "<h1>testpost</h1>") {
t.Error("Post title not rendered as h1. Got: " + result) t.Error("Post title not rendered as h1. Got: " + result)
} }
} }
func TestRendererUsesBaseTemplate(t *testing.T) {
user := getTestUser()
post, _ := user.CreateNewPost("testpost")
result, _ := kiss.RenderPost(post)
if !strings.Contains(result, "<html>") {
t.Error("Base template not used. Got: " + result)
}
}

View File

@ -49,9 +49,11 @@ func (repo Repository) CreateUser(name string) (User, error) {
// create public folder // create public folder
os.Mkdir(path.Join(user_dir, "public"), 0755) os.Mkdir(path.Join(user_dir, "public"), 0755)
base_template := "<html><body><{{content}}/body></html>"
// create Meta files // create Meta files
os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte("0.0.1"), 0644) os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte("0.0.1"), 0644)
os.WriteFile(path.Join(user_dir, "meta", "base.html"), []byte("<html><body><{{content}}/body></html>"), 0644) os.WriteFile(path.Join(user_dir, "meta", "base.html"), []byte(base_template), 0644)
return new_user, nil return new_user, nil
} }

40
user.go
View File

@ -2,6 +2,7 @@ package kiss
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path" "path"
"time" "time"
@ -20,13 +21,18 @@ func (user User) Name() string {
return user.name return user.name
} }
func (user User) Posts() ([]Post, error) { func (user User) Posts() ([]string, error) {
postNames := listDir(path.Join(user.Dir(), "public")) postIds := listDir(path.Join(user.Dir(), "public"))
posts := make([]Post, len(postNames)) return postIds, nil
for i, name := range postNames { }
posts[i] = Post{user: user, id: name}
} func (user User) GetPost(id string) (Post, error) {
return posts, nil post := Post{user: user, id: id}
_, metaData := post.MarkdownData()
title := metaData["title"]
post.title = fmt.Sprint(title)
return post, nil
} }
func (user User) CreateNewPost(title string) (Post, error) { func (user User) CreateNewPost(title string) (Post, error) {
@ -45,11 +51,27 @@ func (user User) CreateNewPost(title string) (Post, error) {
break break
} }
} }
post := Post{user: user, id: folder_name} post := Post{user: user, id: folder_name, title: title}
initial_content := ""
initial_content += "---\n"
initial_content += "title: " + title + "\n"
initial_content += "---\n"
initial_content += "\n"
initial_content += "Write your post here.\n"
initial_content := "# " + title
// create post file // create post file
os.Mkdir(post_dir, 0755) os.Mkdir(post_dir, 0755)
os.WriteFile(post.ContentFile(), []byte(initial_content), 0644) os.WriteFile(post.ContentFile(), []byte(initial_content), 0644)
return post, nil return post, nil
} }
func (user User) Template() (string, error) {
// load base.html
path := path.Join(user.Dir(), "meta", "base.html")
base_html, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}
return string(base_html), nil
}

View File

@ -56,3 +56,15 @@ func TestCanListUserPosts(t *testing.T) {
t.Error("No posts found") t.Error("No posts found")
} }
} }
func TestCanLoadPost(t *testing.T) {
user := getTestUser()
// Create a new post
user.CreateNewPost("testpost")
posts, _ := user.Posts()
post, _ := user.GetPost(posts[0])
if post.Title() != "testpost" {
t.Error("Wrong title, Got: " + post.Title())
}
}