From d93f96f6dad38b3617dc694f7206998c08e01446 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Thu, 21 Jul 2022 19:44:07 +0200 Subject: [PATCH] storing metadata in markdown file --- go.mod | 6 +++++- go.sum | 5 +++++ kiss_test.go | 9 +++++++++ post.go | 32 ++++++++++++++++++++++++++++++-- post_test.go | 12 ++++++++++++ renderer.go | 19 +++++++------------ renderer_test.go | 17 ++++++++++------- repository.go | 4 +++- user.go | 40 +++++++++++++++++++++++++++++++--------- user_test.go | 12 ++++++++++++ 10 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 kiss_test.go create mode 100644 post_test.go diff --git a/go.mod b/go.mod index 7981876..637433d 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,8 @@ module h4kor/kiss-social 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 +) diff --git a/go.sum b/go.sum index 29914fb..89e54e4 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,7 @@ 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-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= diff --git a/kiss_test.go b/kiss_test.go new file mode 100644 index 0000000..94c26ac --- /dev/null +++ b/kiss_test.go @@ -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 +} diff --git a/post.go b/post.go index ae0beb8..85e6d46 100644 --- a/post.go +++ b/post.go @@ -1,19 +1,29 @@ package kiss import ( + "bytes" "io/ioutil" "path" + + "github.com/yuin/goldmark" + meta "github.com/yuin/goldmark-meta" + "github.com/yuin/goldmark/parser" ) type Post struct { - user User - id string + user User + id string + title string } func (post Post) Dir() string { return path.Join(post.user.Dir(), "public", post.id) } +func (post Post) Title() string { + return post.title +} + func (post Post) ContentFile() string { return path.Join(post.Dir(), "index.md") } @@ -23,3 +33,21 @@ func (post Post) Content() []byte { data, _ := ioutil.ReadFile(post.ContentFile()) 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 + +} diff --git a/post_test.go b/post_test.go new file mode 100644 index 0000000..8c38957 --- /dev/null +++ b/post_test.go @@ -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) + } +} diff --git a/renderer.go b/renderer.go index 227f37d..4b9b17d 100644 --- a/renderer.go +++ b/renderer.go @@ -1,16 +1,11 @@ package kiss -import ( - "bytes" +import "strings" - "github.com/yuin/goldmark" -) - -func RenderPost(post Post) string { - - var buf bytes.Buffer - if err := goldmark.Convert(post.Content(), &buf); err != nil { - panic(err) - } - return buf.String() +func RenderPost(post Post) (string, error) { + template, _ := post.user.Template() + buf, _ := post.MarkdownData() + postHtml := "

" + post.Title() + "

\n" + postHtml += buf.String() + return strings.Replace(template, "{{content}}", postHtml, -1), nil } diff --git a/renderer_test.go b/renderer_test.go index 652dfbd..8535106 100644 --- a/renderer_test.go +++ b/renderer_test.go @@ -6,18 +6,21 @@ import ( "testing" ) -func getTestUser() kiss.User { - repo, _ := kiss.CreateRepository(testRepoName()) - user, _ := repo.CreateUser(randomUserName()) - return user -} - func TestCanRenderPost(t *testing.T) { user := getTestUser() post, _ := user.CreateNewPost("testpost") - result := kiss.RenderPost(post) + result, _ := kiss.RenderPost(post) if !strings.Contains(result, "

testpost

") { 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, "") { + t.Error("Base template not used. Got: " + result) + } +} diff --git a/repository.go b/repository.go index c1deaf7..148d1b9 100644 --- a/repository.go +++ b/repository.go @@ -49,9 +49,11 @@ func (repo Repository) CreateUser(name string) (User, error) { // create public folder os.Mkdir(path.Join(user_dir, "public"), 0755) + base_template := "<{{content}}/body>" + // create Meta files os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte("0.0.1"), 0644) - os.WriteFile(path.Join(user_dir, "meta", "base.html"), []byte("<{{content}}/body>"), 0644) + os.WriteFile(path.Join(user_dir, "meta", "base.html"), []byte(base_template), 0644) return new_user, nil } diff --git a/user.go b/user.go index 3bc4b10..d02a00c 100644 --- a/user.go +++ b/user.go @@ -2,6 +2,7 @@ package kiss import ( "fmt" + "io/ioutil" "os" "path" "time" @@ -20,13 +21,18 @@ func (user User) Name() string { return user.name } -func (user User) Posts() ([]Post, error) { - postNames := listDir(path.Join(user.Dir(), "public")) - posts := make([]Post, len(postNames)) - for i, name := range postNames { - posts[i] = Post{user: user, id: name} - } - return posts, nil +func (user User) Posts() ([]string, error) { + postIds := listDir(path.Join(user.Dir(), "public")) + return postIds, nil +} + +func (user User) GetPost(id string) (Post, error) { + 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) { @@ -45,11 +51,27 @@ func (user User) CreateNewPost(title string) (Post, error) { 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 os.Mkdir(post_dir, 0755) os.WriteFile(post.ContentFile(), []byte(initial_content), 0644) 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 +} diff --git a/user_test.go b/user_test.go index 7b86ddc..00fa68e 100644 --- a/user_test.go +++ b/user_test.go @@ -56,3 +56,15 @@ func TestCanListUserPosts(t *testing.T) { 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()) + } +}