storing metadata in markdown file
This commit is contained in:
parent
4a0b7d8db6
commit
d93f96f6da
6
go.mod
6
go.mod
|
@ -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
5
go.sum
|
@ -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=
|
||||||
|
|
|
@ -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
32
post.go
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
19
renderer.go
19
renderer.go
|
@ -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()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
40
user.go
|
@ -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
|
||||||
|
}
|
||||||
|
|
12
user_test.go
12
user_test.go
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue