Set content along with excerpt when rendering posts (#41)

* save content along with excerpt when preparing posts

* add a test
This commit is contained in:
Facundo Olano 2024-07-03 15:08:53 -03:00 committed by GitHub
parent de5ea63d0d
commit d1459f3a37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 64 additions and 16 deletions

View file

@ -164,10 +164,7 @@ func (site *site) loadTemplates() error {
// the rest are pages.
if templ.IsPost() {
// 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)
templ.Metadata["content"], templ.Metadata["excerpt"] = getPreviewContent(templ)
site.posts = append(site.posts, templ.Metadata)
// also add to tags index
@ -414,24 +411,26 @@ func writeToFile(targetPath string, source io.Reader) error {
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 *markup.Template) string {
if excerpt, ok := templ.Metadata["excerpt"]; ok {
return excerpt.(string)
}
// Assuming the given template is a post, try to generating a preview version of its context
// and an excerpt of it. If the metadata contains an `excerpt` key use that, use the first <p>
// from the context preview.
func getPreviewContent(templ *markup.Template) (string, string) {
// if we don't expect this to render to html don't bother parsing it
if templ.TargetExt() != ".html" {
return ""
return "", ""
}
content, err := templ.Render()
if err != nil {
return ""
return "", ""
}
return markup.ExtractFirstParagraph(bytes.NewReader(content))
if excerpt, ok := templ.Metadata["excerpt"]; ok {
return string(content), excerpt.(string)
}
excerpt := markup.ExtractFirstParagraph(bytes.NewReader(content))
return string(content), excerpt
}
// if live reload is enabled, inject the reload snippet to html files

View file

@ -385,7 +385,7 @@ date: 2024-01-01
tags: [web, software]
---
<p>the intro paragraph</p>
<p> and another paragraph>`
<p> and another paragraph</p>`
file := newFile(config.SrcDir, "hello.html", content)
defer os.Remove(file.Name())
@ -430,6 +430,55 @@ hello world! - the intro paragraph
an oldie! -`)
}
func TestRenderPreviewContent(t *testing.T) {
config := newProject()
defer os.RemoveAll(config.RootDir)
content := `---
title: hello world!
date: 2024-01-01
tags: [web, software]
---
<p>the intro paragraph</p>
<p> and another paragraph</p>`
file := newFile(config.SrcDir, "hello.html", content)
defer os.Remove(file.Name())
content = `---
title: goodbye!
date: 2024-02-01
tags: [web]
excerpt: an overridden excerpt
---
<p>goodbye world!</p>
<p> and another paragraph</p>`
file = newFile(config.SrcDir, "goodbye.html", content)
defer os.Remove(file.Name())
// add a page (no date)
content = `---
---
{% for post in site.posts %}
<h1>{{post.title}}</h1>
{{post.content}}
{% endfor %}
`
file = newFile(config.SrcDir, "about.html", content)
defer os.Remove(file.Name())
site, _ := load(*config)
output, err := site.render(site.templates[file.Name()])
assertEqual(t, err, nil)
assertEqual(t, strings.TrimSpace(string(output)), `<h1>goodbye!</h1>
<p>goodbye world!</p>
<p> and another paragraph</p>
<h1>hello world!</h1>
<p>the intro paragraph</p>
<p> and another paragraph</p>`)
}
func TestRenderDataFile(t *testing.T) {
config := newProject()
defer os.RemoveAll(config.RootDir)