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

Merge pull request #662 from mholt/md-include-fix

markdown: Included files in Markdown templates have access to document vars
This commit is contained in:
Matt Holt 2016-03-16 13:56:06 -06:00
commit 4f5fe2de24
4 changed files with 43 additions and 29 deletions

View file

@ -20,35 +20,12 @@ import (
type Context struct { type Context struct {
Root http.FileSystem Root http.FileSystem
Req *http.Request Req *http.Request
// This is used to access information about the URL.
URL *url.URL URL *url.URL
} }
// Include returns the contents of filename relative to the site root // Include returns the contents of filename relative to the site root.
func (c Context) Include(filename string) (string, error) { func (c Context) Include(filename string) (string, error) {
file, err := c.Root.Open(filename) return ContextInclude(filename, c, c.Root)
if err != nil {
return "", err
}
defer file.Close()
body, err := ioutil.ReadAll(file)
if err != nil {
return "", err
}
tpl, err := template.New(filename).Parse(string(body))
if err != nil {
return "", err
}
var buf bytes.Buffer
err = tpl.Execute(&buf, c)
if err != nil {
return "", err
}
return buf.String(), nil
} }
// Now returns the current timestamp in the specified format. // Now returns the current timestamp in the specified format.
@ -212,3 +189,34 @@ func (c Context) Markdown(filename string) (string, error) {
return string(markdown), nil return string(markdown), nil
} }
// ContextInclude opens filename using fs and executes a template with the context ctx.
// This does the same thing that Context.Include() does, but with the ability to provide
// your own context so that the included files can have access to additional fields your
// type may provide. You can embed Context in your type, then override its Include method
// to call this function with ctx being the instance of your type, and fs being Context.Root.
func ContextInclude(filename string, ctx interface{}, fs http.FileSystem) (string, error) {
file, err := fs.Open(filename)
if err != nil {
return "", err
}
defer file.Close()
body, err := ioutil.ReadAll(file)
if err != nil {
return "", err
}
tpl, err := template.New(filename).Parse(string(body))
if err != nil {
return "", err
}
var buf bytes.Buffer
err = tpl.Execute(&buf, ctx)
if err != nil {
return "", err
}
return buf.String(), nil
}

View file

@ -107,7 +107,7 @@ func TestMarkdown(t *testing.T) {
<title>Markdown test 1</title> <title>Markdown test 1</title>
</head> </head>
<body> <body>
<h1>Header</h1> <h1>Header for: Markdown test 1</h1>
Welcome to A Caddy website! Welcome to A Caddy website!
<h2>Welcome on the blog</h2> <h2>Welcome on the blog</h2>
@ -208,7 +208,7 @@ DocFlags.var_bool true`
<title>first_post</title> <title>first_post</title>
</head> </head>
<body> <body>
<h1>Header</h1> <h1>Header for: first_post</h1>
Welcome to title! Welcome to title!
<h1>Test h1</h1> <h1>Test h1</h1>

View file

@ -28,6 +28,12 @@ type Data struct {
Links []PageLink Links []PageLink
} }
// Include "overrides" the embedded middleware.Context's Include()
// method so that included files have access to d's fields.
func (d Data) Include(filename string) (string, error) {
return middleware.ContextInclude(filename, d, d.Root)
}
// Process processes the contents of a page in b. It parses the metadata // Process processes the contents of a page in b. It parses the metadata
// (if any) and uses the template (if found). // (if any) and uses the template (if found).
func (md Markdown) Process(c *Config, requestPath string, b []byte, ctx middleware.Context) ([]byte, error) { func (md Markdown) Process(c *Config, requestPath string, b []byte, ctx middleware.Context) ([]byte, error) {

View file

@ -1 +1 @@
<h1>Header</h1> <h1>Header for: {{.Doc.title}}</h1>