dashboard / erock/pico / feat(prose): lists are back bby #102 rss

open · opened on 2026-01-04T04:57:34Z by erock
Help
checkout latest patchset:
ssh pr.pico.sh print pr-102 | git am -3
checkout any patchset in a patch request:
ssh pr.pico.sh print ps-X | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 102
add review to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add --review 102
accept PR:
ssh pr.pico.sh pr accept 102
close PR:
ssh pr.pico.sh pr close 102
Timeline Patchsets

Range-diff rd-187

title
feat(prose): lists are back bby
description
Patch changed
old #1
ff673f6
new #1
c86f5a4
Back to top
1: ff673f6 ! 1: c86f5a4 feat(prose): lists are back bby

old

old:pkg/apps/prose/api.go new:pkg/apps/prose/api.go
 	Diff         template.HTML
 	UpdatedAtISO string
 	UpdatedAt    string
+	List         *shared.ListParsedText
 }
 
 type HeaderTxt struct {
 	post, err := dbpool.FindPostWithSlug(slug, user.ID, cfg.Space)
 	if err == nil {
 		logger.Info("post found", "id", post.ID, "filename", post.FileSize)
-		parsedText, err := shared.ParseText(post.Text)
-		if err != nil {
-			logger.Error("find post with slug", "err", err.Error())
-		}
+		ext := filepath.Ext(post.Filename)
+		contents := template.HTML("")
+		tags := []string{}
+		unlisted := false
+		var list *shared.ListParsedText
+
+		switch ext {
+		case ".lxt":
+			list = shared.ListParseText(post.Text)
+
+			// if parsedText.Image != "" {
+			// 	ogImage = parsedText.Image
+			// }
+			//
+			// if parsedText.ImageCard != "" {
+			// 	ogImageCard = parsedText.ImageCard
+			// }
+			tags = list.Tags
+
+			if post.Hidden || post.PublishAt.After(time.Now()) {
+				unlisted = true
+			}
+		case ".md":
+			parsedText, err := shared.ParseText(post.Text)
+			if err != nil {
+				logger.Error("could not parse md text", "err", err.Error())
+			}
 
-		if parsedText.Image != "" {
-			ogImage = parsedText.Image
-		}
+			if parsedText.Image != "" {
+				ogImage = parsedText.Image
+			}
 
-		if parsedText.ImageCard != "" {
-			ogImageCard = parsedText.ImageCard
-		}
+			if parsedText.ImageCard != "" {
+				ogImageCard = parsedText.ImageCard
+			}
+			tags = parsedText.Tags
 
-		unlisted := false
-		if post.Hidden || post.PublishAt.After(time.Now()) {
-			unlisted = true
+			if post.Hidden || post.PublishAt.After(time.Now()) {
+				unlisted = true
+			}
+			contents = template.HTML(parsedText.Html)
 		}
 
 		data = PostPageData{
 			UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339),
 			Username:     username,
 			BlogName:     blogName,
-			Contents:     template.HTML(parsedText.Html),
+			Contents:     contents,
 			HasCSS:       hasCSS,
 			CssURL:       template.URL(cfg.CssURL(username)),
-			Tags:         parsedText.Tags,
+			Tags:         tags,
 			Image:        template.URL(ogImage),
 			ImageCard:    ogImageCard,
 			Favicon:      template.URL(favicon),
 			Unlisted:     unlisted,
 			Diff:         template.HTML(diff),
 			WithStyles:   withStyles,
+			List:         list,
 		}
 	} else {
 		logger.Info("post not found")
 	}
 
 	ts, err := shared.RenderTemplate(cfg, []string{
+		cfg.StaticPath("html/list.partial.tmpl"),
 		cfg.StaticPath("html/post.page.tmpl"),
 	})
 

new

old:pkg/apps/prose/api.go new:pkg/apps/prose/api.go
 	Diff         template.HTML
 	UpdatedAtISO string
 	UpdatedAt    string
+	List         *shared.ListParsedText
 }
 
 type HeaderTxt struct {
 	post, err := dbpool.FindPostWithSlug(slug, user.ID, cfg.Space)
 	if err == nil {
 		logger.Info("post found", "id", post.ID, "filename", post.FileSize)
-		parsedText, err := shared.ParseText(post.Text)
-		if err != nil {
-			logger.Error("find post with slug", "err", err.Error())
-		}
+		ext := filepath.Ext(post.Filename)
+		contents := template.HTML("")
+		tags := []string{}
+		unlisted := false
+		var list *shared.ListParsedText
+
+		switch ext {
+		case ".lxt":
+			list = shared.ListParseText(post.Text)
+			tags = list.Tags
+			if post.Hidden || post.PublishAt.After(time.Now()) {
+				unlisted = true
+			}
+		case ".md":
+			parsedText, err := shared.ParseText(post.Text)
+			if err != nil {
+				logger.Error("could not parse md text", "err", err.Error())
+			}
 
-		if parsedText.Image != "" {
-			ogImage = parsedText.Image
-		}
+			if parsedText.Image != "" {
+				ogImage = parsedText.Image
+			}
 
-		if parsedText.ImageCard != "" {
-			ogImageCard = parsedText.ImageCard
-		}
+			if parsedText.ImageCard != "" {
+				ogImageCard = parsedText.ImageCard
+			}
+			tags = parsedText.Tags
 
-		unlisted := false
-		if post.Hidden || post.PublishAt.After(time.Now()) {
-			unlisted = true
+			if post.Hidden || post.PublishAt.After(time.Now()) {
+				unlisted = true
+			}
+			contents = template.HTML(parsedText.Html)
 		}
 
 		data = PostPageData{
 			UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339),
 			Username:     username,
 			BlogName:     blogName,
-			Contents:     template.HTML(parsedText.Html),
+			Contents:     contents,
 			HasCSS:       hasCSS,
 			CssURL:       template.URL(cfg.CssURL(username)),
-			Tags:         parsedText.Tags,
+			Tags:         tags,
 			Image:        template.URL(ogImage),
 			ImageCard:    ogImageCard,
 			Favicon:      template.URL(favicon),
 			Unlisted:     unlisted,
 			Diff:         template.HTML(diff),
 			WithStyles:   withStyles,
+			List:         list,
 		}
 	} else {
 		logger.Info("post not found")
 	}
 
 	ts, err := shared.RenderTemplate(cfg, []string{
+		cfg.StaticPath("html/list.partial.tmpl"),
 		cfg.StaticPath("html/post.page.tmpl"),
 	})
 
 		return
 	}
 
-	ts, err := template.ParseFiles(cfg.StaticPath("html/rss.page.tmpl"))
+	ts, err := template.New("rss.page.tmpl").Funcs(shared.FuncMap).ParseFiles(
+		cfg.StaticPath("html/list.partial.tmpl"),
+		cfg.StaticPath("html/rss.page.tmpl"),
+	)
 	if err != nil {
 		logger.Error("template parse file", "err", err.Error())
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		if slices.Contains(cfg.HiddenPosts, post.Filename) {
 			continue
 		}
-		parsed, err := shared.ParseText(post.Text)
-		if err != nil {
-			logger.Error("parse post text", "err", err.Error())
-		}
 
-		footer, err := dbpool.FindPostWithFilename("_footer.md", user.ID, cfg.Space)
-		var footerHTML string
-		if err == nil {
-			footerParsed, err := shared.ParseText(footer.Text)
+		content := ""
+		ext := filepath.Ext(post.Filename)
+		fmt.Println("HERE", post.Filename, ext)
+		switch ext {
+		case ".md":
+			parsed, err := shared.ParseText(post.Text)
 			if err != nil {
-				logger.Error("parse footer text", "err", err.Error())
+				logger.Error("parse post text", "err", err.Error())
 			}
-			footerHTML = footerParsed.Html
-		}
 
-		var tpl bytes.Buffer
-		data := &PostPageData{
-			Contents: template.HTML(parsed.Html + footerHTML),
-		}
-		if err := ts.Execute(&tpl, data); err != nil {
-			continue
+			footer, err := dbpool.FindPostWithFilename("_footer.md", user.ID, cfg.Space)
+			var footerHTML string
+			if err == nil {
+				footerParsed, err := shared.ParseText(footer.Text)
+				if err != nil {
+					logger.Error("parse footer text", "err", err.Error())
+				}
+				footerHTML = footerParsed.Html
+			}
+
+			var tpl bytes.Buffer
+			data := &PostPageData{
+				Contents: template.HTML(parsed.Html + footerHTML),
+			}
+			if err := ts.Execute(&tpl, data); err != nil {
+				logger.Error("md template", "err", err)
+				continue
+			}
+			content = tpl.String()
+		case ".lxt":
+			parsed := shared.ListParseText(post.Text)
+			var tpl bytes.Buffer
+			data := &PostPageData{
+				List: parsed,
+			}
+			if err := ts.Execute(&tpl, data); err != nil {
+				logger.Error("lxt template", "err", err)
+				continue
+			}
+			content = tpl.String()
+
 		}
 
 		realUrl := cfg.FullPostURL(curl, post.Username, post.Slug)
 			Id:          feedId,
 			Title:       utils.FilenameToTitle(post.Filename, post.Title),
 			Link:        &feeds.Link{Href: realUrl},
-			Content:     tpl.String(),
+			Content:     content,
 			Updated:     *post.PublishAt,
 			Created:     *post.PublishAt,
 			Description: post.Description,
 		return
 	}
 
-	ts, err := template.ParseFiles(cfg.StaticPath("html/rss.page.tmpl"))
+	ts, err := template.New("rss.page.tmpl").Funcs(shared.FuncMap).ParseFiles(
+		cfg.StaticPath("html/list.partial.tmpl"),
+		cfg.StaticPath("html/rss.page.tmpl"),
+	)
 	if err != nil {
 		logger.Error("template parse file", "err", err.Error())
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 
 	var feedItems []*feeds.Item
 	for _, post := range pager.Data {
-		parsed, err := shared.ParseText(post.Text)
-		if err != nil {
-			logger.Error(err.Error())
-		}
+		content := ""
+		ext := filepath.Ext(post.Filename)
+		switch ext {
+		case ".md":
+			parsed, err := shared.ParseText(post.Text)
+			if err != nil {
+				logger.Error(err.Error())
+			}
+
+			var tpl bytes.Buffer
+			data := &PostPageData{
+				Contents: template.HTML(parsed.Html),
+			}
+			if err := ts.Execute(&tpl, data); err != nil {
+				continue
+			}
+			content = tpl.String()
+		case ".lxt":
+			parsed := shared.ListParseText(post.Text)
+			var tpl bytes.Buffer
+			data := &PostPageData{
+				List: parsed,
+			}
+			if err := ts.Execute(&tpl, data); err != nil {
+				continue
+			}
+			content = tpl.String()
 
-		var tpl bytes.Buffer
-		data := &PostPageData{
-			Contents: template.HTML(parsed.Html),
-		}
-		if err := ts.Execute(&tpl, data); err != nil {
-			continue
 		}
 
 		realUrl := cfg.FullPostURL(curl, post.Username, post.Slug)
 			Id:          realUrl,
 			Title:       post.Title,
 			Link:        &feeds.Link{Href: realUrl},
-			Content:     tpl.String(),
+			Content:     content,
 			Created:     *post.PublishAt,
 			Updated:     *post.UpdatedAt,
 			Description: post.Description,

old


                    

new

old:pkg/apps/prose/html/rss.page.tmpl new:pkg/apps/prose/html/rss.page.tmpl
-{{.Contents}}
+{{if .List}}
+  {{template "list" .List}}
+{{else}}
+  {{.Contents}}
+{{end}}