mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
parent
e7d0bc8a74
commit
e371ac0b6f
8 changed files with 185 additions and 17 deletions
|
@ -31,6 +31,15 @@ import (
|
|||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
// Temporary feature flag to ease the refactoring of node vs page, see
|
||||
// https://github.com/spf13/hugo/issues/2297
|
||||
// TODO(bep) eventually remove
|
||||
var nodePageFeatureFlag bool
|
||||
|
||||
func toggleNodePageFeatureFlag() {
|
||||
nodePageFeatureFlag = !nodePageFeatureFlag
|
||||
}
|
||||
|
||||
// HugoSites represents the sites to build. Each site represents a language.
|
||||
type HugoSites struct {
|
||||
Sites []*Site
|
||||
|
@ -563,6 +572,16 @@ func (s *Site) updateBuildStats(page *Page) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *HugoSites) findPagesByNodeType(n NodeType) Pages {
|
||||
var pages Pages
|
||||
for _, p := range h.Sites[0].AllPages {
|
||||
if p.NodeType == n {
|
||||
pages = append(pages, p)
|
||||
}
|
||||
}
|
||||
return pages
|
||||
}
|
||||
|
||||
// Convenience func used in tests to build a single site/language excluding render phase.
|
||||
func buildSiteSkipRender(s *Site, additionalTemplates ...string) error {
|
||||
return doBuildSite(s, false, additionalTemplates...)
|
||||
|
|
|
@ -26,7 +26,23 @@ import (
|
|||
"github.com/spf13/hugo/helpers"
|
||||
)
|
||||
|
||||
// TODO(bep) np add String()
|
||||
type NodeType int
|
||||
|
||||
const (
|
||||
NodePage NodeType = iota
|
||||
|
||||
// The rest are node types; home page, sections etc.
|
||||
NodeHome
|
||||
)
|
||||
|
||||
func (p NodeType) IsNode() bool {
|
||||
return p >= NodeHome
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
NodeType NodeType
|
||||
|
||||
// a natural key that should be unique for this site
|
||||
// for the home page this will typically be "home", but it can anything
|
||||
// as long as it is the same for repeated builds.
|
||||
|
@ -44,7 +60,6 @@ type Node struct {
|
|||
Lastmod time.Time
|
||||
Sitemap Sitemap
|
||||
URLPath
|
||||
IsHome bool
|
||||
paginator *Pager
|
||||
paginatorInit sync.Once
|
||||
scratch *Scratch
|
||||
|
@ -151,11 +166,15 @@ func (n *Node) RSSlink() template.HTML {
|
|||
}
|
||||
|
||||
func (n *Node) IsNode() bool {
|
||||
return true
|
||||
return n.NodeType.IsNode()
|
||||
}
|
||||
|
||||
func (n *Node) IsHome() bool {
|
||||
return n.NodeType == NodeHome
|
||||
}
|
||||
|
||||
func (n *Node) IsPage() bool {
|
||||
return !n.IsNode()
|
||||
return n.NodeType == NodePage
|
||||
}
|
||||
|
||||
func (n *Node) Ref(ref string) (string, error) {
|
||||
|
@ -316,3 +335,11 @@ func (n *Node) addLangFilepathPrefix(outfile string) string {
|
|||
}
|
||||
return helpers.FilePathSeparator + filepath.Join(n.Lang(), outfile)
|
||||
}
|
||||
|
||||
func nodeTypeFromFilename(filename string) NodeType {
|
||||
// TODO(bep) np
|
||||
if !strings.HasPrefix(filename, "_node") {
|
||||
return NodePage
|
||||
}
|
||||
return NodeHome
|
||||
}
|
||||
|
|
103
hugolib/node_as_page_test.go
Normal file
103
hugolib/node_as_page_test.go
Normal file
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2016 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package hugolib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
/*
|
||||
This file will test the "making everything a page" transition.
|
||||
|
||||
See https://github.com/spf13/hugo/issues/2297
|
||||
|
||||
*/
|
||||
|
||||
func TestHomeAsPage(t *testing.T) {
|
||||
nodePageFeatureFlag = true
|
||||
defer toggleNodePageFeatureFlag()
|
||||
|
||||
/* Will have to decide what to name the node content files, but:
|
||||
|
||||
Home page should have:
|
||||
Content, shortcode support
|
||||
Metadata (title, dates etc.)
|
||||
Params
|
||||
Taxonomies (categories, tags)
|
||||
|
||||
*/
|
||||
|
||||
testCommonResetState()
|
||||
|
||||
writeSource(t, filepath.Join("content", "_node.md"), `---
|
||||
title: Home Sweet Home!
|
||||
---
|
||||
Home **Content!**
|
||||
`)
|
||||
|
||||
writeSource(t, filepath.Join("layouts", "index.html"), `
|
||||
Index Title: {{ .Title }}
|
||||
Index Content: {{ .Content }}
|
||||
# Pages: {{ len .Data.Pages }}
|
||||
`)
|
||||
|
||||
writeSource(t, filepath.Join("layouts", "_default", "single.html"), `
|
||||
Single Title: {{ .Title }}
|
||||
Single Content: {{ .Content }}
|
||||
`)
|
||||
|
||||
// Add some regular pages
|
||||
for i := 0; i < 10; i++ {
|
||||
writeSource(t, filepath.Join("content", fmt.Sprintf("regular%d.md", i)), fmt.Sprintf(`---
|
||||
title: Page %d
|
||||
---
|
||||
Content Page %d
|
||||
`, i, i))
|
||||
}
|
||||
|
||||
s := newSiteDefaultLang()
|
||||
|
||||
if err := buildAndRenderSite(s); err != nil {
|
||||
t.Fatalf("Failed to build site: %s", err)
|
||||
}
|
||||
|
||||
assertFileContent(t, filepath.Join("public", "index.html"), false,
|
||||
"Index Title: Home Sweet Home!",
|
||||
"Home <strong>Content!</strong>",
|
||||
"# Pages: 10")
|
||||
assertFileContent(t, filepath.Join("public", "regular1", "index.html"), false, "Single Title: Page 1", "Content Page 1")
|
||||
|
||||
h := s.owner
|
||||
nodes := h.findPagesByNodeType(NodeHome)
|
||||
require.Len(t, nodes, 1)
|
||||
|
||||
home := nodes[0]
|
||||
|
||||
require.True(t, home.IsHome())
|
||||
require.True(t, home.IsNode())
|
||||
require.False(t, home.IsPage())
|
||||
|
||||
pages := h.findPagesByNodeType(NodePage)
|
||||
require.Len(t, pages, 10)
|
||||
|
||||
first := pages[0]
|
||||
require.False(t, first.IsHome())
|
||||
require.False(t, first.IsNode())
|
||||
require.True(t, first.IsPage())
|
||||
|
||||
}
|
|
@ -30,7 +30,7 @@ func TestNodeSimpleMethods(t *testing.T) {
|
|||
{func(n *Node) bool { return n.Now().Unix() == time.Now().Unix() }},
|
||||
} {
|
||||
|
||||
n := &Node{}
|
||||
n := &Node{NodeType: NodeHome}
|
||||
n.RSSLink = "rssLink"
|
||||
|
||||
if !this.assertFunc(n) {
|
||||
|
|
|
@ -182,14 +182,6 @@ func (p *Page) initPlainWords() {
|
|||
})
|
||||
}
|
||||
|
||||
func (p *Page) IsNode() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Page) IsPage() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Param is a convenience method to do lookups in Page's and Site's Params map,
|
||||
// in that order.
|
||||
//
|
||||
|
@ -423,7 +415,7 @@ func (p *Page) getRenderingConfig() *helpers.Blackfriday {
|
|||
func newPage(filename string) *Page {
|
||||
page := Page{contentType: "",
|
||||
Source: Source{File: *source.NewFile(filename)},
|
||||
Node: Node{Keywords: []string{}, Sitemap: Sitemap{Priority: -1}},
|
||||
Node: Node{NodeType: nodeTypeFromFilename(filename), Keywords: []string{}, Sitemap: Sitemap{Priority: -1}},
|
||||
Params: make(map[string]interface{}),
|
||||
translations: make(Pages, 0),
|
||||
}
|
||||
|
@ -457,6 +449,11 @@ func (p *Page) layouts(l ...string) []string {
|
|||
return p.layoutsCalculated
|
||||
}
|
||||
|
||||
// TODO(bep) np
|
||||
if p.NodeType == NodeHome {
|
||||
return []string{"index.html", "_default/list.html"}
|
||||
}
|
||||
|
||||
if p.Layout != "" {
|
||||
return layouts(p.Type(), p.Layout)
|
||||
}
|
||||
|
@ -1136,6 +1133,10 @@ func (p *Page) FullFilePath() string {
|
|||
}
|
||||
|
||||
func (p *Page) TargetPath() (outfile string) {
|
||||
// TODO(bep) ml
|
||||
if p.NodeType == NodeHome {
|
||||
return "index.html"
|
||||
}
|
||||
// Always use URL if it's specified
|
||||
if len(strings.TrimSpace(p.URLPath.URL)) > 2 {
|
||||
outfile = strings.TrimSpace(p.URLPath.URL)
|
||||
|
|
|
@ -645,7 +645,7 @@ func TestCreateNewPage(t *testing.T) {
|
|||
|
||||
// issue #2290: Path is relative to the content dir and will continue to be so.
|
||||
require.Equal(t, filepath.FromSlash(fmt.Sprintf("p0.%s", ext)), p.Path())
|
||||
assert.False(t, p.IsHome)
|
||||
assert.False(t, p.IsHome())
|
||||
checkPageTitle(t, p, "Simple")
|
||||
checkPageContent(t, p, normalizeExpected(ext, "<p>Simple Page</p>\n"))
|
||||
checkPageSummary(t, p, "Simple Page")
|
||||
|
|
|
@ -1678,6 +1678,8 @@ func (s *Site) renderPages() error {
|
|||
func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
for p := range pages {
|
||||
// TODO(bep) np paginator
|
||||
s.preparePage(p)
|
||||
err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(p.layouts())...)
|
||||
if err != nil {
|
||||
results <- err
|
||||
|
@ -1685,6 +1687,17 @@ func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.Wa
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Site) preparePage(p *Page) {
|
||||
// TODO(bep) np the order of it all
|
||||
switch p.NodeType {
|
||||
case NodePage:
|
||||
case NodeHome:
|
||||
p.Data = make(map[string]interface{})
|
||||
// TODO(bep) np cache the below
|
||||
p.Data["Pages"] = s.owner.findPagesByNodeType(NodePage)
|
||||
}
|
||||
}
|
||||
|
||||
func errorCollator(results <-chan error, errs chan<- error) {
|
||||
errMsgs := []string{}
|
||||
for err := range results {
|
||||
|
@ -2028,6 +2041,11 @@ func (s *Site) renderSectionLists(prepare bool) error {
|
|||
}
|
||||
|
||||
func (s *Site) renderHomePage(prepare bool) error {
|
||||
// TODO(bep) np remove this and related
|
||||
if nodePageFeatureFlag {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := s.newHomeNode(prepare, 0)
|
||||
if prepare {
|
||||
return nil
|
||||
|
@ -2118,7 +2136,7 @@ func (s *Site) renderHomePage(prepare bool) error {
|
|||
func (s *Site) newHomeNode(prepare bool, counter int) *Node {
|
||||
n := s.nodeLookup("home", counter, prepare)
|
||||
n.Title = n.Site.Title
|
||||
n.IsHome = true
|
||||
n.NodeType = NodeHome
|
||||
s.setURLs(n, "/")
|
||||
n.Data["Pages"] = s.Pages
|
||||
if len(s.Pages) != 0 {
|
||||
|
@ -2373,7 +2391,7 @@ func (s *Site) renderAndWritePage(name string, dest string, d interface{}, layou
|
|||
}
|
||||
|
||||
// For performance reasons we only inject the Hugo generator tag on the home page.
|
||||
if n, ok := d.(*Node); ok && n.IsHome {
|
||||
if n, ok := d.(*Node); ok && n.IsHome() {
|
||||
if !viper.GetBool("disableHugoGeneratorInject") {
|
||||
transformLinks = append(transformLinks, transform.HugoGeneratorInject)
|
||||
}
|
||||
|
|
|
@ -378,7 +378,7 @@ func doTestShouldAlwaysHaveUglyURLs(t *testing.T, uglyURLs bool) {
|
|||
}
|
||||
|
||||
for _, p := range s.Pages {
|
||||
assert.False(t, p.IsHome)
|
||||
assert.False(t, p.IsHome())
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
Loading…
Reference in a new issue