mirror of
https://github.com/facundoolano/jorge.git
synced 2025-01-15 15:41:12 +01:00
naive implementation of post excerpts
This commit is contained in:
parent
06016cb2ac
commit
6cc4077816
2 changed files with 63 additions and 0 deletions
59
site/site.go
59
site/site.go
|
@ -12,6 +12,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/facundoolano/blorg/templates"
|
"github.com/facundoolano/blorg/templates"
|
||||||
|
"golang.org/x/net/html"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -139,6 +140,11 @@ func (site *Site) loadTemplates(srcDir string) error {
|
||||||
// posts are templates that can be chronologically sorted --that have a date.
|
// posts are templates that can be chronologically sorted --that have a date.
|
||||||
// the rest are pages.
|
// the rest are pages.
|
||||||
if _, ok := templ.Metadata["date"]; ok {
|
if _, ok := templ.Metadata["date"]; ok {
|
||||||
|
|
||||||
|
// NOTE: getting the excerpt if not set at the front matter requires rendering the template
|
||||||
|
// which could be too onerous for this stage. Consider postponing setting this and/or caching the
|
||||||
|
// template render result
|
||||||
|
templ.Metadata["excerpt"] = getExcerpt(templ)
|
||||||
site.posts = append(site.posts, templ.Metadata)
|
site.posts = append(site.posts, templ.Metadata)
|
||||||
|
|
||||||
// also add to tags index
|
// also add to tags index
|
||||||
|
@ -282,3 +288,56 @@ func writeToFile(targetPath string, source io.Reader) error {
|
||||||
|
|
||||||
return targetFile.Sync()
|
return targetFile.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assuming the given template is a post, try to generating an excerpt of it.
|
||||||
|
// If it contains an `excerpt` key in its metadata use that, otherwise try
|
||||||
|
// to render it as HTML and extract the text of its first <p>
|
||||||
|
func getExcerpt(templ *templates.Template) string {
|
||||||
|
if excerpt, ok := templ.Metadata["excerpt"]; ok {
|
||||||
|
return excerpt.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't expect this to render to html don't bother parsing it
|
||||||
|
if templ.Ext() != ".html" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := map[string]interface{}{
|
||||||
|
"page": templ.Metadata,
|
||||||
|
}
|
||||||
|
content, err := templ.Render(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
html, err := html.Parse(bytes.NewReader(content))
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ptag := findFirstParagraph(html)
|
||||||
|
return getTextContent(ptag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func findFirstParagraph(node *html.Node) *html.Node {
|
||||||
|
if node.Type == html.ElementNode && node.Data == "p" {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
for c := node.FirstChild; c != nil; c = c.NextSibling {
|
||||||
|
if p := findFirstParagraph(c); p != nil {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTextContent(node *html.Node) string {
|
||||||
|
var textContent string
|
||||||
|
if node.Type == html.TextNode {
|
||||||
|
textContent = node.Data
|
||||||
|
}
|
||||||
|
for c := node.FirstChild; c != nil; c = c.NextSibling {
|
||||||
|
textContent += getTextContent(c)
|
||||||
|
}
|
||||||
|
return textContent
|
||||||
|
}
|
||||||
|
|
|
@ -96,13 +96,16 @@ func (templ Template) Ext() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (templ Template) Render(context map[string]interface{}) ([]byte, error) {
|
func (templ Template) Render(context map[string]interface{}) ([]byte, error) {
|
||||||
|
// liquid rendering
|
||||||
content, err := templ.liquidTemplate.Render(context)
|
content, err := templ.liquidTemplate.Render(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ext := filepath.Ext(templ.SrcPath)
|
ext := filepath.Ext(templ.SrcPath)
|
||||||
|
|
||||||
if ext == ".org" {
|
if ext == ".org" {
|
||||||
|
// org-mode rendering
|
||||||
doc := org.New().Parse(bytes.NewReader(content), templ.SrcPath)
|
doc := org.New().Parse(bytes.NewReader(content), templ.SrcPath)
|
||||||
contentStr, err := doc.Write(org.NewHTMLWriter())
|
contentStr, err := doc.Write(org.NewHTMLWriter())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -110,6 +113,7 @@ func (templ Template) Render(context map[string]interface{}) ([]byte, error) {
|
||||||
}
|
}
|
||||||
content = []byte(contentStr)
|
content = []byte(contentStr)
|
||||||
} else if ext == ".md" {
|
} else if ext == ".md" {
|
||||||
|
// markdown rendering
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := goldmark.Convert(content, &buf); err != nil {
|
if err := goldmark.Convert(content, &buf); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in a new issue