Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
bf47951f
Commit
bf47951f
authored
Jul 25, 2015
by
Matt Holt
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #196 from evermax/master
markdown, browse: Integrated Context struct for templating
parents
6006de57
604c8abb
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
457 additions
and
49 deletions
+457
-49
config/setup/browse.go
config/setup/browse.go
+1
-1
config/setup/markdown.go
config/setup/markdown.go
+2
-1
middleware/browse/browse.go
middleware/browse/browse.go
+11
-3
middleware/browse/browse_test.go
middleware/browse/browse_test.go
+61
-0
middleware/browse/testdata/header.html
middleware/browse/testdata/header.html
+1
-0
middleware/browse/testdata/photos.tpl
middleware/browse/testdata/photos.tpl
+13
-0
middleware/browse/testdata/photos/test.html
middleware/browse/testdata/photos/test.html
+8
-0
middleware/browse/testdata/photos/test2.html
middleware/browse/testdata/photos/test2.html
+8
-0
middleware/context.go
middleware/context.go
+26
-27
middleware/markdown/markdown.go
middleware/markdown/markdown.go
+6
-1
middleware/markdown/markdown_test.go
middleware/markdown/markdown_test.go
+126
-0
middleware/markdown/process.go
middleware/markdown/process.go
+25
-15
middleware/markdown/testdata/blog/test.md
middleware/markdown/testdata/blog/test.md
+15
-0
middleware/markdown/testdata/header.html
middleware/markdown/testdata/header.html
+1
-0
middleware/markdown/testdata/log/test.md
middleware/markdown/testdata/log/test.md
+15
-0
middleware/markdown/testdata/markdown_tpl.html
middleware/markdown/testdata/markdown_tpl.html
+11
-0
middleware/templates/templates.go
middleware/templates/templates.go
+1
-1
middleware/templates/templates_test.go
middleware/templates/templates_test.go
+121
-0
middleware/templates/testdata/header.html
middleware/templates/testdata/header.html
+1
-0
middleware/templates/testdata/images/header.html
middleware/templates/testdata/images/header.html
+1
-0
middleware/templates/testdata/images/img.htm
middleware/templates/testdata/images/img.htm
+1
-0
middleware/templates/testdata/photos/test.html
middleware/templates/testdata/photos/test.html
+1
-0
middleware/templates/testdata/root.html
middleware/templates/testdata/root.html
+1
-0
No files found.
config/setup/browse.go
View file @
bf47951f
...
@@ -2,8 +2,8 @@ package setup
...
@@ -2,8 +2,8 @@ package setup
import
(
import
(
"fmt"
"fmt"
"html/template"
"io/ioutil"
"io/ioutil"
"text/template"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/browse"
"github.com/mholt/caddy/middleware/browse"
...
...
config/setup/markdown.go
View file @
bf47951f
...
@@ -62,7 +62,8 @@ func Markdown(c *Controller) (middleware.Middleware, error) {
...
@@ -62,7 +62,8 @@ func Markdown(c *Controller) (middleware.Middleware, error) {
reqPath
=
"/"
+
reqPath
reqPath
=
"/"
+
reqPath
// Generate the static file
// Generate the static file
_
,
err
=
md
.
Process
(
cfg
,
reqPath
,
body
)
ctx
:=
middleware
.
Context
{
Root
:
md
.
FileSys
}
_
,
err
=
md
.
Process
(
cfg
,
reqPath
,
body
,
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
middleware/browse/browse.go
View file @
bf47951f
...
@@ -5,13 +5,13 @@ package browse
...
@@ -5,13 +5,13 @@ package browse
import
(
import
(
"bytes"
"bytes"
"errors"
"errors"
"html/template"
"net/http"
"net/http"
"net/url"
"net/url"
"os"
"os"
"path"
"path"
"sort"
"sort"
"strings"
"strings"
"text/template"
"time"
"time"
"github.com/dustin/go-humanize"
"github.com/dustin/go-humanize"
...
@@ -51,6 +51,8 @@ type Listing struct {
...
@@ -51,6 +51,8 @@ type Listing struct {
// And which order
// And which order
Order
string
Order
string
middleware
.
Context
}
}
// FileInfo is the info about a particular file or directory
// FileInfo is the info about a particular file or directory
...
@@ -137,8 +139,9 @@ var IndexPages = []string{
...
@@ -137,8 +139,9 @@ var IndexPages = []string{
"default.txt"
,
"default.txt"
,
}
}
func
directoryListing
(
files
[]
os
.
FileInfo
,
urlPath
string
,
canGoUp
bool
)
(
Listing
,
error
)
{
func
directoryListing
(
files
[]
os
.
FileInfo
,
r
*
http
.
Request
,
canGoUp
bool
,
root
string
)
(
Listing
,
error
)
{
var
fileinfos
[]
FileInfo
var
fileinfos
[]
FileInfo
var
urlPath
=
r
.
URL
.
Path
for
_
,
f
:=
range
files
{
for
_
,
f
:=
range
files
{
name
:=
f
.
Name
()
name
:=
f
.
Name
()
...
@@ -170,6 +173,11 @@ func directoryListing(files []os.FileInfo, urlPath string, canGoUp bool) (Listin
...
@@ -170,6 +173,11 @@ func directoryListing(files []os.FileInfo, urlPath string, canGoUp bool) (Listin
Path
:
urlPath
,
Path
:
urlPath
,
CanGoUp
:
canGoUp
,
CanGoUp
:
canGoUp
,
Items
:
fileinfos
,
Items
:
fileinfos
,
Context
:
middleware
.
Context
{
Root
:
http
.
Dir
(
root
),
Req
:
r
,
URL
:
r
.
URL
,
},
},
nil
},
nil
}
}
...
@@ -224,7 +232,7 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
...
@@ -224,7 +232,7 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
}
}
}
}
// Assemble listing of directory contents
// Assemble listing of directory contents
listing
,
err
:=
directoryListing
(
files
,
r
.
URL
.
Path
,
canGoUp
)
listing
,
err
:=
directoryListing
(
files
,
r
,
canGoUp
,
b
.
Root
)
if
err
!=
nil
{
// directory isn't browsable
if
err
!=
nil
{
// directory isn't browsable
continue
continue
}
}
...
...
middleware/browse/browse_test.go
View file @
bf47951f
package
browse
package
browse
import
(
import
(
"net/http"
"net/http/httptest"
"sort"
"sort"
"testing"
"testing"
"text/template"
"time"
"time"
"github.com/mholt/caddy/middleware"
)
)
// "sort" package has "IsSorted" function, but no "IsReversed";
// "sort" package has "IsSorted" function, but no "IsReversed";
...
@@ -94,3 +99,59 @@ func TestSort(t *testing.T) {
...
@@ -94,3 +99,59 @@ func TestSort(t *testing.T) {
t
.
Errorf
(
"The listing isn't reversed by time: %v"
,
listing
.
Items
)
t
.
Errorf
(
"The listing isn't reversed by time: %v"
,
listing
.
Items
)
}
}
}
}
func
TestBrowseTemplate
(
t
*
testing
.
T
)
{
tmpl
,
err
:=
template
.
ParseFiles
(
"testdata/photos.tpl"
)
if
err
!=
nil
{
t
.
Fatalf
(
"An error occured while parsing the template: %v"
,
err
)
}
b
:=
Browse
{
Next
:
middleware
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
t
.
Fatalf
(
"Next shouldn't be called"
)
return
0
,
nil
}),
Root
:
"./testdata"
,
Configs
:
[]
Config
{
Config
{
PathScope
:
"/photos"
,
Template
:
tmpl
,
},
},
}
req
,
err
:=
http
.
NewRequest
(
"GET"
,
"/photos/"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Test: Could not create HTTP request: %v"
,
err
)
}
rec
:=
httptest
.
NewRecorder
()
b
.
ServeHTTP
(
rec
,
req
)
if
rec
.
Code
!=
http
.
StatusOK
{
t
.
Fatalf
(
"Wrong status, expected %d, got %d"
,
http
.
StatusOK
,
rec
.
Code
)
}
respBody
:=
rec
.
Body
.
String
()
expectedBody
:=
`<!DOCTYPE html>
<html>
<head>
<title>Template</title>
</head>
<body>
<h1>Header</h1>
<h1>/photos/</h1>
<a href="test.html">test.html</a><br>
<a href="test2.html">test2.html</a><br>
</body>
</html>
`
if
respBody
!=
expectedBody
{
t
.
Fatalf
(
"Expected body: %v got: %v"
,
expectedBody
,
respBody
)
}
}
middleware/browse/testdata/header.html
0 → 100644
View file @
bf47951f
<h1>
Header
</h1>
middleware/browse/testdata/photos.tpl
0 → 100644
View file @
bf47951f
<!DOCTYPE html>
<html>
<head>
<title>
Template
</title>
</head>
<body>
{{.Include "header.html"}}
<h1>
{{.Path}}
</h1>
{
{
range
.
Items
}
}
<a
href=
"{{.URL}}"
>
{{.Name}}
</a><br>
{
{
end
}
}
</body>
</html>
middleware/browse/testdata/photos/test.html
0 → 100644
View file @
bf47951f
<!DOCTYPE html>
<html>
<head>
<title>
Test
</title>
</head>
<body>
</body>
</html>
middleware/browse/testdata/photos/test2.html
0 → 100644
View file @
bf47951f
<!DOCTYPE html>
<html>
<head>
<title>
Test 2
</title>
</head>
<body>
</body>
</html>
middleware/
templates/
context.go
→
middleware/context.go
View file @
bf47951f
package
templates
package
middleware
import
(
import
(
"bytes"
"bytes"
...
@@ -8,23 +8,22 @@ import (
...
@@ -8,23 +8,22 @@ import (
"net/url"
"net/url"
"text/template"
"text/template"
"time"
"time"
"github.com/mholt/caddy/middleware"
)
)
// This file contains the context and functions available for
// This file contains the context and functions available for
// use in the templates.
// use in the templates.
// context is the context with which templates are executed.
// context is the context with which templates are executed.
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
c
ontext
)
Include
(
filename
string
)
(
string
,
error
)
{
func
(
c
C
ontext
)
Include
(
filename
string
)
(
string
,
error
)
{
file
,
err
:=
c
.
r
oot
.
Open
(
filename
)
file
,
err
:=
c
.
R
oot
.
Open
(
filename
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
...
@@ -50,13 +49,13 @@ func (c context) Include(filename string) (string, error) {
...
@@ -50,13 +49,13 @@ func (c context) Include(filename string) (string, error) {
}
}
// Date returns the current timestamp in the specified format
// Date returns the current timestamp in the specified format
func
(
c
c
ontext
)
Date
(
format
string
)
string
{
func
(
c
C
ontext
)
Date
(
format
string
)
string
{
return
time
.
Now
()
.
Format
(
format
)
return
time
.
Now
()
.
Format
(
format
)
}
}
// Cookie gets the value of a cookie with name name.
// Cookie gets the value of a cookie with name name.
func
(
c
c
ontext
)
Cookie
(
name
string
)
string
{
func
(
c
C
ontext
)
Cookie
(
name
string
)
string
{
cookies
:=
c
.
r
eq
.
Cookies
()
cookies
:=
c
.
R
eq
.
Cookies
()
for
_
,
cookie
:=
range
cookies
{
for
_
,
cookie
:=
range
cookies
{
if
cookie
.
Name
==
name
{
if
cookie
.
Name
==
name
{
return
cookie
.
Value
return
cookie
.
Value
...
@@ -66,15 +65,15 @@ func (c context) Cookie(name string) string {
...
@@ -66,15 +65,15 @@ func (c context) Cookie(name string) string {
}
}
// Header gets the value of a request header with field name.
// Header gets the value of a request header with field name.
func
(
c
c
ontext
)
Header
(
name
string
)
string
{
func
(
c
C
ontext
)
Header
(
name
string
)
string
{
return
c
.
r
eq
.
Header
.
Get
(
name
)
return
c
.
R
eq
.
Header
.
Get
(
name
)
}
}
// IP gets the (remote) IP address of the client making the request.
// IP gets the (remote) IP address of the client making the request.
func
(
c
c
ontext
)
IP
()
string
{
func
(
c
C
ontext
)
IP
()
string
{
ip
,
_
,
err
:=
net
.
SplitHostPort
(
c
.
r
eq
.
RemoteAddr
)
ip
,
_
,
err
:=
net
.
SplitHostPort
(
c
.
R
eq
.
RemoteAddr
)
if
err
!=
nil
{
if
err
!=
nil
{
return
c
.
r
eq
.
RemoteAddr
return
c
.
R
eq
.
RemoteAddr
}
}
return
ip
return
ip
}
}
...
@@ -82,14 +81,14 @@ func (c context) IP() string {
...
@@ -82,14 +81,14 @@ func (c context) IP() string {
// URI returns the raw, unprocessed request URI (including query
// URI returns the raw, unprocessed request URI (including query
// string and hash) obtained directly from the Request-Line of
// string and hash) obtained directly from the Request-Line of
// the HTTP request.
// the HTTP request.
func
(
c
c
ontext
)
URI
()
string
{
func
(
c
C
ontext
)
URI
()
string
{
return
c
.
r
eq
.
RequestURI
return
c
.
R
eq
.
RequestURI
}
}
// Host returns the hostname portion of the Host header
// Host returns the hostname portion of the Host header
// from the HTTP request.
// from the HTTP request.
func
(
c
c
ontext
)
Host
()
(
string
,
error
)
{
func
(
c
C
ontext
)
Host
()
(
string
,
error
)
{
host
,
_
,
err
:=
net
.
SplitHostPort
(
c
.
r
eq
.
Host
)
host
,
_
,
err
:=
net
.
SplitHostPort
(
c
.
R
eq
.
Host
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
...
@@ -97,8 +96,8 @@ func (c context) Host() (string, error) {
...
@@ -97,8 +96,8 @@ func (c context) Host() (string, error) {
}
}
// Port returns the port portion of the Host header if specified.
// Port returns the port portion of the Host header if specified.
func
(
c
c
ontext
)
Port
()
(
string
,
error
)
{
func
(
c
C
ontext
)
Port
()
(
string
,
error
)
{
_
,
port
,
err
:=
net
.
SplitHostPort
(
c
.
r
eq
.
Host
)
_
,
port
,
err
:=
net
.
SplitHostPort
(
c
.
R
eq
.
Host
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
...
@@ -106,12 +105,12 @@ func (c context) Port() (string, error) {
...
@@ -106,12 +105,12 @@ func (c context) Port() (string, error) {
}
}
// Method returns the method (GET, POST, etc.) of the request.
// Method returns the method (GET, POST, etc.) of the request.
func
(
c
c
ontext
)
Method
()
string
{
func
(
c
C
ontext
)
Method
()
string
{
return
c
.
r
eq
.
Method
return
c
.
R
eq
.
Method
}
}
// PathMatches returns true if the path portion of the request
// PathMatches returns true if the path portion of the request
// URL matches pattern.
// URL matches pattern.
func
(
c
c
ontext
)
PathMatches
(
pattern
string
)
bool
{
func
(
c
C
ontext
)
PathMatches
(
pattern
string
)
bool
{
return
middleware
.
Path
(
c
.
r
eq
.
URL
.
Path
)
.
Matches
(
pattern
)
return
Path
(
c
.
R
eq
.
URL
.
Path
)
.
Matches
(
pattern
)
}
}
middleware/markdown/markdown.go
View file @
bf47951f
...
@@ -119,7 +119,12 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
...
@@ -119,7 +119,12 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
return
http
.
StatusInternalServerError
,
err
return
http
.
StatusInternalServerError
,
err
}
}
html
,
err
:=
md
.
Process
(
m
,
fpath
,
body
)
ctx
:=
middleware
.
Context
{
Root
:
md
.
FileSys
,
Req
:
r
,
URL
:
r
.
URL
,
}
html
,
err
:=
md
.
Process
(
m
,
fpath
,
body
,
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
return
http
.
StatusInternalServerError
,
err
}
}
...
...
middleware/markdown/markdown_test.go
0 → 100644
View file @
bf47951f
package
markdown
import
(
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/mholt/caddy/middleware"
"github.com/russross/blackfriday"
)
func
TestMarkdown
(
t
*
testing
.
T
)
{
templates
:=
make
(
map
[
string
]
string
)
templates
[
DefaultTemplate
]
=
"testdata/markdown_tpl.html"
md
:=
Markdown
{
Root
:
"./testdata"
,
FileSys
:
http
.
Dir
(
"./testdata"
),
Configs
:
[]
Config
{
Config
{
Renderer
:
blackfriday
.
HtmlRenderer
(
0
,
""
,
""
),
PathScope
:
"/blog"
,
Extensions
:
[]
string
{
".md"
},
Styles
:
[]
string
{},
Scripts
:
[]
string
{},
Templates
:
templates
,
},
Config
{
Renderer
:
blackfriday
.
HtmlRenderer
(
0
,
""
,
""
),
PathScope
:
"/log"
,
Extensions
:
[]
string
{
".md"
},
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
),
},
},
IndexFiles
:
[]
string
{
"index.html"
},
Next
:
middleware
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
t
.
Fatalf
(
"Next shouldn't be called"
)
return
0
,
nil
}),
}
req
,
err
:=
http
.
NewRequest
(
"GET"
,
"/blog/test.md"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Could not create HTTP request: %v"
,
err
)
}
rec
:=
httptest
.
NewRecorder
()
md
.
ServeHTTP
(
rec
,
req
)
if
rec
.
Code
!=
http
.
StatusOK
{
t
.
Fatalf
(
"Wrong status, expected: %d and got %d"
,
http
.
StatusOK
,
rec
.
Code
)
}
respBody
:=
rec
.
Body
.
String
()
expectedBody
:=
`<!DOCTYPE html>
<html>
<head>
<title>Markdown test</title>
</head>
<body>
<h1>Header</h1>
Welcome to A Caddy website!
<h2>Welcome on the blog</h2>
<p>Body</p>
<p><code>go
func getTrue() bool {
return true
}
</code></p>
</body>
</html>
`
if
respBody
!=
expectedBody
{
t
.
Fatalf
(
"Expected body: %v got: %v"
,
expectedBody
,
respBody
)
}
req
,
err
=
http
.
NewRequest
(
"GET"
,
"/log/test.md"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Could not create HTTP request: %v"
,
err
)
}
rec
=
httptest
.
NewRecorder
()
md
.
ServeHTTP
(
rec
,
req
)
if
rec
.
Code
!=
http
.
StatusOK
{
t
.
Fatalf
(
"Wrong status, expected: %d and got %d"
,
http
.
StatusOK
,
rec
.
Code
)
}
respBody
=
rec
.
Body
.
String
()
expectedBody
=
`<!DOCTYPE html>
<html>
<head>
<title>Markdown test</title>
<meta charset="utf-8">
<link rel="stylesheet" href="/resources/css/log.css">
<link rel="stylesheet" href="/resources/css/default.css">
<script src="/resources/js/log.js"></script>
<script src="/resources/js/default.js"></script>
</head>
<body>
<h2>Welcome on the blog</h2>
<p>Body</p>
<p><code>go
func getTrue() bool {
return true
}
</code></p>
</body>
</html>`
replacer
:=
strings
.
NewReplacer
(
"
\r
"
,
""
,
"
\n
"
,
""
)
respBody
=
replacer
.
Replace
(
respBody
)
expectedBody
=
replacer
.
Replace
(
expectedBody
)
if
respBody
!=
expectedBody
{
t
.
Fatalf
(
"Expected body: %v got: %v"
,
expectedBody
,
respBody
)
}
}
middleware/markdown/process.go
View file @
bf47951f
...
@@ -9,6 +9,7 @@ import (
...
@@ -9,6 +9,7 @@ import (
"strings"
"strings"
"text/template"
"text/template"
"github.com/mholt/caddy/middleware"
"github.com/russross/blackfriday"
"github.com/russross/blackfriday"
)
)
...
@@ -17,9 +18,14 @@ const (
...
@@ -17,9 +18,14 @@ const (
DefaultStaticDir
=
"generated_site"
DefaultStaticDir
=
"generated_site"
)
)
type
MarkdownData
struct
{
middleware
.
Context
Doc
map
[
string
]
interface
{}
}
// 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
)
([]
byte
,
error
)
{
func
(
md
Markdown
)
Process
(
c
Config
,
requestPath
string
,
b
[]
byte
,
ctx
middleware
.
Context
)
([]
byte
,
error
)
{
var
metadata
=
Metadata
{
Variables
:
make
(
map
[
string
]
interface
{})}
var
metadata
=
Metadata
{
Variables
:
make
(
map
[
string
]
interface
{})}
var
markdown
[]
byte
var
markdown
[]
byte
var
err
error
var
err
error
...
@@ -61,14 +67,21 @@ func (md Markdown) Process(c Config, requestPath string, b []byte) ([]byte, erro
...
@@ -61,14 +67,21 @@ func (md Markdown) Process(c Config, requestPath string, b []byte) ([]byte, erro
markdown
=
blackfriday
.
Markdown
(
markdown
,
c
.
Renderer
,
0
)
markdown
=
blackfriday
.
Markdown
(
markdown
,
c
.
Renderer
,
0
)
// set it as body for template
// set it as body for template
metadata
.
Variables
[
"markdown"
]
=
string
(
markdown
)
metadata
.
Variables
[
"body"
]
=
string
(
markdown
)
title
:=
metadata
.
Title
if
title
==
""
{
title
=
filepath
.
Base
(
requestPath
)
var
extension
=
filepath
.
Ext
(
requestPath
)
title
=
title
[
0
:
len
(
title
)
-
len
(
extension
)]
}
metadata
.
Variables
[
"title"
]
=
title
return
md
.
processTemplate
(
c
,
requestPath
,
tmpl
,
metadata
)
return
md
.
processTemplate
(
c
,
requestPath
,
tmpl
,
metadata
,
ctx
)
}
}
// processTemplate processes a template given a requestPath,
// processTemplate processes a template given a requestPath,
// template (tmpl) and metadata
// template (tmpl) and metadata
func
(
md
Markdown
)
processTemplate
(
c
Config
,
requestPath
string
,
tmpl
[]
byte
,
metadata
Metadata
)
([]
byte
,
error
)
{
func
(
md
Markdown
)
processTemplate
(
c
Config
,
requestPath
string
,
tmpl
[]
byte
,
metadata
Metadata
,
ctx
middleware
.
Context
)
([]
byte
,
error
)
{
// if template is not specified,
// if template is not specified,
// use the default template
// use the default template
if
tmpl
==
nil
{
if
tmpl
==
nil
{
...
@@ -81,7 +94,12 @@ func (md Markdown) processTemplate(c Config, requestPath string, tmpl []byte, me
...
@@ -81,7 +94,12 @@ func (md Markdown) processTemplate(c Config, requestPath string, tmpl []byte, me
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
err
=
t
.
Execute
(
b
,
metadata
.
Variables
);
err
!=
nil
{
mdData
:=
MarkdownData
{
Context
:
ctx
,
Doc
:
metadata
.
Variables
,
}
if
err
=
t
.
Execute
(
b
,
mdData
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -148,15 +166,7 @@ func defaultTemplate(c Config, metadata Metadata, requestPath string) []byte {
...
@@ -148,15 +166,7 @@ func defaultTemplate(c Config, metadata Metadata, requestPath string) []byte {
}
}
// Title is first line (length-limited), otherwise filename
// Title is first line (length-limited), otherwise filename
title
:=
metadata
.
Title
title
,
_
:=
metadata
.
Variables
[
"title"
]
.
(
string
)
if
title
==
""
{
title
=
filepath
.
Base
(
requestPath
)
if
body
,
_
:=
metadata
.
Variables
[
"markdown"
]
.
([]
byte
);
len
(
body
)
>
128
{
title
=
string
(
body
[
:
128
])
}
else
if
len
(
body
)
>
0
{
title
=
string
(
body
)
}
}
html
:=
[]
byte
(
htmlTemplate
)
html
:=
[]
byte
(
htmlTemplate
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{title}}"
),
[]
byte
(
title
),
1
)
html
=
bytes
.
Replace
(
html
,
[]
byte
(
"{{title}}"
),
[]
byte
(
title
),
1
)
...
@@ -176,7 +186,7 @@ const (
...
@@ -176,7 +186,7 @@ const (
{{js}}
{{js}}
</head>
</head>
<body>
<body>
{{.
markdown
}}
{{.
Doc.body
}}
</body>
</body>
</html>`
</html>`
cssTemplate
=
`<link rel="stylesheet" href="{{url}}">`
cssTemplate
=
`<link rel="stylesheet" href="{{url}}">`
...
...
middleware/markdown/testdata/blog/test.md
0 → 100644
View file @
bf47951f
---
title
:
Markdown test
variables
:
sitename
:
A Caddy website
---
## Welcome on the blog
Body
```
go
func
getTrue
()
bool
{
return
true
}
```
middleware/markdown/testdata/header.html
0 → 100644
View file @
bf47951f
<h1>
Header
</h1>
middleware/markdown/testdata/log/test.md
0 → 100644
View file @
bf47951f
---
title
:
Markdown test
variables
:
sitename
:
A Caddy website
---
## Welcome on the blog
Body
```
go
func
getTrue
()
bool
{
return
true
}
```
middleware/markdown/testdata/markdown_tpl.html
0 → 100644
View file @
bf47951f
<!DOCTYPE html>
<html>
<head>
<title>
{{.Doc.title}}
</title>
</head>
<body>
{{.Include "header.html"}}
Welcome to {{.Doc.sitename}}!
{{.Doc.body}}
</body>
</html>
middleware/templates/templates.go
View file @
bf47951f
...
@@ -31,7 +31,7 @@ func (t Templates) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
...
@@ -31,7 +31,7 @@ func (t Templates) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
for
_
,
ext
:=
range
rule
.
Extensions
{
for
_
,
ext
:=
range
rule
.
Extensions
{
if
reqExt
==
ext
{
if
reqExt
==
ext
{
// Create execution context
// Create execution context
ctx
:=
context
{
root
:
t
.
FileSys
,
r
eq
:
r
,
URL
:
r
.
URL
}
ctx
:=
middleware
.
Context
{
Root
:
t
.
FileSys
,
R
eq
:
r
,
URL
:
r
.
URL
}
// Build the template
// Build the template
tpl
,
err
:=
template
.
ParseFiles
(
filepath
.
Join
(
t
.
Root
,
fpath
))
tpl
,
err
:=
template
.
ParseFiles
(
filepath
.
Join
(
t
.
Root
,
fpath
))
...
...
middleware/templates/templates_test.go
0 → 100644
View file @
bf47951f
package
templates
import
(
"net/http"
"net/http/httptest"
"testing"
"github.com/mholt/caddy/middleware"
)
func
Test
(
t
*
testing
.
T
)
{
tmpl
:=
Templates
{
Next
:
middleware
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
return
0
,
nil
}),
Rules
:
[]
Rule
{
Rule
{
Extensions
:
[]
string
{
".html"
},
IndexFiles
:
[]
string
{
"index.html"
},
Path
:
"/photos"
,
},
Rule
{
Extensions
:
[]
string
{
".html"
,
".htm"
},
IndexFiles
:
[]
string
{
"index.html"
,
"index.htm"
},
Path
:
"/images"
,
},
},
Root
:
"./testdata"
,
FileSys
:
http
.
Dir
(
"./testdata"
),
}
tmplroot
:=
Templates
{
Next
:
middleware
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
return
0
,
nil
}),
Rules
:
[]
Rule
{
Rule
{
Extensions
:
[]
string
{
".html"
},
IndexFiles
:
[]
string
{
"index.html"
},
Path
:
"/"
,
},
},
Root
:
"./testdata"
,
FileSys
:
http
.
Dir
(
"./testdata"
),
}
/*
* Test tmpl on /photos/test.html
*/
req
,
err
:=
http
.
NewRequest
(
"GET"
,
"/photos/test.html"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Test: Could not create HTTP request: %v"
,
err
)
}
rec
:=
httptest
.
NewRecorder
()
tmpl
.
ServeHTTP
(
rec
,
req
)
if
rec
.
Code
!=
http
.
StatusOK
{
t
.
Fatalf
(
"Test: Wrong response code: %d, should be %d"
,
rec
.
Code
,
http
.
StatusOK
)
}
respBody
:=
rec
.
Body
.
String
()
expectedBody
:=
`<!DOCTYPE html><html><head><title>test page</title></head><body><h1>Header title</h1>
</body></html>
`
if
respBody
!=
expectedBody
{
t
.
Fatalf
(
"Test: the expected body %v is different from the response one: %v"
,
expectedBody
,
respBody
)
}
/*
* Test tmpl on /images/img.htm
*/
req
,
err
=
http
.
NewRequest
(
"GET"
,
"/images/img.htm"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Could not create HTTP request: %v"
,
err
)
}
rec
=
httptest
.
NewRecorder
()
tmpl
.
ServeHTTP
(
rec
,
req
)
if
rec
.
Code
!=
http
.
StatusOK
{
t
.
Fatalf
(
"Test: Wrong response code: %d, should be %d"
,
rec
.
Code
,
http
.
StatusOK
)
}
respBody
=
rec
.
Body
.
String
()
expectedBody
=
`<!DOCTYPE html><html><head><title>img</title></head><body><h1>Header title</h1>
</body></html>
`
if
respBody
!=
expectedBody
{
t
.
Fatalf
(
"Test: the expected body %v is different from the response one: %v"
,
expectedBody
,
respBody
)
}
/*
* Test tmplroot on /root.html
*/
req
,
err
=
http
.
NewRequest
(
"GET"
,
"/root.html"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Could not create HTTP request: %v"
,
err
)
}
rec
=
httptest
.
NewRecorder
()
tmplroot
.
ServeHTTP
(
rec
,
req
)
if
rec
.
Code
!=
http
.
StatusOK
{
t
.
Fatalf
(
"Test: Wrong response code: %d, should be %d"
,
rec
.
Code
,
http
.
StatusOK
)
}
respBody
=
rec
.
Body
.
String
()
expectedBody
=
`<!DOCTYPE html><html><head><title>root</title></head><body><h1>Header title</h1>
</body></html>
`
if
respBody
!=
expectedBody
{
t
.
Fatalf
(
"Test: the expected body %v is different from the response one: %v"
,
expectedBody
,
respBody
)
}
}
middleware/templates/testdata/header.html
0 → 100644
View file @
bf47951f
<h1>
Header title
</h1>
middleware/templates/testdata/images/header.html
0 → 100644
View file @
bf47951f
<h1>
Header title
</h1>
middleware/templates/testdata/images/img.htm
0 → 100644
View file @
bf47951f
<!DOCTYPE html>
<html><head><title>
img
</title></head><body>
{{.Include "header.html"}}
</body></html>
middleware/templates/testdata/photos/test.html
0 → 100644
View file @
bf47951f
<!DOCTYPE html>
<html><head><title>
test page
</title></head><body>
{{.Include "../header.html"}}
</body></html>
middleware/templates/testdata/root.html
0 → 100644
View file @
bf47951f
<!DOCTYPE html>
<html><head><title>
root
</title></head><body>
{{.Include "header.html"}}
</body></html>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment