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
|
||||
|
||||
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/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
|
||||
}
|
28
post.go
28
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
|
||||
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
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
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 := "<h1>" + post.Title() + "</h1>\n"
|
||||
postHtml += buf.String()
|
||||
return strings.Replace(template, "{{content}}", postHtml, -1), nil
|
||||
}
|
||||
|
|
|
@ -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, "<h1>testpost</h1>") {
|
||||
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
|
||||
os.Mkdir(path.Join(user_dir, "public"), 0755)
|
||||
|
||||
base_template := "<html><body><{{content}}/body></html>"
|
||||
|
||||
// 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("<html><body><{{content}}/body></html>"), 0644)
|
||||
os.WriteFile(path.Join(user_dir, "meta", "base.html"), []byte(base_template), 0644)
|
||||
|
||||
return new_user, nil
|
||||
}
|
||||
|
|
40
user.go
40
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
|
||||
}
|
||||
|
|
12
user_test.go
12
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())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue