recipe post

This commit is contained in:
Niko Abeler 2023-01-12 21:21:29 +01:00
parent a49deabf07
commit 23d7afe9d4
6 changed files with 171 additions and 1 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"h4kor/owl-blogs" "h4kor/owl-blogs"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -203,6 +204,11 @@ func userEditorPostHandler(repo *owl.Repository) func(http.ResponseWriter, *http
content := r.Form.Get("content") content := r.Form.Get("content")
draft := r.Form.Get("draft") draft := r.Form.Get("draft")
// recipe values
recipe_yield := r.Form.Get("yield")
recipe_ingredients := r.Form.Get("ingredients")
recipe_duration := r.Form.Get("duration")
// conditional values // conditional values
reply_url := r.Form.Get("reply_url") reply_url := r.Form.Get("reply_url")
bookmark_url := r.Form.Get("bookmark_url") bookmark_url := r.Form.Get("bookmark_url")
@ -216,7 +222,7 @@ func userEditorPostHandler(repo *owl.Repository) func(http.ResponseWriter, *http
w.Write([]byte(html)) w.Write([]byte(html))
return return
} }
if (post_type == "article" || post_type == "page") && title == "" { if (post_type == "article" || post_type == "page" || post_type == "recipe") && title == "" {
html, _ := owl.RenderUserError(user, owl.ErrorMessage{ html, _ := owl.RenderUserError(user, owl.ErrorMessage{
Error: "Missing Title", Error: "Missing Title",
Message: "Articles and Pages must have a title", Message: "Articles and Pages must have a title",
@ -257,6 +263,11 @@ func userEditorPostHandler(repo *owl.Repository) func(http.ResponseWriter, *http
Bookmark: owl.BookmarkData{ Bookmark: owl.BookmarkData{
Url: bookmark_url, Url: bookmark_url,
}, },
Recipe: owl.RecipeData{
Yield: recipe_yield,
Ingredients: strings.Split(recipe_ingredients, "\n"),
Duration: recipe_duration,
},
}, content) }, content)
if err != nil { if err != nil {

View File

@ -243,3 +243,40 @@ func TestEditorSendsWebmentions(t *testing.T) {
assertions.AssertEqual(t, repo.HttpClient.(*CountMockHttpClient).InvokedPostForm, 1) assertions.AssertEqual(t, repo.HttpClient.(*CountMockHttpClient).InvokedPostForm, 1)
} }
func TestEditorPostWithSessionRecipe(t *testing.T) {
repo, user := getSingleUserTestRepo()
user.ResetPassword("testpassword")
sessionId := user.CreateNewSession()
csrfToken := "test_csrf_token"
// Create Request and Response
form := url.Values{}
form.Add("type", "recipe")
form.Add("title", "testtitle")
form.Add("yield", "2")
form.Add("duration", "1 hour")
form.Add("ingredients", "water\nwheat")
form.Add("content", "testcontent")
form.Add("csrf_token", csrfToken)
req, err := http.NewRequest("POST", user.EditorUrl(), strings.NewReader(form.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Content-Length", strconv.Itoa(len(form.Encode())))
req.AddCookie(&http.Cookie{Name: "csrf_token", Value: csrfToken})
req.AddCookie(&http.Cookie{Name: "session", Value: sessionId})
assertions.AssertNoError(t, err, "Error creating request")
rr := httptest.NewRecorder()
router := main.SingleUserRouter(&repo)
router.ServeHTTP(rr, req)
posts, _ := user.AllPosts()
assertions.AssertEqual(t, len(posts), 1)
post := posts[0]
assertions.AssertLen(t, post.Meta().Recipe.Ingredients, 2)
assertions.AssertStatus(t, rr, http.StatusFound)
assertions.AssertEqual(t, rr.Header().Get("Location"), post.FullUrl())
}

View File

@ -54,6 +54,35 @@
</form> </form>
</details> </details>
<details>
<summary>Write Recipe</summary>
<form action="" method="post">
<h2>Create new Recipe</h2>
<input type="hidden" name="csrf_token" value="{{.CsrfToken}}">
<input type="hidden" name="type" value="recipe">
<label for="title">Title</label>
<input type="text" name="title" placeholder="Title" />
<label for="yield">Yield</label>
<input type="text" name="yield" placeholder="Yield" />
<label for="duration">Duration</label>
<input type="text" name="duration" placeholder="Duration" />
<label for="description">Description</label>
<input type="text" name="description" placeholder="Description" />
<label for="ingredients">Ingredients (1 per line)</label>
<textarea name="ingredients" placeholder="Ingredients" rows="8"></textarea>
<label for="content">Instructions</label>
<textarea name="content" placeholder="Ingredients" rows="24"></textarea>
<br><br>
<input type="submit" value="Create Reply" />
</form>
</details>
<details> <details>
<summary>Bookmark</summary> <summary>Bookmark</summary>
<form action="" method="post"> <form action="" method="post">

59
embed/recipe/detail.html Normal file
View File

@ -0,0 +1,59 @@
<div class="h-entry h-Recipe">
<hgroup>
<h1 class="p-name">{{.Title}}</h1>
<small>
<a class="u-url" href="{{.Post.FullUrl}}">#</a>
Published:
<time class="dt-published" datetime="{{.Post.Meta.Date}}">
{{.Post.Meta.FormattedDate}}
</time>
{{ if .Post.User.Config.AuthorName }}
by
<a class="p-author h-card" href="{{.Post.User.FullUrl}}">
{{ if .Post.User.AvatarUrl }}
<img class="u-photo u-logo" style="height: 1em;" src="{{ .Post.User.AvatarUrl }}"
alt="{{ .Post.User.Config.Title }}" />
{{ end }}
{{.Post.User.Config.AuthorName}}
</a>
{{ end }}
</small>
</hgroup>
<hr>
<br>
<div class="e-content">
<small>
{{ if .Post.Meta.Recipe.Yield }}
Servings: <span class="p-yield">{{ .Post.Meta.Recipe.Yield }}</span>
{{ if .Post.Meta.Recipe.Duration }}, {{end}}
{{ end }}
{{ if .Post.Meta.Recipe.Duration }}
Prep Time: <time class="dt-duration" value="{{ .Post.Meta.Recipe.Duration }}">
{{ .Post.Meta.Recipe.Duration }}
</time>
{{ end }}
</small>
<h2>Ingredients</h2>
<ul>
{{ range $ingredient := .Post.Meta.Recipe.Ingredients }}
<li class="p-ingredient">
{{ $ingredient }}
</li>
{{ end }}
</ul>
<h2>Instructions</h2>
<div class="e-instructions">
{{.Content}}
</div>
</div>
</div>

View File

@ -72,6 +72,12 @@ type BookmarkData struct {
Text string `yaml:"text"` Text string `yaml:"text"`
} }
type RecipeData struct {
Yield string `yaml:"yield"`
Duration string `yaml:"duration"`
Ingredients []string `yaml:"ingredients"`
}
type PostMeta struct { type PostMeta struct {
Type string `yaml:"type"` Type string `yaml:"type"`
Title string `yaml:"title"` Title string `yaml:"title"`
@ -81,6 +87,7 @@ type PostMeta struct {
Draft bool `yaml:"draft"` Draft bool `yaml:"draft"`
Reply ReplyData `yaml:"reply"` Reply ReplyData `yaml:"reply"`
Bookmark BookmarkData `yaml:"bookmark"` Bookmark BookmarkData `yaml:"bookmark"`
Recipe RecipeData `yaml:"recipe"`
} }
func (pm PostMeta) FormattedDate() string { func (pm PostMeta) FormattedDate() string {
@ -96,6 +103,7 @@ func (pm *PostMeta) UnmarshalYAML(unmarshal func(interface{}) error) error {
Draft bool `yaml:"draft"` Draft bool `yaml:"draft"`
Reply ReplyData `yaml:"reply"` Reply ReplyData `yaml:"reply"`
Bookmark BookmarkData `yaml:"bookmark"` Bookmark BookmarkData `yaml:"bookmark"`
Recipe RecipeData `yaml:"recipe"`
} }
type S struct { type S struct {
Date string `yaml:"date"` Date string `yaml:"date"`
@ -120,6 +128,7 @@ func (pm *PostMeta) UnmarshalYAML(unmarshal func(interface{}) error) error {
pm.Draft = t.Draft pm.Draft = t.Draft
pm.Reply = t.Reply pm.Reply = t.Reply
pm.Bookmark = t.Bookmark pm.Bookmark = t.Bookmark
pm.Recipe = t.Recipe
possibleFormats := []string{ possibleFormats := []string{
"2006-01-02", "2006-01-02",

View File

@ -478,3 +478,28 @@ func TestRenderFooterMenuPost(t *testing.T) {
assertions.AssertContains(t, result, "Test Entry") assertions.AssertContains(t, result, "Test Entry")
assertions.AssertContains(t, result, post.UrlPath()) assertions.AssertContains(t, result, post.UrlPath())
} }
func TestRecipePost(t *testing.T) {
repo := getTestRepo(owl.RepoConfig{})
user, _ := repo.CreateUser("testuser")
post, err := user.CreateNewPost(owl.PostMeta{
Type: "recipe",
Title: "test recipe",
Recipe: owl.RecipeData{
Yield: "1 loaf",
Ingredients: []string{
"1 cup flour",
"1 cup water",
},
Duration: "1 hour",
},
}, "")
assertions.AssertNoError(t, err, "Error creating post")
result, err := owl.RenderPost(post)
assertions.AssertNoError(t, err, "Error rendering post")
assertions.AssertContains(t, result, "1 loaf")
assertions.AssertContains(t, result, "1 cup flour")
assertions.AssertContains(t, result, "1 cup water")
assertions.AssertContains(t, result, "1 hour")
}