mirror of
https://github.com/gohugoio/hugo.git
synced 2024-07-05 08:42:12 +00:00
parent
4ea4359ac1
commit
d6000a208c
|
@ -19,16 +19,17 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/spf13/hugo/tpl"
|
||||||
|
|
||||||
"github.com/spf13/hugo/helpers"
|
"github.com/spf13/hugo/helpers"
|
||||||
"github.com/spf13/hugo/tpl"
|
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -106,9 +107,8 @@ void do();
|
||||||
"(?s)^\n<div class=\"highlight\" style=\"background: #f0f0f0\"><pre style=\"line-height: 125%\">.*?void</span>.*?do</span>.*?().*?</pre></div>\n$",
|
"(?s)^\n<div class=\"highlight\" style=\"background: #f0f0f0\"><pre style=\"line-height: 125%\">.*?void</span>.*?do</span>.*?().*?</pre></div>\n$",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
templ := tpl.New(logger)
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md")
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("[%d] Handle shortcode error", i)
|
t.Fatalf("[%d] Handle shortcode error", i)
|
||||||
|
@ -150,9 +150,8 @@ func TestShortcodeFigure(t *testing.T) {
|
||||||
"(?s)^\n<figure >.*?<img src=\"/img/hugo-logo.png\" />.*?<figcaption>.*?<p>.*?<a href=\"/img/hugo-logo.png\">.*?Hugo logo.*?</a>.*?</p>.*?</figcaption>.*?</figure>\n$",
|
"(?s)^\n<figure >.*?<img src=\"/img/hugo-logo.png\" />.*?<figcaption>.*?<p>.*?<a href=\"/img/hugo-logo.png\">.*?Hugo logo.*?</a>.*?</p>.*?</figcaption>.*?</figure>\n$",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
templ := tpl.New(logger)
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md")
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
matched, err := regexp.MatchString(this.expected, output)
|
matched, err := regexp.MatchString(this.expected, output)
|
||||||
|
|
||||||
|
@ -175,9 +174,8 @@ func TestShortcodeSpeakerdeck(t *testing.T) {
|
||||||
"(?s)^<script async class='speakerdeck-embed' data-id='4e8126e72d853c0060001f97'.*?>.*?</script>$",
|
"(?s)^<script async class='speakerdeck-embed' data-id='4e8126e72d853c0060001f97'.*?>.*?</script>$",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
templ := tpl.New(logger)
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md")
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
matched, err := regexp.MatchString(this.expected, output)
|
matched, err := regexp.MatchString(this.expected, output)
|
||||||
|
|
||||||
|
@ -210,9 +208,8 @@ func TestShortcodeYoutube(t *testing.T) {
|
||||||
"(?s)^\n<div class=\"video\">.*?<iframe src=\"//www.youtube.com/embed/w7Ft2ymGmfc\\?autoplay=1\".*?allowfullscreen frameborder=\"0\">.*?</iframe>.*?</div>$",
|
"(?s)^\n<div class=\"video\">.*?<iframe src=\"//www.youtube.com/embed/w7Ft2ymGmfc\\?autoplay=1\".*?allowfullscreen frameborder=\"0\">.*?</iframe>.*?</div>$",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
templ := tpl.New(logger)
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md")
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
matched, err := regexp.MatchString(this.expected, output)
|
matched, err := regexp.MatchString(this.expected, output)
|
||||||
|
|
||||||
|
@ -245,9 +242,8 @@ func TestShortcodeVimeo(t *testing.T) {
|
||||||
"(?s)^<div class=\"video\">.*?<iframe src=\"//player.vimeo.com/video/146022717\" webkitallowfullscreen mozallowfullscreen allowfullscreen>.*?</iframe>.*?</div>$",
|
"(?s)^<div class=\"video\">.*?<iframe src=\"//player.vimeo.com/video/146022717\" webkitallowfullscreen mozallowfullscreen allowfullscreen>.*?</iframe>.*?</div>$",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
templ := tpl.New(logger)
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md")
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
matched, err := regexp.MatchString(this.expected, output)
|
matched, err := regexp.MatchString(this.expected, output)
|
||||||
|
|
||||||
|
@ -274,9 +270,8 @@ func TestShortcodeGist(t *testing.T) {
|
||||||
"(?s)^<script src=\"//gist.github.com/spf13/7896402.js\\?file=img.html\"></script>$",
|
"(?s)^<script src=\"//gist.github.com/spf13/7896402.js\\?file=img.html\"></script>$",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
templ := tpl.New(logger)
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md")
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
matched, err := regexp.MatchString(this.expected, output)
|
matched, err := regexp.MatchString(this.expected, output)
|
||||||
|
|
||||||
|
@ -313,13 +308,14 @@ func TestShortcodeTweet(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
templ := tpl.New(logger)
|
p, _ := pageFromString(simplePage, "simple.md", func(templ tpl.Template) error {
|
||||||
templ.Lookup("").Funcs(tweetFuncMap)
|
templ.Funcs(tweetFuncMap)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
|
||||||
cacheFileID := viper.GetString("cacheDir") + url.QueryEscape("https://api.twitter.com/1/statuses/oembed.json?id=666616452582129664")
|
cacheFileID := viper.GetString("cacheDir") + url.QueryEscape("https://api.twitter.com/1/statuses/oembed.json?id=666616452582129664")
|
||||||
defer os.Remove(cacheFileID)
|
defer os.Remove(cacheFileID)
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
matched, err := regexp.MatchString(this.expected, output)
|
matched, err := regexp.MatchString(this.expected, output)
|
||||||
|
|
||||||
|
@ -353,7 +349,7 @@ func TestShortcodeInstagram(t *testing.T) {
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
// overload getJSON to return mock API response from Instagram
|
// overload getJSON to return mock API response from Instagram
|
||||||
tweetFuncMap := template.FuncMap{
|
instagramFuncMap := template.FuncMap{
|
||||||
"getJSON": func(urlParts ...string) interface{} {
|
"getJSON": func(urlParts ...string) interface{} {
|
||||||
var v interface{}
|
var v interface{}
|
||||||
err := json.Unmarshal([]byte(this.resp), &v)
|
err := json.Unmarshal([]byte(this.resp), &v)
|
||||||
|
@ -365,13 +361,14 @@ func TestShortcodeInstagram(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
templ := tpl.New(logger)
|
p, _ := pageFromString(simplePage, "simple.md", func(templ tpl.Template) error {
|
||||||
templ.Lookup("").Funcs(tweetFuncMap)
|
templ.Funcs(instagramFuncMap)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
|
||||||
cacheFileID := viper.GetString("cacheDir") + url.QueryEscape("https://api.instagram.com/oembed/?url=https://instagram.com/p/BMokmydjG-M/&hidecaption="+this.hidecaption)
|
cacheFileID := viper.GetString("cacheDir") + url.QueryEscape("https://api.instagram.com/oembed/?url=https://instagram.com/p/BMokmydjG-M/&hidecaption="+this.hidecaption)
|
||||||
defer os.Remove(cacheFileID)
|
defer os.Remove(cacheFileID)
|
||||||
output, err := HandleShortcodes(this.in, p, templ)
|
output, err := HandleShortcodes(this.in, p)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("[%d] Failed to render shortcodes", i)
|
t.Fatalf("[%d] Failed to render shortcodes", i)
|
||||||
|
|
|
@ -15,12 +15,11 @@ package hugolib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/hugo/source"
|
"github.com/spf13/hugo/source"
|
||||||
"github.com/spf13/hugo/tpl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
FileConvert(*source.File, *Site) HandledResult
|
FileConvert(*source.File, *Site) HandledResult
|
||||||
PageConvert(*Page, tpl.Template) HandledResult
|
PageConvert(*Page) HandledResult
|
||||||
Read(*source.File, *Site) HandledResult
|
Read(*source.File, *Site) HandledResult
|
||||||
Extensions() []string
|
Extensions() []string
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ import (
|
||||||
|
|
||||||
"github.com/dchest/cssmin"
|
"github.com/dchest/cssmin"
|
||||||
"github.com/spf13/hugo/source"
|
"github.com/spf13/hugo/source"
|
||||||
"github.com/spf13/hugo/tpl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -32,7 +31,7 @@ func (h basicFileHandler) Read(f *source.File, s *Site) HandledResult {
|
||||||
return HandledResult{file: f}
|
return HandledResult{file: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h basicFileHandler) PageConvert(*Page, tpl.Template) HandledResult {
|
func (h basicFileHandler) PageConvert(*Page) HandledResult {
|
||||||
return HandledResult{}
|
return HandledResult{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ func (mh *MetaHandle) Convert(i interface{}, s *Site, results HandleResults) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
results <- h.PageConvert(p, s.owner.tmpl)
|
results <- h.PageConvert(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/hugo/helpers"
|
"github.com/spf13/hugo/helpers"
|
||||||
"github.com/spf13/hugo/source"
|
"github.com/spf13/hugo/source"
|
||||||
"github.com/spf13/hugo/tpl"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,8 +55,8 @@ type markdownHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h markdownHandler) Extensions() []string { return []string{"mdown", "markdown", "md"} }
|
func (h markdownHandler) Extensions() []string { return []string{"mdown", "markdown", "md"} }
|
||||||
func (h markdownHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
|
func (h markdownHandler) PageConvert(p *Page) HandledResult {
|
||||||
return commonConvert(p, t)
|
return commonConvert(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
type htmlHandler struct {
|
type htmlHandler struct {
|
||||||
|
@ -65,7 +64,9 @@ type htmlHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h htmlHandler) Extensions() []string { return []string{"html", "htm"} }
|
func (h htmlHandler) Extensions() []string { return []string{"html", "htm"} }
|
||||||
func (h htmlHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
|
|
||||||
|
// TODO(bep) globals use p.s.t
|
||||||
|
func (h htmlHandler) PageConvert(p *Page) HandledResult {
|
||||||
if p.rendered {
|
if p.rendered {
|
||||||
panic(fmt.Sprintf("Page %q already rendered, does not need conversion", p.BaseFileName()))
|
panic(fmt.Sprintf("Page %q already rendered, does not need conversion", p.BaseFileName()))
|
||||||
}
|
}
|
||||||
|
@ -73,7 +74,7 @@ func (h htmlHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
|
||||||
// Work on a copy of the raw content from now on.
|
// Work on a copy of the raw content from now on.
|
||||||
p.createWorkContentCopy()
|
p.createWorkContentCopy()
|
||||||
|
|
||||||
p.ProcessShortcodes(t)
|
p.ProcessShortcodes()
|
||||||
|
|
||||||
return HandledResult{err: nil}
|
return HandledResult{err: nil}
|
||||||
}
|
}
|
||||||
|
@ -83,8 +84,8 @@ type asciidocHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h asciidocHandler) Extensions() []string { return []string{"asciidoc", "adoc", "ad"} }
|
func (h asciidocHandler) Extensions() []string { return []string{"asciidoc", "adoc", "ad"} }
|
||||||
func (h asciidocHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
|
func (h asciidocHandler) PageConvert(p *Page) HandledResult {
|
||||||
return commonConvert(p, t)
|
return commonConvert(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
type rstHandler struct {
|
type rstHandler struct {
|
||||||
|
@ -92,8 +93,8 @@ type rstHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h rstHandler) Extensions() []string { return []string{"rest", "rst"} }
|
func (h rstHandler) Extensions() []string { return []string{"rest", "rst"} }
|
||||||
func (h rstHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
|
func (h rstHandler) PageConvert(p *Page) HandledResult {
|
||||||
return commonConvert(p, t)
|
return commonConvert(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
type mmarkHandler struct {
|
type mmarkHandler struct {
|
||||||
|
@ -101,11 +102,11 @@ type mmarkHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h mmarkHandler) Extensions() []string { return []string{"mmark"} }
|
func (h mmarkHandler) Extensions() []string { return []string{"mmark"} }
|
||||||
func (h mmarkHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
|
func (h mmarkHandler) PageConvert(p *Page) HandledResult {
|
||||||
return commonConvert(p, t)
|
return commonConvert(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func commonConvert(p *Page, t tpl.Template) HandledResult {
|
func commonConvert(p *Page) HandledResult {
|
||||||
if p.rendered {
|
if p.rendered {
|
||||||
panic(fmt.Sprintf("Page %q already rendered, does not need conversion", p.BaseFileName()))
|
panic(fmt.Sprintf("Page %q already rendered, does not need conversion", p.BaseFileName()))
|
||||||
}
|
}
|
||||||
|
@ -113,7 +114,7 @@ func commonConvert(p *Page, t tpl.Template) HandledResult {
|
||||||
// Work on a copy of the raw content from now on.
|
// Work on a copy of the raw content from now on.
|
||||||
p.createWorkContentCopy()
|
p.createWorkContentCopy()
|
||||||
|
|
||||||
p.ProcessShortcodes(t)
|
p.ProcessShortcodes()
|
||||||
|
|
||||||
// TODO(bep) these page handlers need to be re-evaluated, as it is hard to
|
// TODO(bep) these page handlers need to be re-evaluated, as it is hard to
|
||||||
// process a page in isolation. See the new preRender func.
|
// process a page in isolation. See the new preRender func.
|
||||||
|
|
|
@ -34,7 +34,6 @@ import (
|
||||||
type HugoSites struct {
|
type HugoSites struct {
|
||||||
Sites []*Site
|
Sites []*Site
|
||||||
|
|
||||||
tmpl tpl.Template
|
|
||||||
runMode runmode
|
runMode runmode
|
||||||
|
|
||||||
multilingual *Multilingual
|
multilingual *Multilingual
|
||||||
|
@ -50,7 +49,14 @@ type deps struct {
|
||||||
// The logger to use.
|
// The logger to use.
|
||||||
log *jww.Notepad
|
log *jww.Notepad
|
||||||
|
|
||||||
// TODO(bep) next in line: Viper, hugofs, template
|
tmpl *tpl.GoHTMLTemplate
|
||||||
|
|
||||||
|
// TODO(bep) next in line: Viper, hugofs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deps) refreshTemplates(withTemplate ...func(templ tpl.Template) error) {
|
||||||
|
d.tmpl = tpl.New(d.log, withTemplate...)
|
||||||
|
d.tmpl.PrintErrors() // TODO(bep) globals error handling
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDeps(cfg DepsCfg) *deps {
|
func newDeps(cfg DepsCfg) *deps {
|
||||||
|
@ -59,11 +65,12 @@ func newDeps(cfg DepsCfg) *deps {
|
||||||
if logger == nil {
|
if logger == nil {
|
||||||
// TODO(bep) globals default log level
|
// TODO(bep) globals default log level
|
||||||
//logger = jww.NewNotepad(jww.LevelError, jww.LevelWarn, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
|
//logger = jww.NewNotepad(jww.LevelError, jww.LevelWarn, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
|
||||||
logger = jww.NewNotepad(jww.LevelFatal, jww.LevelFatal, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
|
logger = jww.NewNotepad(jww.LevelError, jww.LevelError, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &deps{
|
return &deps{
|
||||||
log: logger,
|
log: logger,
|
||||||
|
tmpl: tpl.New(logger, cfg.WithTemplate...),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +83,16 @@ func newHugoSites(cfg DepsCfg, sites ...*Site) (*HugoSites, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var d *deps
|
||||||
|
|
||||||
|
if sites[0].deps != nil {
|
||||||
|
d = sites[0].deps
|
||||||
|
} else {
|
||||||
|
d = newDeps(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
h := &HugoSites{
|
h := &HugoSites{
|
||||||
deps: newDeps(cfg),
|
deps: d,
|
||||||
multilingual: langConfig,
|
multilingual: langConfig,
|
||||||
Sites: sites}
|
Sites: sites}
|
||||||
|
|
||||||
|
@ -91,18 +106,24 @@ func newHugoSites(cfg DepsCfg, sites ...*Site) (*HugoSites, error) {
|
||||||
// NewHugoSitesFromConfiguration creates HugoSites from the global Viper config.
|
// NewHugoSitesFromConfiguration creates HugoSites from the global Viper config.
|
||||||
// TODO(bep) globals rename this when all the globals are gone.
|
// TODO(bep) globals rename this when all the globals are gone.
|
||||||
func NewHugoSitesFromConfiguration(cfg DepsCfg) (*HugoSites, error) {
|
func NewHugoSitesFromConfiguration(cfg DepsCfg) (*HugoSites, error) {
|
||||||
sites, err := createSitesFromConfig()
|
sites, err := createSitesFromConfig(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return newHugoSites(cfg, sites...)
|
return newHugoSites(cfg, sites...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSitesFromConfig() ([]*Site, error) {
|
func createSitesFromConfig(cfg DepsCfg) ([]*Site, error) {
|
||||||
|
deps := newDeps(cfg)
|
||||||
|
return createSitesFromDeps(deps)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSitesFromDeps(deps *deps) ([]*Site, error) {
|
||||||
var sites []*Site
|
var sites []*Site
|
||||||
multilingual := viper.GetStringMap("languages")
|
multilingual := viper.GetStringMap("languages")
|
||||||
|
|
||||||
if len(multilingual) == 0 {
|
if len(multilingual) == 0 {
|
||||||
sites = append(sites, newSite(helpers.NewDefaultLanguage()))
|
sites = append(sites, newSite(helpers.NewDefaultLanguage(), deps))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(multilingual) > 0 {
|
if len(multilingual) > 0 {
|
||||||
|
@ -115,7 +136,7 @@ func createSitesFromConfig() ([]*Site, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, lang := range languages {
|
for _, lang := range languages {
|
||||||
sites = append(sites, newSite(lang))
|
sites = append(sites, newSite(lang, deps))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -134,7 +155,7 @@ func (h *HugoSites) reset() {
|
||||||
|
|
||||||
func (h *HugoSites) createSitesFromConfig() error {
|
func (h *HugoSites) createSitesFromConfig() error {
|
||||||
|
|
||||||
sites, err := createSitesFromConfig()
|
sites, err := createSitesFromDeps(h.deps)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -192,6 +213,8 @@ type DepsCfg struct {
|
||||||
|
|
||||||
// The Logger to use.
|
// The Logger to use.
|
||||||
Logger *jww.Notepad
|
Logger *jww.Notepad
|
||||||
|
|
||||||
|
WithTemplate []func(templ tpl.Template) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HugoSites) renderCrossSitesArtifacts() error {
|
func (h *HugoSites) renderCrossSitesArtifacts() error {
|
||||||
|
|
|
@ -40,7 +40,6 @@ import (
|
||||||
bp "github.com/spf13/hugo/bufferpool"
|
bp "github.com/spf13/hugo/bufferpool"
|
||||||
"github.com/spf13/hugo/hugofs"
|
"github.com/spf13/hugo/hugofs"
|
||||||
"github.com/spf13/hugo/source"
|
"github.com/spf13/hugo/source"
|
||||||
"github.com/spf13/hugo/tpl"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1284,7 +1283,7 @@ func (p *Page) Render(layout ...string) template.HTML {
|
||||||
l = p.layouts()
|
l = p.layouts()
|
||||||
}
|
}
|
||||||
|
|
||||||
return tpl.ExecuteTemplateToHTML(p, l...)
|
return p.s.tmpl.ExecuteTemplateToHTML(p, l...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Page) determineMarkupType() string {
|
func (p *Page) determineMarkupType() string {
|
||||||
|
@ -1399,8 +1398,8 @@ func (p *Page) SaveSource() error {
|
||||||
return p.SaveSourceAs(p.FullFilePath())
|
return p.SaveSourceAs(p.FullFilePath())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Page) ProcessShortcodes(t tpl.Template) {
|
func (p *Page) ProcessShortcodes() {
|
||||||
tmpContent, tmpContentShortCodes, _ := extractAndRenderShortcodes(string(p.workContent), p, t)
|
tmpContent, tmpContentShortCodes, _ := extractAndRenderShortcodes(string(p.workContent), p)
|
||||||
p.workContent = []byte(tmpContent)
|
p.workContent = []byte(tmpContent)
|
||||||
p.contentShortCodes = tmpContentShortCodes
|
p.contentShortCodes = tmpContentShortCodes
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,8 +151,8 @@ func (sc shortcode) String() string {
|
||||||
|
|
||||||
// HandleShortcodes does all in one go: extract, render and replace
|
// HandleShortcodes does all in one go: extract, render and replace
|
||||||
// only used for testing
|
// only used for testing
|
||||||
func HandleShortcodes(stringToParse string, page *Page, t tpl.Template) (string, error) {
|
func HandleShortcodes(stringToParse string, page *Page) (string, error) {
|
||||||
tmpContent, tmpShortcodes, err := extractAndRenderShortcodes(stringToParse, page, t)
|
tmpContent, tmpShortcodes, err := extractAndRenderShortcodes(stringToParse, page)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -210,8 +210,8 @@ const innerNewlineRegexp = "\n"
|
||||||
const innerCleanupRegexp = `\A<p>(.*)</p>\n\z`
|
const innerCleanupRegexp = `\A<p>(.*)</p>\n\z`
|
||||||
const innerCleanupExpand = "$1"
|
const innerCleanupExpand = "$1"
|
||||||
|
|
||||||
func renderShortcode(sc shortcode, parent *ShortcodeWithPage, p *Page, t tpl.Template) string {
|
func renderShortcode(sc shortcode, parent *ShortcodeWithPage, p *Page) string {
|
||||||
tmpl := getShortcodeTemplate(sc.name, t)
|
tmpl := getShortcodeTemplate(sc.name, p.s.tmpl)
|
||||||
|
|
||||||
if tmpl == nil {
|
if tmpl == nil {
|
||||||
p.s.log.ERROR.Printf("Unable to locate template for shortcode '%s' in page %s", sc.name, p.BaseFileName())
|
p.s.log.ERROR.Printf("Unable to locate template for shortcode '%s' in page %s", sc.name, p.BaseFileName())
|
||||||
|
@ -230,7 +230,7 @@ func renderShortcode(sc shortcode, parent *ShortcodeWithPage, p *Page, t tpl.Tem
|
||||||
case string:
|
case string:
|
||||||
inner += innerData.(string)
|
inner += innerData.(string)
|
||||||
case shortcode:
|
case shortcode:
|
||||||
inner += renderShortcode(innerData.(shortcode), data, p, t)
|
inner += renderShortcode(innerData.(shortcode), data, p)
|
||||||
default:
|
default:
|
||||||
p.s.log.ERROR.Printf("Illegal state on shortcode rendering of '%s' in page %s. Illegal type in inner data: %s ",
|
p.s.log.ERROR.Printf("Illegal state on shortcode rendering of '%s' in page %s. Illegal type in inner data: %s ",
|
||||||
sc.name, p.BaseFileName(), reflect.TypeOf(innerData))
|
sc.name, p.BaseFileName(), reflect.TypeOf(innerData))
|
||||||
|
@ -280,9 +280,9 @@ func renderShortcode(sc shortcode, parent *ShortcodeWithPage, p *Page, t tpl.Tem
|
||||||
return renderShortcodeWithPage(tmpl, data)
|
return renderShortcodeWithPage(tmpl, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractAndRenderShortcodes(stringToParse string, p *Page, t tpl.Template) (string, map[string]func() (string, error), error) {
|
func extractAndRenderShortcodes(stringToParse string, p *Page) (string, map[string]func() (string, error), error) {
|
||||||
|
|
||||||
content, shortcodes, err := extractShortcodes(stringToParse, p, t)
|
content, shortcodes, err := extractShortcodes(stringToParse, p)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// try to render what we have whilst logging the error
|
// try to render what we have whilst logging the error
|
||||||
|
@ -293,7 +293,7 @@ func extractAndRenderShortcodes(stringToParse string, p *Page, t tpl.Template) (
|
||||||
// TODO(bep) refactor this
|
// TODO(bep) refactor this
|
||||||
p.shortcodes = shortcodes
|
p.shortcodes = shortcodes
|
||||||
|
|
||||||
renderedShortcodes := renderShortcodes(shortcodes, p, t)
|
renderedShortcodes := renderShortcodes(shortcodes, p)
|
||||||
|
|
||||||
return content, renderedShortcodes, err
|
return content, renderedShortcodes, err
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ func executeShortcodeFuncMap(funcs map[string]func() (string, error)) (map[strin
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderShortcodes(shortcodes map[string]shortcode, p *Page, t tpl.Template) map[string]func() (string, error) {
|
func renderShortcodes(shortcodes map[string]shortcode, p *Page) map[string]func() (string, error) {
|
||||||
renderedShortcodes := make(map[string]func() (string, error))
|
renderedShortcodes := make(map[string]func() (string, error))
|
||||||
|
|
||||||
for key, sc := range shortcodes {
|
for key, sc := range shortcodes {
|
||||||
|
@ -324,7 +324,7 @@ func renderShortcodes(shortcodes map[string]shortcode, p *Page, t tpl.Template)
|
||||||
renderedShortcodes[key] = emptyShortcodeFn
|
renderedShortcodes[key] = emptyShortcodeFn
|
||||||
} else {
|
} else {
|
||||||
shorctode := sc
|
shorctode := sc
|
||||||
renderedShortcodes[key] = func() (string, error) { return renderShortcode(shorctode, nil, p, t), nil }
|
renderedShortcodes[key] = func() (string, error) { return renderShortcode(shorctode, nil, p), nil }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ var errShortCodeIllegalState = errors.New("Illegal shortcode state")
|
||||||
// pageTokens state:
|
// pageTokens state:
|
||||||
// - before: positioned just before the shortcode start
|
// - before: positioned just before the shortcode start
|
||||||
// - after: shortcode(s) consumed (plural when they are nested)
|
// - after: shortcode(s) consumed (plural when they are nested)
|
||||||
func extractShortcode(pt *pageTokens, p *Page, t tpl.Template) (shortcode, error) {
|
func extractShortcode(pt *pageTokens, p *Page) (shortcode, error) {
|
||||||
sc := shortcode{}
|
sc := shortcode{}
|
||||||
var isInner = false
|
var isInner = false
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ Loop:
|
||||||
if cnt > 0 {
|
if cnt > 0 {
|
||||||
// nested shortcode; append it to inner content
|
// nested shortcode; append it to inner content
|
||||||
pt.backup3(currItem, next)
|
pt.backup3(currItem, next)
|
||||||
nested, err := extractShortcode(pt, p, t)
|
nested, err := extractShortcode(pt, p)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
sc.inner = append(sc.inner, nested)
|
sc.inner = append(sc.inner, nested)
|
||||||
} else {
|
} else {
|
||||||
|
@ -398,7 +398,7 @@ Loop:
|
||||||
sc.inner = append(sc.inner, currItem.val)
|
sc.inner = append(sc.inner, currItem.val)
|
||||||
case tScName:
|
case tScName:
|
||||||
sc.name = currItem.val
|
sc.name = currItem.val
|
||||||
tmpl := getShortcodeTemplate(sc.name, t)
|
tmpl := getShortcodeTemplate(sc.name, p.s.tmpl)
|
||||||
|
|
||||||
if tmpl == nil {
|
if tmpl == nil {
|
||||||
return sc, fmt.Errorf("Unable to locate template for shortcode '%s' in page %s", sc.name, p.BaseFileName())
|
return sc, fmt.Errorf("Unable to locate template for shortcode '%s' in page %s", sc.name, p.BaseFileName())
|
||||||
|
@ -454,7 +454,7 @@ Loop:
|
||||||
return sc, nil
|
return sc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractShortcodes(stringToParse string, p *Page, t tpl.Template) (string, map[string]shortcode, error) {
|
func extractShortcodes(stringToParse string, p *Page) (string, map[string]shortcode, error) {
|
||||||
|
|
||||||
shortCodes := make(map[string]shortcode)
|
shortCodes := make(map[string]shortcode)
|
||||||
|
|
||||||
|
@ -492,7 +492,7 @@ Loop:
|
||||||
case tLeftDelimScWithMarkup, tLeftDelimScNoMarkup:
|
case tLeftDelimScWithMarkup, tLeftDelimScNoMarkup:
|
||||||
// let extractShortcode handle left delim (will do so recursively)
|
// let extractShortcode handle left delim (will do so recursively)
|
||||||
pt.backup()
|
pt.backup()
|
||||||
if currShortcode, err = extractShortcode(pt, p, t); err != nil {
|
if currShortcode, err = extractShortcode(pt, p); err != nil {
|
||||||
return result.String(), shortCodes, err
|
return result.String(), shortCodes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(bep) remove
|
// TODO(bep) remove
|
||||||
func pageFromString(in, filename string) (*Page, error) {
|
func pageFromString(in, filename string, withTemplate ...func(templ tpl.Template) error) (*Page, error) {
|
||||||
return pageTestSite.NewPageFrom(strings.NewReader(in), filename)
|
s := pageTestSite
|
||||||
|
if len(withTemplate) > 0 {
|
||||||
|
// Have to create a new site
|
||||||
|
s = NewSiteDefaultLang(withTemplate...)
|
||||||
|
}
|
||||||
|
return s.NewPageFrom(strings.NewReader(in), filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.Template) error) {
|
func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.Template) error) {
|
||||||
|
@ -83,10 +88,10 @@ title: "Title"
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShortcodeGoFuzzReports(t *testing.T) {
|
func TestShortcodeGoFuzzReports(t *testing.T) {
|
||||||
tem := tpl.New(logger)
|
|
||||||
|
|
||||||
tem.AddInternalShortcode("sc.html", `foo`)
|
p, _ := pageFromString(simplePage, "simple.md", func(templ tpl.Template) error {
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
return templ.AddInternalShortcode("sc.html", `foo`)
|
||||||
|
})
|
||||||
|
|
||||||
for i, this := range []struct {
|
for i, this := range []struct {
|
||||||
data string
|
data string
|
||||||
|
@ -94,7 +99,7 @@ func TestShortcodeGoFuzzReports(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{"{{</*/", true},
|
{"{{</*/", true},
|
||||||
} {
|
} {
|
||||||
output, err := HandleShortcodes(this.data, p, tem)
|
output, err := HandleShortcodes(this.data, p)
|
||||||
|
|
||||||
if this.expectErr && err == nil {
|
if this.expectErr && err == nil {
|
||||||
t.Errorf("[%d] should have errored", i)
|
t.Errorf("[%d] should have errored", i)
|
||||||
|
@ -304,15 +309,13 @@ func TestHighlight(t *testing.T) {
|
||||||
viper.Set("pygmentsStyle", "bw")
|
viper.Set("pygmentsStyle", "bw")
|
||||||
viper.Set("pygmentsUseClasses", false)
|
viper.Set("pygmentsUseClasses", false)
|
||||||
|
|
||||||
templ := tpl.New(logger)
|
|
||||||
|
|
||||||
code := `
|
code := `
|
||||||
{{< highlight java >}}
|
{{< highlight java >}}
|
||||||
void do();
|
void do();
|
||||||
{{< /highlight >}}`
|
{{< /highlight >}}`
|
||||||
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md")
|
||||||
output, err := HandleShortcodes(code, p, templ)
|
output, err := HandleShortcodes(code, p)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Handle shortcode error", err)
|
t.Fatal("Handle shortcode error", err)
|
||||||
|
@ -379,16 +382,17 @@ func TestExtractShortcodes(t *testing.T) {
|
||||||
fmt.Sprintf("Hello %sworld%s. And that's it.", testScPlaceholderRegexp, testScPlaceholderRegexp), ""},
|
fmt.Sprintf("Hello %sworld%s. And that's it.", testScPlaceholderRegexp, testScPlaceholderRegexp), ""},
|
||||||
} {
|
} {
|
||||||
|
|
||||||
p, _ := pageFromString(simplePage, "simple.md")
|
p, _ := pageFromString(simplePage, "simple.md", func(templ tpl.Template) error {
|
||||||
tem := tpl.New(logger)
|
templ.AddInternalShortcode("tag.html", `tag`)
|
||||||
tem.AddInternalShortcode("tag.html", `tag`)
|
templ.AddInternalShortcode("sc1.html", `sc1`)
|
||||||
tem.AddInternalShortcode("sc1.html", `sc1`)
|
templ.AddInternalShortcode("sc2.html", `sc2`)
|
||||||
tem.AddInternalShortcode("sc2.html", `sc2`)
|
templ.AddInternalShortcode("inner.html", `{{with .Inner }}{{ . }}{{ end }}`)
|
||||||
tem.AddInternalShortcode("inner.html", `{{with .Inner }}{{ . }}{{ end }}`)
|
templ.AddInternalShortcode("inner2.html", `{{.Inner}}`)
|
||||||
tem.AddInternalShortcode("inner2.html", `{{.Inner}}`)
|
templ.AddInternalShortcode("inner3.html", `{{.Inner}}`)
|
||||||
tem.AddInternalShortcode("inner3.html", `{{.Inner}}`)
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
content, shortCodes, err := extractShortcodes(this.input, p, tem)
|
content, shortCodes, err := extractShortcodes(this.input, p)
|
||||||
|
|
||||||
if b, ok := this.expect.(bool); ok && !b {
|
if b, ok := this.expect.(bool); ok && !b {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -115,19 +115,23 @@ func (s *Site) reset() *Site {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newSite creates a new site in the given language.
|
// newSite creates a new site in the given language.
|
||||||
func newSite(lang *helpers.Language) *Site {
|
func newSite(lang *helpers.Language, deps *deps, withTemplate ...func(templ tpl.Template) error) *Site {
|
||||||
c := newPageCollections()
|
c := newPageCollections()
|
||||||
// TODO(bep) globals (also see other Site creation places)
|
|
||||||
deps := newDeps(DepsCfg{})
|
|
||||||
// TODO(bep) globals
|
// TODO(bep) globals
|
||||||
viper.Set("currentContentLanguage", lang)
|
viper.Set("currentContentLanguage", lang)
|
||||||
|
|
||||||
|
if deps == nil {
|
||||||
|
depsCfg := DepsCfg{WithTemplate: withTemplate}
|
||||||
|
deps = newDeps(depsCfg)
|
||||||
|
}
|
||||||
|
|
||||||
return &Site{deps: deps, Language: lang, PageCollections: c, Info: newSiteInfo(siteBuilderCfg{pageCollections: c, language: lang})}
|
return &Site{deps: deps, Language: lang, PageCollections: c, Info: newSiteInfo(siteBuilderCfg{pageCollections: c, language: lang})}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSiteDefaultLang creates a new site in the default language.
|
// NewSiteDefaultLang creates a new site in the default language.
|
||||||
func NewSiteDefaultLang() *Site {
|
func NewSiteDefaultLang(withTemplate ...func(templ tpl.Template) error) *Site {
|
||||||
return newSite(helpers.NewDefaultLanguage())
|
return newSite(helpers.NewDefaultLanguage(), nil, withTemplate...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience func used in tests.
|
// Convenience func used in tests.
|
||||||
|
@ -656,24 +660,23 @@ func (s *Site) reProcess(events []fsnotify.Event) (whatChanged, error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) loadTemplates() {
|
|
||||||
s.owner.tmpl = tpl.InitializeT(s.log)
|
|
||||||
s.owner.tmpl.LoadTemplates(s.absLayoutDir())
|
|
||||||
if s.hasTheme() {
|
|
||||||
s.owner.tmpl.LoadTemplatesWithPrefix(s.absThemeDir()+"/layouts", "theme")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Site) prepTemplates(withTemplate func(templ tpl.Template) error) error {
|
func (s *Site) prepTemplates(withTemplate func(templ tpl.Template) error) error {
|
||||||
s.loadTemplates()
|
|
||||||
|
|
||||||
if withTemplate != nil {
|
wt := func(tmpl tpl.Template) error {
|
||||||
if err := withTemplate(s.owner.tmpl); err != nil {
|
// TODO(bep) global error handling
|
||||||
return err
|
tmpl.LoadTemplates(s.absLayoutDir())
|
||||||
|
if s.hasTheme() {
|
||||||
|
tmpl.LoadTemplatesWithPrefix(s.absThemeDir()+"/layouts", "theme")
|
||||||
}
|
}
|
||||||
|
if withTemplate != nil {
|
||||||
|
if err := withTemplate(tmpl); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.owner.tmpl.MarkReady()
|
s.refreshTemplates(wt)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -778,6 +781,7 @@ func (s *Site) process(config BuildCfg) (err error) {
|
||||||
if err = s.initialize(); err != nil {
|
if err = s.initialize(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.prepTemplates(config.withTemplate)
|
s.prepTemplates(config.withTemplate)
|
||||||
s.owner.tmpl.PrintErrors()
|
s.owner.tmpl.PrintErrors()
|
||||||
s.timerStep("initialize & template prep")
|
s.timerStep("initialize & template prep")
|
||||||
|
|
|
@ -109,8 +109,13 @@ func TestRenderWithInvalidTemplate(t *testing.T) {
|
||||||
t.Fatalf("Got build error: %s", err)
|
t.Fatalf("Got build error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.log.LogCountForLevelsGreaterThanorEqualTo(jww.LevelError) != 1 {
|
errCount := s.log.LogCountForLevelsGreaterThanorEqualTo(jww.LevelError)
|
||||||
t.Fatalf("Expecting the template to log an ERROR")
|
|
||||||
|
// TODO(bep) globals clean up the template error handling
|
||||||
|
// The template errors are stored in a slice etc. so we get 4 log entries
|
||||||
|
// When we should get only 1
|
||||||
|
if errCount == 0 {
|
||||||
|
t.Fatalf("Expecting the template to log 1 ERROR, got %d", errCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,8 @@ import (
|
||||||
"github.com/yosssi/ace"
|
"github.com/yosssi/ace"
|
||||||
)
|
)
|
||||||
|
|
||||||
var localTemplates *template.Template
|
// TODO(bep) globals get rid of the rest of the jww.ERR etc.
|
||||||
|
//var tmpl *GoHTMLTemplate
|
||||||
// TODO(bep) globals get rid of the reset of the jww.ERR etc.
|
|
||||||
var tmpl *GoHTMLTemplate
|
|
||||||
|
|
||||||
// TODO(bep) an interface with hundreds of methods ... remove it.
|
// TODO(bep) an interface with hundreds of methods ... remove it.
|
||||||
// And unexport most of these methods.
|
// And unexport most of these methods.
|
||||||
|
@ -45,13 +43,13 @@ type Template interface {
|
||||||
GetClone() *template.Template
|
GetClone() *template.Template
|
||||||
LoadTemplates(absPath string)
|
LoadTemplates(absPath string)
|
||||||
LoadTemplatesWithPrefix(absPath, prefix string)
|
LoadTemplatesWithPrefix(absPath, prefix string)
|
||||||
MarkReady()
|
|
||||||
AddTemplate(name, tpl string) error
|
AddTemplate(name, tpl string) error
|
||||||
AddTemplateFileWithMaster(name, overlayFilename, masterFilename string) error
|
AddTemplateFileWithMaster(name, overlayFilename, masterFilename string) error
|
||||||
AddAceTemplate(name, basePath, innerPath string, baseContent, innerContent []byte) error
|
AddAceTemplate(name, basePath, innerPath string, baseContent, innerContent []byte) error
|
||||||
AddInternalTemplate(prefix, name, tpl string) error
|
AddInternalTemplate(prefix, name, tpl string) error
|
||||||
AddInternalShortcode(name, tpl string) error
|
AddInternalShortcode(name, tpl string) error
|
||||||
PrintErrors()
|
PrintErrors()
|
||||||
|
Funcs(funcMap template.FuncMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
type templateErr struct {
|
type templateErr struct {
|
||||||
|
@ -60,7 +58,8 @@ type templateErr struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GoHTMLTemplate struct {
|
type GoHTMLTemplate struct {
|
||||||
template.Template
|
*template.Template
|
||||||
|
|
||||||
clone *template.Template
|
clone *template.Template
|
||||||
|
|
||||||
// a separate storage for the overlays created from cloned master templates.
|
// a separate storage for the overlays created from cloned master templates.
|
||||||
|
@ -69,41 +68,54 @@ type GoHTMLTemplate struct {
|
||||||
|
|
||||||
errors []*templateErr
|
errors []*templateErr
|
||||||
|
|
||||||
|
funcster *templateFuncster
|
||||||
|
|
||||||
// TODO(bep) globals template
|
// TODO(bep) globals template
|
||||||
log *jww.Notepad
|
log *jww.Notepad
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitializeT resets the internal template state to its initial state
|
|
||||||
func InitializeT(logger *jww.Notepad) *GoHTMLTemplate {
|
|
||||||
tmpl = New(logger)
|
|
||||||
return tmpl
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new Hugo Template System
|
// New returns a new Hugo Template System
|
||||||
// with all the additional features, templates & functions
|
// with all the additional features, templates & functions
|
||||||
func New(logger *jww.Notepad) *GoHTMLTemplate {
|
func New(logger *jww.Notepad, withTemplate ...func(templ Template) error) *GoHTMLTemplate {
|
||||||
var templates = &GoHTMLTemplate{
|
tmpl := &GoHTMLTemplate{
|
||||||
Template: *template.New(""),
|
Template: template.New(""),
|
||||||
overlays: make(map[string]*template.Template),
|
overlays: make(map[string]*template.Template),
|
||||||
errors: make([]*templateErr, 0),
|
errors: make([]*templateErr, 0),
|
||||||
log: logger,
|
log: logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
localTemplates = &templates.Template
|
tmpl.funcster = newTemplateFuncster(tmpl)
|
||||||
|
|
||||||
// The URL funcs in the funcMap is somewhat language dependent,
|
// The URL funcs in the funcMap is somewhat language dependent,
|
||||||
// so we need to wait until the language and site config is loaded.
|
// so we need to wait until the language and site config is loaded.
|
||||||
initFuncMap()
|
// TODO(bep) globals
|
||||||
|
tmpl.funcster.initFuncMap()
|
||||||
|
|
||||||
for k, v := range funcMap {
|
// TODO(bep) globals
|
||||||
|
for k, v := range tmpl.funcster.funcMap {
|
||||||
amber.FuncMap[k] = v
|
amber.FuncMap[k] = v
|
||||||
}
|
}
|
||||||
templates.Funcs(funcMap)
|
|
||||||
templates.LoadEmbedded()
|
tmpl.LoadEmbedded()
|
||||||
return templates
|
|
||||||
|
for _, wt := range withTemplate {
|
||||||
|
err := wt(tmpl)
|
||||||
|
if err != nil {
|
||||||
|
tmpl.errors = append(tmpl.errors, &templateErr{"init", err})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl.markReady()
|
||||||
|
|
||||||
|
return tmpl
|
||||||
}
|
}
|
||||||
|
|
||||||
func partial(name string, contextList ...interface{}) template.HTML {
|
func (t *GoHTMLTemplate) Funcs(funcMap template.FuncMap) {
|
||||||
|
t.Template.Funcs(funcMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GoHTMLTemplate) partial(name string, contextList ...interface{}) template.HTML {
|
||||||
if strings.HasPrefix("partials/", name) {
|
if strings.HasPrefix("partials/", name) {
|
||||||
name = name[8:]
|
name = name[8:]
|
||||||
}
|
}
|
||||||
|
@ -114,16 +126,16 @@ func partial(name string, contextList ...interface{}) template.HTML {
|
||||||
} else {
|
} else {
|
||||||
context = contextList[0]
|
context = contextList[0]
|
||||||
}
|
}
|
||||||
return ExecuteTemplateToHTML(context, "partials/"+name, "theme/partials/"+name)
|
return t.ExecuteTemplateToHTML(context, "partials/"+name, "theme/partials/"+name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeTemplate(context interface{}, w io.Writer, layouts ...string) {
|
func (t *GoHTMLTemplate) executeTemplate(context interface{}, w io.Writer, layouts ...string) {
|
||||||
var worked bool
|
var worked bool
|
||||||
for _, layout := range layouts {
|
for _, layout := range layouts {
|
||||||
templ := Lookup(layout)
|
templ := t.Lookup(layout)
|
||||||
if templ == nil {
|
if templ == nil {
|
||||||
layout += ".html"
|
layout += ".html"
|
||||||
templ = Lookup(layout)
|
templ = t.Lookup(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if templ != nil {
|
if templ != nil {
|
||||||
|
@ -136,28 +148,20 @@ func executeTemplate(context interface{}, w io.Writer, layouts ...string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !worked {
|
if !worked {
|
||||||
tmpl.log.ERROR.Println("Unable to render", layouts)
|
t.log.ERROR.Println("Unable to render", layouts)
|
||||||
tmpl.log.ERROR.Println("Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations", layouts)
|
t.log.ERROR.Println("Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations", layouts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExecuteTemplateToHTML(context interface{}, layouts ...string) template.HTML {
|
func (t *GoHTMLTemplate) ExecuteTemplateToHTML(context interface{}, layouts ...string) template.HTML {
|
||||||
b := bp.GetBuffer()
|
b := bp.GetBuffer()
|
||||||
defer bp.PutBuffer(b)
|
defer bp.PutBuffer(b)
|
||||||
executeTemplate(context, b, layouts...)
|
t.executeTemplate(context, b, layouts...)
|
||||||
return template.HTML(b.String())
|
return template.HTML(b.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Lookup(name string) *template.Template {
|
|
||||||
return tmpl.Lookup(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *GoHTMLTemplate) Lookup(name string) *template.Template {
|
func (t *GoHTMLTemplate) Lookup(name string) *template.Template {
|
||||||
|
|
||||||
if templ := localTemplates.Lookup(name); templ != nil {
|
|
||||||
return templ
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.overlays != nil {
|
if t.overlays != nil {
|
||||||
if templ, ok := t.overlays[name]; ok {
|
if templ, ok := t.overlays[name]; ok {
|
||||||
return templ
|
return templ
|
||||||
|
@ -183,9 +187,9 @@ func (t *GoHTMLTemplate) LoadEmbedded() {
|
||||||
t.EmbedTemplates()
|
t.EmbedTemplates()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkReady marks the template as "ready for execution". No changes allowed
|
// markReady marks the template as "ready for execution". No changes allowed
|
||||||
// after this is set.
|
// after this is set.
|
||||||
func (t *GoHTMLTemplate) MarkReady() {
|
func (t *GoHTMLTemplate) markReady() {
|
||||||
if t.clone == nil {
|
if t.clone == nil {
|
||||||
t.clone = template.Must(t.Template.Clone())
|
t.clone = template.Must(t.Template.Clone())
|
||||||
}
|
}
|
||||||
|
@ -522,7 +526,7 @@ func (t *GoHTMLTemplate) LoadTemplates(absPath string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GoHTMLTemplate) PrintErrors() {
|
func (t *GoHTMLTemplate) PrintErrors() {
|
||||||
for _, e := range t.errors {
|
for i, e := range t.errors {
|
||||||
t.log.ERROR.Println(e.err)
|
t.log.ERROR.Println(i, ":", e.err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ import (
|
||||||
|
|
||||||
"html/template"
|
"html/template"
|
||||||
|
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -265,7 +264,3 @@ P2: {{ .Params.LOWER }}
|
||||||
require.Contains(t, result, "P1: P1L")
|
require.Contains(t, result, "P1: P1L")
|
||||||
require.Contains(t, result, "P2: P1L")
|
require.Contains(t, result, "P2: P1L")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
jww.SetStdoutThreshold(jww.LevelCritical)
|
|
||||||
}
|
|
||||||
|
|
|
@ -54,9 +54,19 @@ import (
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// Some of the template funcs are'nt entirely stateless.
|
||||||
funcMap template.FuncMap
|
type templateFuncster struct {
|
||||||
)
|
t *GoHTMLTemplate
|
||||||
|
funcMap template.FuncMap
|
||||||
|
cachedPartials partialCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTemplateFuncster(t *GoHTMLTemplate) *templateFuncster {
|
||||||
|
return &templateFuncster{
|
||||||
|
t: t,
|
||||||
|
cachedPartials: partialCache{p: make(map[string]template.HTML)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// eq returns the boolean truth of arg1 == arg2.
|
// eq returns the boolean truth of arg1 == arg2.
|
||||||
func eq(x, y interface{}) bool {
|
func eq(x, y interface{}) bool {
|
||||||
|
@ -1003,7 +1013,7 @@ func where(seq, key interface{}, args ...interface{}) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply takes a map, array, or slice and returns a new slice with the function fname applied over it.
|
// apply takes a map, array, or slice and returns a new slice with the function fname applied over it.
|
||||||
func apply(seq interface{}, fname string, args ...interface{}) (interface{}, error) {
|
func (tf *templateFuncster) apply(seq interface{}, fname string, args ...interface{}) (interface{}, error) {
|
||||||
if seq == nil {
|
if seq == nil {
|
||||||
return make([]interface{}, 0), nil
|
return make([]interface{}, 0), nil
|
||||||
}
|
}
|
||||||
|
@ -1018,7 +1028,7 @@ func apply(seq interface{}, fname string, args ...interface{}) (interface{}, err
|
||||||
return nil, errors.New("can't iterate over a nil value")
|
return nil, errors.New("can't iterate over a nil value")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn, found := funcMap[fname]
|
fn, found := tf.funcMap[fname]
|
||||||
if !found {
|
if !found {
|
||||||
return nil, errors.New("can't find function " + fname)
|
return nil, errors.New("can't find function " + fname)
|
||||||
}
|
}
|
||||||
|
@ -1518,41 +1528,39 @@ type partialCache struct {
|
||||||
// Get retrieves partial output from the cache based upon the partial name.
|
// Get retrieves partial output from the cache based upon the partial name.
|
||||||
// If the partial is not found in the cache, the partial is rendered and added
|
// If the partial is not found in the cache, the partial is rendered and added
|
||||||
// to the cache.
|
// to the cache.
|
||||||
func (c *partialCache) Get(key, name string, context interface{}) (p template.HTML) {
|
func (tf *templateFuncster) Get(key, name string, context interface{}) (p template.HTML) {
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
c.RLock()
|
tf.cachedPartials.RLock()
|
||||||
p, ok = c.p[key]
|
p, ok = tf.cachedPartials.p[key]
|
||||||
c.RUnlock()
|
tf.cachedPartials.RUnlock()
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Lock()
|
tf.cachedPartials.Lock()
|
||||||
if p, ok = c.p[key]; !ok {
|
if p, ok = tf.cachedPartials.p[key]; !ok {
|
||||||
p = partial(name, context)
|
p = tf.t.partial(name, context)
|
||||||
c.p[key] = p
|
tf.cachedPartials.p[key] = p
|
||||||
}
|
}
|
||||||
c.Unlock()
|
tf.cachedPartials.Unlock()
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
var cachedPartials = partialCache{p: make(map[string]template.HTML)}
|
|
||||||
|
|
||||||
// partialCached executes and caches partial templates. An optional variant
|
// partialCached executes and caches partial templates. An optional variant
|
||||||
// string parameter (a string slice actually, but be only use a variadic
|
// string parameter (a string slice actually, but be only use a variadic
|
||||||
// argument to make it optional) can be passed so that a given partial can have
|
// argument to make it optional) can be passed so that a given partial can have
|
||||||
// multiple uses. The cache is created with name+variant as the key.
|
// multiple uses. The cache is created with name+variant as the key.
|
||||||
func partialCached(name string, context interface{}, variant ...string) template.HTML {
|
func (tf *templateFuncster) partialCached(name string, context interface{}, variant ...string) template.HTML {
|
||||||
key := name
|
key := name
|
||||||
if len(variant) > 0 {
|
if len(variant) > 0 {
|
||||||
for i := 0; i < len(variant); i++ {
|
for i := 0; i < len(variant); i++ {
|
||||||
key += variant[i]
|
key += variant[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cachedPartials.Get(key, name, context)
|
return tf.Get(key, name, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// regexpCache represents a cache of regexp objects protected by a mutex.
|
// regexpCache represents a cache of regexp objects protected by a mutex.
|
||||||
|
@ -2090,8 +2098,8 @@ func getenv(key interface{}) (string, error) {
|
||||||
return os.Getenv(skey), nil
|
return os.Getenv(skey), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func initFuncMap() {
|
func (tf *templateFuncster) initFuncMap() {
|
||||||
funcMap = template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"absURL": absURL,
|
"absURL": absURL,
|
||||||
"absLangURL": func(i interface{}) (template.HTML, error) {
|
"absLangURL": func(i interface{}) (template.HTML, error) {
|
||||||
s, err := cast.ToStringE(i)
|
s, err := cast.ToStringE(i)
|
||||||
|
@ -2102,7 +2110,7 @@ func initFuncMap() {
|
||||||
},
|
},
|
||||||
"add": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '+') },
|
"add": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '+') },
|
||||||
"after": after,
|
"after": after,
|
||||||
"apply": apply,
|
"apply": tf.apply,
|
||||||
"base64Decode": base64Decode,
|
"base64Decode": base64Decode,
|
||||||
"base64Encode": base64Encode,
|
"base64Encode": base64Encode,
|
||||||
"chomp": chomp,
|
"chomp": chomp,
|
||||||
|
@ -2147,8 +2155,8 @@ func initFuncMap() {
|
||||||
"mul": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '*') },
|
"mul": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '*') },
|
||||||
"ne": ne,
|
"ne": ne,
|
||||||
"now": func() time.Time { return time.Now() },
|
"now": func() time.Time { return time.Now() },
|
||||||
"partial": partial,
|
"partial": tf.t.partial,
|
||||||
"partialCached": partialCached,
|
"partialCached": tf.partialCached,
|
||||||
"plainify": plainify,
|
"plainify": plainify,
|
||||||
"pluralize": pluralize,
|
"pluralize": pluralize,
|
||||||
"querify": querify,
|
"querify": querify,
|
||||||
|
@ -2195,4 +2203,7 @@ func initFuncMap() {
|
||||||
"i18n": i18nTranslate,
|
"i18n": i18nTranslate,
|
||||||
"T": i18nTranslate,
|
"T": i18nTranslate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tf.funcMap = funcMap
|
||||||
|
tf.t.Funcs(funcMap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1960,40 +1960,43 @@ func TestMarkdownify(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApply(t *testing.T) {
|
func TestApply(t *testing.T) {
|
||||||
|
|
||||||
|
f := newTestFuncster()
|
||||||
|
|
||||||
strings := []interface{}{"a\n", "b\n"}
|
strings := []interface{}{"a\n", "b\n"}
|
||||||
noStringers := []interface{}{tstNoStringer{}, tstNoStringer{}}
|
noStringers := []interface{}{tstNoStringer{}, tstNoStringer{}}
|
||||||
|
|
||||||
chomped, _ := apply(strings, "chomp", ".")
|
chomped, _ := f.apply(strings, "chomp", ".")
|
||||||
assert.Equal(t, []interface{}{template.HTML("a"), template.HTML("b")}, chomped)
|
assert.Equal(t, []interface{}{template.HTML("a"), template.HTML("b")}, chomped)
|
||||||
|
|
||||||
chomped, _ = apply(strings, "chomp", "c\n")
|
chomped, _ = f.apply(strings, "chomp", "c\n")
|
||||||
assert.Equal(t, []interface{}{template.HTML("c"), template.HTML("c")}, chomped)
|
assert.Equal(t, []interface{}{template.HTML("c"), template.HTML("c")}, chomped)
|
||||||
|
|
||||||
chomped, _ = apply(nil, "chomp", ".")
|
chomped, _ = f.apply(nil, "chomp", ".")
|
||||||
assert.Equal(t, []interface{}{}, chomped)
|
assert.Equal(t, []interface{}{}, chomped)
|
||||||
|
|
||||||
_, err := apply(strings, "apply", ".")
|
_, err := f.apply(strings, "apply", ".")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("apply with apply should fail")
|
t.Errorf("apply with apply should fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
var nilErr *error
|
var nilErr *error
|
||||||
_, err = apply(nilErr, "chomp", ".")
|
_, err = f.apply(nilErr, "chomp", ".")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("apply with nil in seq should fail")
|
t.Errorf("apply with nil in seq should fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = apply(strings, "dobedobedo", ".")
|
_, err = f.apply(strings, "dobedobedo", ".")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("apply with unknown func should fail")
|
t.Errorf("apply with unknown func should fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = apply(noStringers, "chomp", ".")
|
_, err = f.apply(noStringers, "chomp", ".")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("apply when func fails should fail")
|
t.Errorf("apply when func fails should fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = apply(tstNoStringer{}, "chomp", ".")
|
_, err = f.apply(tstNoStringer{}, "chomp", ".")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("apply with non-sequence should fail")
|
t.Errorf("apply with non-sequence should fail")
|
||||||
}
|
}
|
||||||
|
@ -2780,7 +2783,6 @@ func TestPartialCached(t *testing.T) {
|
||||||
data.Params = map[string]interface{}{"langCode": "en"}
|
data.Params = map[string]interface{}{"langCode": "en"}
|
||||||
|
|
||||||
tstInitTemplates()
|
tstInitTemplates()
|
||||||
InitializeT(logger)
|
|
||||||
for i, tc := range testCases {
|
for i, tc := range testCases {
|
||||||
var tmp string
|
var tmp string
|
||||||
if tc.variant != "" {
|
if tc.variant != "" {
|
||||||
|
@ -2831,7 +2833,6 @@ func TestPartialCached(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPartial(b *testing.B) {
|
func BenchmarkPartial(b *testing.B) {
|
||||||
InitializeT(logger)
|
|
||||||
tmpl, err := New(logger).New("testroot").Parse(`{{ partial "bench1" . }}`)
|
tmpl, err := New(logger).New("testroot").Parse(`{{ partial "bench1" . }}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("unable to create new html template: %s", err)
|
b.Fatalf("unable to create new html template: %s", err)
|
||||||
|
@ -2851,7 +2852,6 @@ func BenchmarkPartial(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPartialCached(b *testing.B) {
|
func BenchmarkPartialCached(b *testing.B) {
|
||||||
InitializeT(logger)
|
|
||||||
tmpl, err := New(logger).New("testroot").Parse(`{{ partialCached "bench1" . }}`)
|
tmpl, err := New(logger).New("testroot").Parse(`{{ partialCached "bench1" . }}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("unable to create new html template: %s", err)
|
b.Fatalf("unable to create new html template: %s", err)
|
||||||
|
@ -2871,7 +2871,6 @@ func BenchmarkPartialCached(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPartialCachedVariants(b *testing.B) {
|
func BenchmarkPartialCachedVariants(b *testing.B) {
|
||||||
InitializeT(logger)
|
|
||||||
tmpl, err := New(logger).New("testroot").Parse(`{{ partialCached "bench1" . "header" }}`)
|
tmpl, err := New(logger).New("testroot").Parse(`{{ partialCached "bench1" . "header" }}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("unable to create new html template: %s", err)
|
b.Fatalf("unable to create new html template: %s", err)
|
||||||
|
@ -2889,3 +2888,7 @@ func BenchmarkPartialCachedVariants(b *testing.B) {
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newTestFuncster() *templateFuncster {
|
||||||
|
return New(logger).funcster
|
||||||
|
}
|
||||||
|
|
|
@ -55,8 +55,6 @@ html lang=en
|
||||||
|
|
||||||
for _, root := range []string{"", os.TempDir()} {
|
for _, root := range []string{"", os.TempDir()} {
|
||||||
|
|
||||||
templ := New(logger)
|
|
||||||
|
|
||||||
basePath := this.basePath
|
basePath := this.basePath
|
||||||
innerPath := this.innerPath
|
innerPath := this.innerPath
|
||||||
|
|
||||||
|
@ -70,17 +68,20 @@ html lang=en
|
||||||
|
|
||||||
d := "DATA"
|
d := "DATA"
|
||||||
|
|
||||||
err := templ.AddAceTemplate("mytemplate.ace", basePath, innerPath,
|
templ := New(logger, func(templ Template) error {
|
||||||
[]byte(this.baseContent), []byte(this.innerContent))
|
return templ.AddAceTemplate("mytemplate.ace", basePath, innerPath,
|
||||||
|
[]byte(this.baseContent), []byte(this.innerContent))
|
||||||
|
|
||||||
if err != nil && this.expectErr == 0 {
|
})
|
||||||
t.Errorf("Test %d with root '%s' errored: %s", i, root, err)
|
|
||||||
} else if err == nil && this.expectErr == 1 {
|
if len(templ.errors) > 0 && this.expectErr == 0 {
|
||||||
|
t.Errorf("Test %d with root '%s' errored: %v", i, root, templ.errors)
|
||||||
|
} else if len(templ.errors) == 0 && this.expectErr == 1 {
|
||||||
t.Errorf("#1 Test %d with root '%s' should have errored", i, root)
|
t.Errorf("#1 Test %d with root '%s' should have errored", i, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
var buff bytes.Buffer
|
var buff bytes.Buffer
|
||||||
err = templ.ExecuteTemplate(&buff, "mytemplate.html", d)
|
err := templ.ExecuteTemplate(&buff, "mytemplate.html", d)
|
||||||
|
|
||||||
if err != nil && this.expectErr == 0 {
|
if err != nil && this.expectErr == 0 {
|
||||||
t.Errorf("Test %d with root '%s' errored: %s", i, root, err)
|
t.Errorf("Test %d with root '%s' errored: %s", i, root, err)
|
||||||
|
@ -245,7 +246,6 @@ func TestTplGoFuzzReports(t *testing.T) {
|
||||||
// Issue #1095
|
// Issue #1095
|
||||||
{"{{apply .C \"urlize\" " +
|
{"{{apply .C \"urlize\" " +
|
||||||
"\".\"}}", 2}} {
|
"\".\"}}", 2}} {
|
||||||
templ := New(logger)
|
|
||||||
|
|
||||||
d := &Data{
|
d := &Data{
|
||||||
A: 42,
|
A: 42,
|
||||||
|
@ -258,15 +258,17 @@ func TestTplGoFuzzReports(t *testing.T) {
|
||||||
H: "a,b,c,d,e,f",
|
H: "a,b,c,d,e,f",
|
||||||
}
|
}
|
||||||
|
|
||||||
err := templ.AddTemplate("fuzz", this.data)
|
templ := New(logger, func(templ Template) error {
|
||||||
|
return templ.AddTemplate("fuzz", this.data)
|
||||||
|
|
||||||
if err != nil && this.expectErr == 0 {
|
})
|
||||||
t.Fatalf("Test %d errored: %s", i, err)
|
|
||||||
} else if err == nil && this.expectErr == 1 {
|
if len(templ.errors) > 0 && this.expectErr == 0 {
|
||||||
t.Fatalf("#1 Test %d should have errored", i)
|
t.Errorf("Test %d errored: %v", i, templ.errors)
|
||||||
|
} else if len(templ.errors) == 0 && this.expectErr == 1 {
|
||||||
|
t.Errorf("#1 Test %d should have errored", i)
|
||||||
}
|
}
|
||||||
|
err := templ.ExecuteTemplate(ioutil.Discard, "fuzz", d)
|
||||||
err = templ.ExecuteTemplate(ioutil.Discard, "fuzz", d)
|
|
||||||
|
|
||||||
if err != nil && this.expectErr == 0 {
|
if err != nil && this.expectErr == 0 {
|
||||||
t.Fatalf("Test %d errored: %s", i, err)
|
t.Fatalf("Test %d errored: %s", i, err)
|
||||||
|
|
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
|
@ -281,10 +281,10 @@
|
||||||
"revisionTime": "2016-11-30T04:45:28Z"
|
"revisionTime": "2016-11-30T04:45:28Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "HWDERqbEvvfLwzP7Dvh2fvu+sng=",
|
"checksumSHA1": "9pkkhgKp3mwSreiML3plQlQYdLQ=",
|
||||||
"path": "github.com/spf13/jwalterweatherman",
|
"path": "github.com/spf13/jwalterweatherman",
|
||||||
"revision": "bccdd23ae5e51bd2b081814db093646c7af3d34d",
|
"revision": "fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66",
|
||||||
"revisionTime": "2017-01-05T10:55:09Z"
|
"revisionTime": "2017-01-09T13:33:55Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "zLJY+lsX1e5OO6gRxQd5RfKgdQY=",
|
"checksumSHA1": "zLJY+lsX1e5OO6gRxQd5RfKgdQY=",
|
||||||
|
|
Loading…
Reference in a new issue