mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
New targets & new renderers and write methods [WIP]
This commit is contained in:
parent
e02dc6742a
commit
7b960ac121
5 changed files with 195 additions and 119 deletions
|
@ -24,23 +24,23 @@ func (s *Site) ShowPlan(out io.Writer) (err error) {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "\n")
|
fmt.Fprintf(out, "\n")
|
||||||
fmt.Fprintf(out, " canonical => ")
|
fmt.Fprintf(out, " canonical => ")
|
||||||
if s.Target == nil {
|
if s.Targets.Page == nil {
|
||||||
fmt.Fprintf(out, "%s\n\n", "!no target specified!")
|
fmt.Fprintf(out, "%s\n\n", "!no target specified!")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
trns, err := s.Target.Translate(p.TargetPath())
|
trns, err := s.PageTarget().Translate(p.TargetPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "%s\n", trns)
|
fmt.Fprintf(out, "%s\n", trns)
|
||||||
|
|
||||||
if s.Alias == nil {
|
if s.Targets.Alias == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, alias := range p.Aliases {
|
for _, alias := range p.Aliases {
|
||||||
aliasTrans, err := s.Alias.Translate(alias)
|
aliasTrans, err := s.AliasTarget().Translate(alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
176
hugolib/site.go
176
hugolib/site.go
|
@ -69,8 +69,7 @@ type Site struct {
|
||||||
Shortcodes map[string]ShortcodeFunc
|
Shortcodes map[string]ShortcodeFunc
|
||||||
Menus Menus
|
Menus Menus
|
||||||
timer *nitro.B
|
timer *nitro.B
|
||||||
Target target.Output
|
Targets targetList
|
||||||
Alias target.AliasPublisher
|
|
||||||
Completed chan bool
|
Completed chan bool
|
||||||
RunMode runmode
|
RunMode runmode
|
||||||
params map[string]interface{}
|
params map[string]interface{}
|
||||||
|
@ -78,6 +77,12 @@ type Site struct {
|
||||||
futureCount int
|
futureCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type targetList struct {
|
||||||
|
Page target.Output
|
||||||
|
File target.Output
|
||||||
|
Alias target.AliasPublisher
|
||||||
|
}
|
||||||
|
|
||||||
type SiteInfo struct {
|
type SiteInfo struct {
|
||||||
BaseUrl template.URL
|
BaseUrl template.URL
|
||||||
Taxonomies TaxonomyList
|
Taxonomies TaxonomyList
|
||||||
|
@ -157,10 +162,6 @@ func (s *Site) Build() (err error) {
|
||||||
|
|
||||||
func (s *Site) Analyze() {
|
func (s *Site) Analyze() {
|
||||||
s.Process()
|
s.Process()
|
||||||
s.initTarget()
|
|
||||||
s.Alias = &target.HTMLRedirectAlias{
|
|
||||||
PublishDir: s.absPublishDir(),
|
|
||||||
}
|
|
||||||
s.ShowPlan(os.Stdout)
|
s.ShowPlan(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,7 +672,7 @@ func (s *Site) RenderAliases() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := s.WriteAlias(a, template.HTML(plink)); err != nil {
|
if err := s.WriteDestAlias(a, template.HTML(plink)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -733,7 +734,12 @@ func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.Wa
|
||||||
layouts = append(layouts, "_default/single.html")
|
layouts = append(layouts, "_default/single.html")
|
||||||
}
|
}
|
||||||
|
|
||||||
results <- s.render("page "+p.FullFilePath(), p, p.TargetPath(), s.appendThemeTemplates(layouts)...)
|
b, err := s.renderPage("page "+p.FullFilePath(), p, s.appendThemeTemplates(layouts)...)
|
||||||
|
if err != nil {
|
||||||
|
results <- err
|
||||||
|
} else {
|
||||||
|
results <- s.WriteDestPage(p.TargetPath(), b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,23 +849,32 @@ func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error,
|
||||||
for t := range taxes {
|
for t := range taxes {
|
||||||
n, base := s.newTaxonomyNode(t)
|
n, base := s.newTaxonomyNode(t)
|
||||||
layouts := []string{"taxonomy/" + t.singular + ".html", "indexes/" + t.singular + ".html", "_default/taxonomy.html", "_default/list.html"}
|
layouts := []string{"taxonomy/" + t.singular + ".html", "indexes/" + t.singular + ".html", "_default/taxonomy.html", "_default/list.html"}
|
||||||
err := s.render("taxononomy "+t.singular, n, base+".html", s.appendThemeTemplates(layouts)...)
|
b, err := s.renderPage("taxononomy "+t.singular, n, s.appendThemeTemplates(layouts)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
results <- err
|
results <- err
|
||||||
continue
|
continue
|
||||||
|
} else {
|
||||||
|
err := s.WriteDestPage(base+".html", b)
|
||||||
|
if err != nil {
|
||||||
|
results <- err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !viper.GetBool("DisableRSS") {
|
if !viper.GetBool("DisableRSS") {
|
||||||
// XML Feed
|
// XML Feed
|
||||||
s.setUrls(n, base+".xml")
|
s.setUrls(n, base+".xml")
|
||||||
rssLayouts := []string{"taxonomy/" + t.singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
rssLayouts := []string{"taxonomy/" + t.singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
||||||
err := s.render("taxonomy "+t.singular+" rss", n, base+".xml", s.appendThemeTemplates(rssLayouts)...)
|
b, err := s.renderXML("taxonomy "+t.singular+" rss", n, s.appendThemeTemplates(rssLayouts)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
results <- err
|
results <- err
|
||||||
continue
|
continue
|
||||||
|
} else {
|
||||||
|
err := s.WriteDestFile(base+".xml", b)
|
||||||
|
if err != nil {
|
||||||
|
results <- err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
results <- nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,10 +894,13 @@ func (s *Site) RenderListsOfTaxonomyTerms() (err error) {
|
||||||
layouts := []string{"taxonomy/" + singular + ".terms.html", "_default/terms.html", "indexes/indexes.html"}
|
layouts := []string{"taxonomy/" + singular + ".terms.html", "_default/terms.html", "indexes/indexes.html"}
|
||||||
layouts = s.appendThemeTemplates(layouts)
|
layouts = s.appendThemeTemplates(layouts)
|
||||||
if s.layoutExists(layouts...) {
|
if s.layoutExists(layouts...) {
|
||||||
err := s.render("taxonomy terms for "+singular, n, plural+"/index.html", layouts...)
|
b, err := s.renderPage("taxonomy terms for "+singular, n, layouts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.WriteDestPage(plural+"/index.html", b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,19 +921,25 @@ func (s *Site) RenderSectionLists() error {
|
||||||
n.Data["Pages"] = data.Pages()
|
n.Data["Pages"] = data.Pages()
|
||||||
layouts := []string{"section/" + section + ".html", "_default/section.html", "_default/list.html", "indexes/" + section + ".html", "_default/indexes.html"}
|
layouts := []string{"section/" + section + ".html", "_default/section.html", "_default/list.html", "indexes/" + section + ".html", "_default/indexes.html"}
|
||||||
|
|
||||||
err := s.render("section "+section, n, section, s.appendThemeTemplates(layouts)...)
|
b, err := s.renderPage("section "+section, n, s.appendThemeTemplates(layouts)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.WriteDestPage(section, b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !viper.GetBool("DisableRSS") {
|
if !viper.GetBool("DisableRSS") {
|
||||||
// XML Feed
|
// XML Feed
|
||||||
rssLayouts := []string{"section/" + section + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
rssLayouts := []string{"section/" + section + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
||||||
s.setUrls(n, section+".xml")
|
s.setUrls(n, section+".xml")
|
||||||
err = s.render("section "+section+" rss", n, section+".xml", s.appendThemeTemplates(rssLayouts)...)
|
b, err = s.renderXML("section "+section+" rss", n, s.appendThemeTemplates(rssLayouts)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.WriteDestFile(section+".xml", b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -932,10 +956,13 @@ func (s *Site) newHomeNode() *Node {
|
||||||
func (s *Site) RenderHomePage() error {
|
func (s *Site) RenderHomePage() error {
|
||||||
n := s.newHomeNode()
|
n := s.newHomeNode()
|
||||||
layouts := []string{"index.html", "_default/list.html", "_default/single.html"}
|
layouts := []string{"index.html", "_default/list.html", "_default/single.html"}
|
||||||
err := s.render("homepage", n, "/", s.appendThemeTemplates(layouts)...)
|
b, err := s.renderPage("homepage", n, s.appendThemeTemplates(layouts)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.WriteDestPage("/", b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !viper.GetBool("DisableRSS") {
|
if !viper.GetBool("DisableRSS") {
|
||||||
// XML Feed
|
// XML Feed
|
||||||
|
@ -953,20 +980,14 @@ func (s *Site) RenderHomePage() error {
|
||||||
|
|
||||||
if !viper.GetBool("DisableRSS") {
|
if !viper.GetBool("DisableRSS") {
|
||||||
rssLayouts := []string{"rss.xml", "_default/rss.xml", "_internal/_default/rss.xml"}
|
rssLayouts := []string{"rss.xml", "_default/rss.xml", "_internal/_default/rss.xml"}
|
||||||
err := s.render("homepage rss", n, ".xml", s.appendThemeTemplates(rssLayouts)...)
|
b, err := s.renderXML("homepage rss", n, s.appendThemeTemplates(rssLayouts)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.WriteDestFile("rss.xml", b); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force `UglyUrls` option to force `404.html` file name
|
|
||||||
switch s.Target.(type) {
|
|
||||||
case *target.Filesystem:
|
|
||||||
if !s.Target.(*target.Filesystem).UglyUrls {
|
|
||||||
s.Target.(*target.Filesystem).UglyUrls = true
|
|
||||||
defer func() { s.Target.(*target.Filesystem).UglyUrls = false }()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Url = helpers.Urlize("404.html")
|
n.Url = helpers.Urlize("404.html")
|
||||||
|
@ -974,10 +995,13 @@ func (s *Site) RenderHomePage() error {
|
||||||
n.Permalink = s.permalink("404.html")
|
n.Permalink = s.permalink("404.html")
|
||||||
|
|
||||||
nfLayouts := []string{"404.html"}
|
nfLayouts := []string{"404.html"}
|
||||||
nfErr := s.render("404 page", n, "404.html", s.appendThemeTemplates(nfLayouts)...)
|
b, nfErr := s.renderPage("404 page", n, s.appendThemeTemplates(nfLayouts)...)
|
||||||
if nfErr != nil {
|
if nfErr != nil {
|
||||||
return nfErr
|
return nfErr
|
||||||
}
|
}
|
||||||
|
if err := s.WriteDestFile("404.html", b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1017,20 +1041,23 @@ func (s *Site) RenderSitemap() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force `UglyUrls` option to force `sitemap.xml` file name
|
// Force `UglyUrls` option to force `sitemap.xml` file name
|
||||||
switch s.Target.(type) {
|
switch s.PageTarget().(type) {
|
||||||
case *target.Filesystem:
|
case *target.Filesystem:
|
||||||
s.Target.(*target.Filesystem).UglyUrls = true
|
s.PageTarget().(*target.PagePub).UglyUrls = true
|
||||||
optChanged = true
|
optChanged = true
|
||||||
}
|
}
|
||||||
|
|
||||||
smLayouts := []string{"sitemap.xml", "_default/sitemap.xml", "_internal/_default/sitemap.xml"}
|
smLayouts := []string{"sitemap.xml", "_default/sitemap.xml", "_internal/_default/sitemap.xml"}
|
||||||
err := s.render("sitemap", n, "sitemap.xml", s.appendThemeTemplates(smLayouts)...)
|
b, err := s.renderXML("sitemap", n, s.appendThemeTemplates(smLayouts)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.WriteDestFile("sitemap.xml", b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if optChanged {
|
if optChanged {
|
||||||
s.Target.(*target.Filesystem).UglyUrls = viper.GetBool("UglyUrls")
|
s.PageTarget().(*target.PagePub).UglyUrls = viper.GetBool("UglyUrls")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -1087,20 +1114,24 @@ func (s *Site) layoutExists(layouts ...string) bool {
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) render(name string, d interface{}, out string, layouts ...string) (err error) {
|
func (s *Site) renderXML(name string, d interface{}, layouts ...string) (io.Reader, error) {
|
||||||
|
renderBuffer := s.NewXMLBuffer()
|
||||||
|
err := s.render(name, d, renderBuffer, layouts...)
|
||||||
|
return renderBuffer, err
|
||||||
|
}
|
||||||
|
|
||||||
layout, found := s.findFirstLayout(layouts...)
|
func (s *Site) renderPage(name string, d interface{}, layouts ...string) (io.Reader, error) {
|
||||||
if found == false {
|
renderBuffer := new(bytes.Buffer)
|
||||||
jww.WARN.Printf("Unable to locate layout for %s: %s\n", name, layouts)
|
err := s.render(name, d, renderBuffer, layouts...)
|
||||||
return
|
|
||||||
}
|
var outBuffer = new(bytes.Buffer)
|
||||||
|
|
||||||
transformLinks := transform.NewEmptyTransforms()
|
transformLinks := transform.NewEmptyTransforms()
|
||||||
|
|
||||||
if viper.GetBool("CanonifyUrls") {
|
if viper.GetBool("CanonifyUrls") {
|
||||||
absURL, err := transform.AbsURL(viper.GetString("BaseUrl"))
|
absURL, err := transform.AbsURL(viper.GetString("BaseUrl"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
transformLinks = append(transformLinks, absURL...)
|
transformLinks = append(transformLinks, absURL...)
|
||||||
}
|
}
|
||||||
|
@ -1110,17 +1141,18 @@ func (s *Site) render(name string, d interface{}, out string, layouts ...string)
|
||||||
}
|
}
|
||||||
|
|
||||||
transformer := transform.NewChain(transformLinks...)
|
transformer := transform.NewChain(transformLinks...)
|
||||||
|
transformer.Apply(outBuffer, renderBuffer)
|
||||||
|
return outBuffer, err
|
||||||
|
}
|
||||||
|
|
||||||
var renderBuffer *bytes.Buffer
|
func (s *Site) render(name string, d interface{}, renderBuffer *bytes.Buffer, layouts ...string) error {
|
||||||
|
layout, found := s.findFirstLayout(layouts...)
|
||||||
if strings.HasSuffix(out, ".xml") {
|
if found == false {
|
||||||
renderBuffer = s.NewXMLBuffer()
|
jww.WARN.Printf("Unable to locate layout for %s: %s\n", name, layouts)
|
||||||
} else {
|
return nil
|
||||||
renderBuffer = new(bytes.Buffer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.renderThing(d, layout, renderBuffer)
|
if err := s.renderThing(d, layout, renderBuffer); err != nil {
|
||||||
if err != nil {
|
|
||||||
// Behavior here should be dependent on if running in server or watch mode.
|
// Behavior here should be dependent on if running in server or watch mode.
|
||||||
jww.ERROR.Println(fmt.Errorf("Error while rendering %s: %v", name, err))
|
jww.ERROR.Println(fmt.Errorf("Error while rendering %s: %v", name, err))
|
||||||
if !s.Running() {
|
if !s.Running() {
|
||||||
|
@ -1128,14 +1160,7 @@ func (s *Site) render(name string, d interface{}, out string, layouts ...string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var outBuffer = new(bytes.Buffer)
|
return nil
|
||||||
if strings.HasSuffix(out, ".xml") {
|
|
||||||
outBuffer = renderBuffer
|
|
||||||
} else {
|
|
||||||
transformer.Apply(outBuffer, renderBuffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.WritePublic(out, outBuffer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) findFirstLayout(layouts ...string) (string, bool) {
|
func (s *Site) findFirstLayout(layouts ...string) (string, bool) {
|
||||||
|
@ -1160,33 +1185,48 @@ func (s *Site) NewXMLBuffer() *bytes.Buffer {
|
||||||
return bytes.NewBufferString(header)
|
return bytes.NewBufferString(header)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) initTarget() {
|
func (s *Site) PageTarget() target.Output {
|
||||||
if s.Target == nil {
|
if s.Targets.Page == nil {
|
||||||
s.Target = &target.Filesystem{
|
s.Targets.Page = &target.PagePub{
|
||||||
PublishDir: s.absPublishDir(),
|
PublishDir: s.absPublishDir(),
|
||||||
UglyUrls: viper.GetBool("UglyUrls"),
|
UglyUrls: viper.GetBool("UglyUrls"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return s.Targets.Page
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) WritePublic(path string, reader io.Reader) (err error) {
|
func (s *Site) FileTarget() target.Output {
|
||||||
s.initTarget()
|
if s.Targets.File == nil {
|
||||||
|
s.Targets.File = &target.Filesystem{
|
||||||
jww.DEBUG.Println("writing to", path)
|
|
||||||
return s.Target.Publish(path, reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Site) WriteAlias(path string, permalink template.HTML) (err error) {
|
|
||||||
if s.Alias == nil {
|
|
||||||
s.initTarget()
|
|
||||||
s.Alias = &target.HTMLRedirectAlias{
|
|
||||||
PublishDir: s.absPublishDir(),
|
PublishDir: s.absPublishDir(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return s.Targets.File
|
||||||
|
}
|
||||||
|
|
||||||
jww.DEBUG.Println("alias created at", path)
|
func (s *Site) AliasTarget() target.AliasPublisher {
|
||||||
|
if s.Targets.Alias == nil {
|
||||||
|
s.Targets.Alias = &target.HTMLRedirectAlias{
|
||||||
|
PublishDir: s.absPublishDir(),
|
||||||
|
}
|
||||||
|
|
||||||
return s.Alias.Publish(path, permalink)
|
}
|
||||||
|
return s.Targets.Alias
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Site) WriteDestFile(path string, reader io.Reader) (err error) {
|
||||||
|
jww.DEBUG.Println("creating file:", path)
|
||||||
|
return s.FileTarget().Publish(path, reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Site) WriteDestPage(path string, reader io.Reader) (err error) {
|
||||||
|
jww.DEBUG.Println("creating page:", path)
|
||||||
|
return s.PageTarget().Publish(path, reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Site) WriteDestAlias(path string, permalink template.HTML) (err error) {
|
||||||
|
jww.DEBUG.Println("alias created at:", path)
|
||||||
|
return s.AliasTarget().Publish(path, permalink)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) draftStats() string {
|
func (s *Site) draftStats() string {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package target
|
package target
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
@ -23,13 +22,10 @@ type Output interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Filesystem struct {
|
type Filesystem struct {
|
||||||
UglyUrls bool
|
|
||||||
DefaultExtension string
|
|
||||||
PublishDir string
|
PublishDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *Filesystem) Publish(path string, r io.Reader) (err error) {
|
func (fs *Filesystem) Publish(path string, r io.Reader) (err error) {
|
||||||
|
|
||||||
translated, err := fs.Translate(path)
|
translated, err := fs.Translate(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -39,42 +35,11 @@ func (fs *Filesystem) Publish(path string, r io.Reader) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *Filesystem) Translate(src string) (dest string, err error) {
|
func (fs *Filesystem) Translate(src string) (dest string, err error) {
|
||||||
if src == "/" {
|
return path.Join(fs.PublishDir, src), nil
|
||||||
if fs.PublishDir != "" {
|
|
||||||
return path.Join(fs.PublishDir, "index.html"), nil
|
|
||||||
}
|
|
||||||
return "index.html", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dir, file := path.Split(src)
|
|
||||||
ext := fs.extension(path.Ext(file))
|
|
||||||
name := filename(file)
|
|
||||||
if fs.PublishDir != "" {
|
|
||||||
dir = path.Join(fs.PublishDir, dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
if fs.UglyUrls || file == "index.html" {
|
|
||||||
return path.Join(dir, fmt.Sprintf("%s%s", name, ext)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.Join(dir, name, fmt.Sprintf("index%s", ext)), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *Filesystem) extension(ext string) string {
|
func (fs *Filesystem) extension(ext string) string {
|
||||||
switch ext {
|
|
||||||
case ".md", ".rst": // TODO make this list configurable. page.go has the list of markup types.
|
|
||||||
return ".html"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ext != "" {
|
|
||||||
return ext
|
return ext
|
||||||
}
|
|
||||||
|
|
||||||
if fs.DefaultExtension != "" {
|
|
||||||
return fs.DefaultExtension
|
|
||||||
}
|
|
||||||
|
|
||||||
return ".html"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func filename(f string) string {
|
func filename(f string) string {
|
||||||
|
|
71
target/page.go
Normal file
71
target/page.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package target
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/spf13/hugo/helpers"
|
||||||
|
"github.com/spf13/hugo/hugofs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PagePublisher interface {
|
||||||
|
Translator
|
||||||
|
Publish(string, template.HTML) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type PagePub struct {
|
||||||
|
UglyUrls bool
|
||||||
|
DefaultExtension string
|
||||||
|
PublishDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *PagePub) Publish(path string, r io.Reader) (err error) {
|
||||||
|
|
||||||
|
translated, err := pp.Translate(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return helpers.WriteToDisk(translated, r, hugofs.DestinationFS)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *PagePub) Translate(src string) (dest string, err error) {
|
||||||
|
if src == "/" {
|
||||||
|
if pp.PublishDir != "" {
|
||||||
|
return path.Join(pp.PublishDir, "index.html"), nil
|
||||||
|
}
|
||||||
|
return "index.html", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, file := path.Split(src)
|
||||||
|
ext := pp.extension(path.Ext(file))
|
||||||
|
name := filename(file)
|
||||||
|
if pp.PublishDir != "" {
|
||||||
|
dir = path.Join(pp.PublishDir, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pp.UglyUrls || file == "index.html" {
|
||||||
|
return path.Join(dir, fmt.Sprintf("%s%s", name, ext)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Join(dir, name, fmt.Sprintf("index%s", ext)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *PagePub) extension(ext string) string {
|
||||||
|
switch ext {
|
||||||
|
case ".md", ".rst": // TODO make this list configurable. page.go has the list of markup types.
|
||||||
|
return ".html"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ext != "" {
|
||||||
|
return ext
|
||||||
|
}
|
||||||
|
|
||||||
|
if pp.DefaultExtension != "" {
|
||||||
|
return pp.DefaultExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
return ".html"
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFileTranslator(t *testing.T) {
|
func TestPageTranslator(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
content string
|
content string
|
||||||
expected string
|
expected string
|
||||||
|
@ -23,7 +23,7 @@ func TestFileTranslator(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
f := new(Filesystem)
|
f := new(PagePub)
|
||||||
dest, err := f.Translate(test.content)
|
dest, err := f.Translate(test.content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Translate returned and unexpected err: %s", err)
|
t.Fatalf("Translate returned and unexpected err: %s", err)
|
||||||
|
@ -35,7 +35,7 @@ func TestFileTranslator(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFileTranslatorBase(t *testing.T) {
|
func TestPageTranslatorBase(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
content string
|
content string
|
||||||
expected string
|
expected string
|
||||||
|
@ -44,10 +44,10 @@ func TestFileTranslatorBase(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
f := &Filesystem{PublishDir: "a/base"}
|
f := &PagePub{PublishDir: "a/base"}
|
||||||
fts := &Filesystem{PublishDir: "a/base/"}
|
fts := &PagePub{PublishDir: "a/base/"}
|
||||||
|
|
||||||
for _, fs := range []*Filesystem{f, fts} {
|
for _, fs := range []*PagePub{f, fts} {
|
||||||
dest, err := fs.Translate(test.content)
|
dest, err := fs.Translate(test.content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Translated returned and err: %s", err)
|
t.Fatalf("Translated returned and err: %s", err)
|
||||||
|
@ -72,7 +72,7 @@ func TestTranslateUglyUrls(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
f := &Filesystem{UglyUrls: true}
|
f := &PagePub{UglyUrls: true}
|
||||||
dest, err := f.Translate(test.content)
|
dest, err := f.Translate(test.content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Translate returned an unexpected err: %s", err)
|
t.Fatalf("Translate returned an unexpected err: %s", err)
|
||||||
|
@ -85,7 +85,7 @@ func TestTranslateUglyUrls(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTranslateDefaultExtension(t *testing.T) {
|
func TestTranslateDefaultExtension(t *testing.T) {
|
||||||
f := &Filesystem{DefaultExtension: ".foobar"}
|
f := &PagePub{DefaultExtension: ".foobar"}
|
||||||
dest, _ := f.Translate("baz")
|
dest, _ := f.Translate("baz")
|
||||||
if dest != "baz/index.foobar" {
|
if dest != "baz/index.foobar" {
|
||||||
t.Errorf("Translate expected return: %s, got %s", "baz/index.foobar", dest)
|
t.Errorf("Translate expected return: %s, got %s", "baz/index.foobar", dest)
|
Loading…
Reference in a new issue