Wordpress summaries

Allow full control of summaries which can be rendered as html rather
than text.  Using a `<!--more-->` html comment in your markdown / rst
you can indiciate where the summary should end and have the summary
converted to html.

Signed-off-by: Noah Campbell <noahcampbell@gmail.com>

Conflicts:
	hugolib/page_test.go
This commit is contained in:
Ross Lawley 2013-08-21 10:37:14 +01:00 committed by Noah Campbell
parent 7b1f0960e3
commit 9930011ea2
3 changed files with 77 additions and 22 deletions

View file

@ -20,6 +20,7 @@ import (
"github.com/kr/pretty" "github.com/kr/pretty"
"html/template" "html/template"
"os" "os"
"os/exec"
"reflect" "reflect"
"regexp" "regexp"
"strconv" "strconv"
@ -28,6 +29,8 @@ import (
) )
var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]") var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]")
var summaryLength = 70
var summaryDivider = []byte("<!--more-->")
// TODO: Make these wrappers private // TODO: Make these wrappers private
// Wrapper around Fprintf taking verbose flag in account. // Wrapper around Fprintf taking verbose flag in account.
@ -329,3 +332,32 @@ func TruncateWordsToWholeSentence(s string, max int) string {
func MakePermalink(domain string, path string) string { func MakePermalink(domain string, path string) string {
return strings.TrimRight(domain, "/") + "/" + strings.TrimLeft(path, "/") return strings.TrimRight(domain, "/") + "/" + strings.TrimLeft(path, "/")
} }
func getSummaryString(content []byte) ([]byte, bool) {
if (bytes.Contains(content, summaryDivider)) {
return bytes.Split(content, summaryDivider)[0], false
} else {
plainContent := StripHTML(StripShortcodes(string(content)))
return []byte(TruncateWordsToWholeSentence(plainContent, summaryLength)), true
}
}
func getRstContent(content []byte) string {
cleanContent := bytes.Replace(content, summaryDivider, []byte(""), 1)
cmd := exec.Command("rst2html.py", "--leave-comments")
cmd.Stdin = bytes.NewReader(cleanContent)
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
fmt.Println(err)
}
rstLines := strings.Split(out.String(), "\n")
for i, line := range rstLines {
if strings.HasPrefix(line, "<body>") {
rstLines = (rstLines[i+1 : len(rstLines)-3])
}
}
return strings.Join(rstLines, "\n")
}

View file

@ -26,7 +26,6 @@ import (
"io/ioutil" "io/ioutil"
"launchpad.net/goyaml" "launchpad.net/goyaml"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"sort" "sort"
"strings" "strings"
@ -55,8 +54,6 @@ type Page struct {
Node Node
} }
const summaryLength = 70
type File struct { type File struct {
FileName, OutFile, Extension string FileName, OutFile, Extension string
} }
@ -476,27 +473,25 @@ func (page *Page) parse(reader io.Reader) error {
func (page *Page) convertMarkdown(lines io.Reader) { func (page *Page) convertMarkdown(lines io.Reader) {
b := new(bytes.Buffer) b := new(bytes.Buffer)
b.ReadFrom(lines) b.ReadFrom(lines)
content := string(blackfriday.MarkdownCommon(b.Bytes())) content := b.Bytes()
page.Content = template.HTML(content) page.Content = template.HTML(string(blackfriday.MarkdownCommon(content)))
page.Summary = template.HTML(TruncateWordsToWholeSentence(StripHTML(StripShortcodes(content)), summaryLength)) summary, plain := getSummaryString(content)
if plain {
page.Summary = template.HTML(string(summary))
} else {
page.Summary = template.HTML(string(blackfriday.MarkdownCommon(summary)))
}
} }
func (page *Page) convertRestructuredText(lines io.Reader) { func (page *Page) convertRestructuredText(lines io.Reader) {
cmd := exec.Command("rst2html.py") b := new(bytes.Buffer)
cmd.Stdin = lines b.ReadFrom(lines)
var out bytes.Buffer content := b.Bytes()
cmd.Stdout = &out page.Content = template.HTML(getRstContent(content))
if err := cmd.Run(); err != nil { summary, plain := getSummaryString(content)
fmt.Println(err) if plain {
page.Summary = template.HTML(string(summary))
} else {
page.Summary = template.HTML(getRstContent(summary))
} }
rstLines := strings.Split(out.String(), "\n")
for i, line := range rstLines {
if strings.HasPrefix(line, "<body>") {
rstLines = (rstLines[i+1 : len(rstLines)-3])
}
}
content := strings.Join(rstLines, "\n")
page.Content = template.HTML(content)
page.Summary = template.HTML(TruncateWordsToWholeSentence(StripHTML(StripShortcodes(content)), summaryLength))
} }

View file

@ -91,6 +91,15 @@ layout: buzfoo
--- ---
type and layout set` type and layout set`
var SIMPLE_PAGE_WITH_SUMMARY_DELIMITER = `---
title: Simple
---
Simple Page
<!--more-->
Some more text
`
func checkError(t *testing.T, err error, expected string) { func checkError(t *testing.T, err error, expected string) {
if err == nil { if err == nil {
t.Fatalf("err is nil") t.Fatalf("err is nil")
@ -130,6 +139,12 @@ func checkPageContent(t *testing.T, page *Page, content string) {
} }
} }
func checkPageSummary(t *testing.T, page *Page, summary string) {
if page.Summary != template.HTML(summary) {
t.Fatalf("Page summary is: `%s`. Expected `%s`", page.Summary, summary)
}
}
func checkPageType(t *testing.T, page *Page, pageType string) { func checkPageType(t *testing.T, page *Page, pageType string) {
if page.Type() != pageType { if page.Type() != pageType {
t.Fatalf("Page type is: %s. Expected: %s", page.Type(), pageType) t.Fatalf("Page type is: %s. Expected: %s", page.Type(), pageType)
@ -149,6 +164,19 @@ func TestCreateNewPage(t *testing.T) {
} }
checkPageTitle(t, p, "Simple") checkPageTitle(t, p, "Simple")
checkPageContent(t, p, "<p>Simple Page</p>\n") checkPageContent(t, p, "<p>Simple Page</p>\n")
checkPageSummary(t, p, "Simple Page")
checkPageType(t, p, "page")
checkPageLayout(t, p, "page/single.html")
}
func TestPageWithDelimiter(t *testing.T) {
p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SUMMARY_DELIMITER), "simple")
if err != nil {
t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
}
checkPageTitle(t, p, "Simple")
checkPageContent(t, p, "<p>Simple Page</p>\n\n<!--more-->\n\n<p>Some more text</p>\n")
checkPageSummary(t, p, "<p>Simple Page</p>\n")
checkPageType(t, p, "page") checkPageType(t, p, "page")
checkPageLayout(t, p, "page/single.html") checkPageLayout(t, p, "page/single.html")
} }