0
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2024-12-23 22:27:38 -05:00

Fix more tests, and fix template parsing.

This commit is contained in:
Tobias Weingartner 2016-04-10 23:17:01 -07:00
parent 027f697fdf
commit 42b7d57421
6 changed files with 160 additions and 102 deletions

View file

@ -36,7 +36,7 @@ func markdownParse(c *Controller) ([]*markdown.Config, error) {
md := &markdown.Config{
Renderer: blackfriday.HtmlRenderer(0, "", ""),
Extensions: make(map[string]struct{}),
Templates: make(map[string]string),
Template: markdown.GetDefaultTemplate(),
}
// Get the path scope
@ -95,17 +95,32 @@ func loadParams(c *Controller, mdc *markdown.Config) error {
default:
return c.ArgErr()
case 1:
if _, ok := mdc.Templates[markdown.DefaultTemplate]; ok {
return c.Err("only one default template is allowed, use alias.")
}
fpath := filepath.ToSlash(filepath.Clean(c.Root + string(filepath.Separator) + tArgs[0]))
mdc.Templates[markdown.DefaultTemplate] = fpath
if err := markdown.SetTemplate(mdc.Template, "", fpath); err != nil {
c.Errf("default template parse error: %v", err)
}
return nil
case 2:
fpath := filepath.ToSlash(filepath.Clean(c.Root + string(filepath.Separator) + tArgs[1]))
mdc.Templates[tArgs[0]] = fpath
if err := markdown.SetTemplate(mdc.Template, tArgs[0], fpath); err != nil {
c.Errf("template parse error: %v", err)
}
return nil
}
case "templatedir":
if !c.NextArg() {
return c.ArgErr()
}
_, err := mdc.Template.ParseGlob(c.Val())
if err != nil {
c.Errf("template load error: %v", err)
}
if c.NextArg() {
return c.ArgErr()
}
return nil
default:
return c.Err("Expected valid markdown configuration property")
}

View file

@ -1,9 +1,13 @@
package setup
import (
"bytes"
"fmt"
"net/http"
"testing"
"text/template"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/markdown"
)
@ -58,8 +62,9 @@ func TestMarkdownParse(t *testing.T) {
".md": struct{}{},
".txt": struct{}{},
},
Styles: []string{"/resources/css/blog.css"},
Scripts: []string{"/resources/js/blog.js"},
Styles: []string{"/resources/css/blog.css"},
Scripts: []string{"/resources/js/blog.js"},
Template: markdown.GetDefaultTemplate(),
}}},
{`markdown /blog {
ext .md
@ -69,9 +74,13 @@ func TestMarkdownParse(t *testing.T) {
Extensions: map[string]struct{}{
".md": struct{}{},
},
Templates: map[string]string{markdown.DefaultTemplate: "testdata/tpl_with_include.html"},
Template: markdown.GetDefaultTemplate(),
}}},
}
// Setup the extra template
tmpl := tests[1].expectedMarkdownConfig[0].Template
markdown.SetTemplate(tmpl, "", "./testdata/tpl_with_include.html")
for i, test := range tests {
c := NewTestController(test.inputMarkdownConfig)
c.Root = "./testdata"
@ -101,11 +110,47 @@ func TestMarkdownParse(t *testing.T) {
t.Errorf("Test %d expected %dth Markdown Config Scripts to be %s , but got %s",
i, j, fmt.Sprint(test.expectedMarkdownConfig[j].Scripts), fmt.Sprint(actualMarkdownConfig.Scripts))
}
if fmt.Sprint(actualMarkdownConfig.Templates) != fmt.Sprint(test.expectedMarkdownConfig[j].Templates) {
t.Errorf("Test %d expected %dth Markdown Config Templates to be %s , but got %s",
i, j, fmt.Sprint(test.expectedMarkdownConfig[j].Templates), fmt.Sprint(actualMarkdownConfig.Templates))
if ok, tx, ty := equalTemplates(actualMarkdownConfig.Template, test.expectedMarkdownConfig[j].Template); !ok {
t.Errorf("Test %d the %dth Markdown Config Templates did not match, expected %s to be %s", i, j, tx, ty)
}
}
}
}
func equalTemplates(i, j *template.Template) (bool, string, string) {
// Just in case :)
if i == j {
return true, "", ""
}
// We can't do much here, templates can't really be compared. However,
// we can execute the templates and compare their outputs to be reasonably
// sure that they're the same.
// This is exceedingly ugly.
ctx := middleware.Context{
Root: http.Dir("./testdata"),
}
md := markdown.Data{
Context: ctx,
Doc: make(map[string]string),
DocFlags: make(map[string]bool),
Styles: []string{"style1"},
Scripts: []string{"js1"},
}
md.Doc["title"] = "some title"
md.Doc["body"] = "some body"
bufi := new(bytes.Buffer)
bufj := new(bytes.Buffer)
if err := i.Execute(bufi, md); err != nil {
return false, fmt.Sprintf("%v", err), ""
}
if err := j.Execute(bufj, md); err != nil {
return false, "", fmt.Sprintf("%v", err)
}
return bytes.Equal(bufi.Bytes(), bufj.Bytes()), string(bufi.Bytes()), string(bufj.Bytes())
}

View file

@ -4,10 +4,10 @@ package markdown
import (
"io/ioutil"
"log"
"net/http"
"os"
"path"
"text/template"
"github.com/mholt/caddy/middleware"
"github.com/russross/blackfriday"
@ -59,8 +59,8 @@ type Config struct {
// List of JavaScript files to load for each markdown file
Scripts []string
// Map of registered templates
Templates map[string]string
// Template(s) to render with
Template *template.Template
}
// ServeHTTP implements the http.Handler interface.

View file

@ -5,6 +5,7 @@ import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
@ -14,11 +15,15 @@ import (
)
func TestMarkdown(t *testing.T) {
templates := make(map[string]string)
templates[DefaultTemplate] = "testdata/markdown_tpl.html"
rootDir := "./testdata"
f := func(filename string) string {
return filepath.ToSlash(rootDir + string(filepath.Separator) + filename)
}
md := Markdown{
Root: "./testdata",
FileSys: http.Dir("./testdata"),
Root: rootDir,
FileSys: http.Dir(rootDir),
Configs: []*Config{
{
Renderer: blackfriday.HtmlRenderer(0, "", ""),
@ -26,9 +31,9 @@ func TestMarkdown(t *testing.T) {
Extensions: map[string]struct{}{
".md": struct{}{},
},
Styles: []string{},
Scripts: []string{},
Templates: templates,
Styles: []string{},
Scripts: []string{},
Template: setDefaultTemplate(f("markdown_tpl.html")),
},
{
Renderer: blackfriday.HtmlRenderer(0, "", ""),
@ -36,11 +41,9 @@ func TestMarkdown(t *testing.T) {
Extensions: map[string]struct{}{
".md": struct{}{},
},
Styles: []string{},
Scripts: []string{},
Templates: map[string]string{
DefaultTemplate: "testdata/docflags/template.txt",
},
Styles: []string{},
Scripts: []string{},
Template: setDefaultTemplate(f("docflags/template.txt")),
},
{
Renderer: blackfriday.HtmlRenderer(0, "", ""),
@ -48,9 +51,9 @@ func TestMarkdown(t *testing.T) {
Extensions: map[string]struct{}{
".md": struct{}{},
},
Styles: []string{"/resources/css/log.css", "/resources/css/default.css"},
Scripts: []string{"/resources/js/log.js", "/resources/js/default.js"},
Templates: make(map[string]string),
Styles: []string{"/resources/css/log.css", "/resources/css/default.css"},
Scripts: []string{"/resources/js/log.js", "/resources/js/default.js"},
Template: GetDefaultTemplate(),
},
{
Renderer: blackfriday.HtmlRenderer(0, "", ""),
@ -58,9 +61,9 @@ func TestMarkdown(t *testing.T) {
Extensions: map[string]struct{}{
".md": struct{}{},
},
Styles: []string{},
Scripts: []string{},
Templates: templates,
Styles: []string{},
Scripts: []string{},
Template: setDefaultTemplate(f("markdown_tpl.html")),
},
},
IndexFiles: []string{"index.html"},
@ -145,12 +148,10 @@ DocFlags.var_bool true`
<title>Markdown test 2</title>
<meta charset="utf-8">
<link rel="stylesheet" href="/resources/css/log.css">
<link rel="stylesheet" href="/resources/css/default.css">
<link rel="stylesheet" href="/resources/css/default.css">
<script src="/resources/js/log.js"></script>
<script src="/resources/js/default.js"></script>
</head>
<script src="/resources/js/default.js"></script>
</head>
<body>
<h2>Welcome on the blog</h2>

View file

@ -2,19 +2,12 @@ package markdown
import (
"bytes"
"io/ioutil"
"path/filepath"
"text/template"
"github.com/mholt/caddy/middleware"
"github.com/russross/blackfriday"
)
const (
// DefaultTemplate is the default template.
DefaultTemplate = "defaultTemplate"
)
// Data represents a markdown document.
type Data struct {
middleware.Context
@ -52,24 +45,6 @@ func (md Markdown) Process(c *Config, requestPath string, b []byte, ctx middlewa
metadata = parser.Metadata()
}
// if template is not specified, check if Default template is set
if metadata.Template == "" {
if _, ok := c.Templates[DefaultTemplate]; ok {
metadata.Template = DefaultTemplate
}
}
// if template is set, load it
var tmpl []byte
if metadata.Template != "" {
if t, ok := c.Templates[metadata.Template]; ok {
tmpl, err = ioutil.ReadFile(t)
}
if err != nil {
return nil, err
}
}
// process markdown
extns := 0
extns |= blackfriday.EXTENSION_TABLES
@ -88,27 +63,12 @@ func (md Markdown) Process(c *Config, requestPath string, b []byte, ctx middlewa
}
metadata.Variables["title"] = title
return md.processTemplate(c, requestPath, tmpl, metadata, ctx)
// return md.processTemplate(c, requestPath, metadata, ctx)
return md.doTemplate(c, requestPath, metadata, ctx)
}
// processTemplate processes a template given a requestPath,
// template (tmpl) and metadata
func (md Markdown) processTemplate(c *Config, requestPath string, tmpl []byte, metadata Metadata, ctx middleware.Context) ([]byte, error) {
var t *template.Template
var err error
// if template is not specified,
// use the default template
if tmpl == nil {
t = template.Must(template.New("").Parse(htmlTemplate))
} else {
t, err = template.New("").Parse(string(tmpl))
if err != nil {
return nil, err
}
}
// process the template
// doTemplate executes a template given a requestPath, template, and metadata
func (md Markdown) doTemplate(c *Config, reqPath string, metadata Metadata, ctx middleware.Context) ([]byte, error) {
mdData := Data{
Context: ctx,
Doc: metadata.Variables,
@ -118,27 +78,9 @@ func (md Markdown) processTemplate(c *Config, requestPath string, tmpl []byte, m
}
b := new(bytes.Buffer)
err = t.Execute(b, mdData)
if err != nil {
if err := c.Template.ExecuteTemplate(b, metadata.Template, mdData); err != nil {
return nil, err
}
return b.Bytes(), nil
}
const (
htmlTemplate = `<!DOCTYPE html>
<html>
<head>
<title>{{.Doc.title}}</title>
<meta charset="utf-8">
{{range .Styles}}<link rel="stylesheet" href="{{.}}">
{{end -}}
{{range .Scripts}}<script src="{{.}}"></script>
{{end -}}
</head>
<body>
{{.Doc.body}}
</body>
</html>`
)

View file

@ -0,0 +1,55 @@
package markdown
import (
"io/ioutil"
"text/template"
)
func setDefaultTemplate(filename string) *template.Template {
buf, err := ioutil.ReadFile(filename)
if err != nil {
return nil
}
return template.Must(GetDefaultTemplate().Parse(string(buf)))
}
func SetTemplate(t *template.Template, name, filename string) error {
// Read template
buf, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
// Update if exists
if tt := t.Lookup(name); tt != nil {
_, err = tt.Parse(string(buf))
return err
}
// Allocate new name if not
_, err = t.New(name).Parse(string(buf))
return err
}
func GetDefaultTemplate() *template.Template {
return template.Must(template.New("").Parse(defaultTemplate))
}
const (
defaultTemplate = `<!DOCTYPE html>
<html>
<head>
<title>{{.Doc.title}}</title>
<meta charset="utf-8">
{{range .Styles}}<link rel="stylesheet" href="{{.}}">
{{end -}}
{{range .Scripts}}<script src="{{.}}"></script>
{{end -}}
</head>
<body>
{{.Doc.body}}
</body>
</html>`
)