shithub: hugo

Download patch

ref: 524eb16686bed7d110c6001c5d98b2ee0a2d80ee
parent: c8d3124ddeb86093caf1b18dfaa328c3053e5b63
author: Bjørn Erik Pedersen <[email protected]>
date: Tue Nov 15 05:43:49 EST 2016

node to page: Handle URLs

This includes removing the error return value from Permalink and RelPermalink.

We ignore that error all over the place, so we might as well remove it.

Updates #2297

--- a/hugolib/hugo_sites_build.go
+++ b/hugolib/hugo_sites_build.go
@@ -136,7 +136,7 @@
 }
 
 func (h *HugoSites) assemble(config *BuildCfg) error {
-	// TODO(bep) np we could probably wait and do this in one go later
+	// TODO(bep) we could probably wait and do this in one go later
 	h.setupTranslations()
 
 	if len(h.Sites) > 1 {
--- a/hugolib/hugo_sites_build_test.go
+++ b/hugolib/hugo_sites_build_test.go
@@ -86,13 +86,13 @@
 	doc1en := enSite.RegularPages[0]
 	doc1fr := frSite.RegularPages[0]
 
-	enPerm, _ := doc1en.Permalink()
-	enRelPerm, _ := doc1en.RelPermalink()
+	enPerm := doc1en.Permalink()
+	enRelPerm := doc1en.RelPermalink()
 	require.Equal(t, "http://example.com/blog/en/sect/doc1-slug/", enPerm)
 	require.Equal(t, "/blog/en/sect/doc1-slug/", enRelPerm)
 
-	frPerm, _ := doc1fr.Permalink()
-	frRelPerm, _ := doc1fr.RelPermalink()
+	frPerm := doc1fr.Permalink()
+	frRelPerm := doc1fr.RelPermalink()
 	// Main language in root
 	require.Equal(t, replaceDefaultContentLanguageValue("http://example.com/blog/fr/sect/doc1/", defaultInSubDir), frPerm)
 	require.Equal(t, replaceDefaultContentLanguageValue("/blog/fr/sect/doc1/", defaultInSubDir), frRelPerm)
@@ -223,18 +223,18 @@
 	assert.Len(t, enSite.AllPages, 28, "should have 28 total pages (including translations and index types)")
 
 	doc1en := enSite.RegularPages[0]
-	permalink, err := doc1en.Permalink()
+	permalink := doc1en.Permalink()
 	assert.NoError(t, err, "permalink call failed")
 	assert.Equal(t, "http://example.com/blog/en/sect/doc1-slug/", permalink, "invalid doc1.en permalink")
 	assert.Len(t, doc1en.Translations(), 1, "doc1-en should have one translation, excluding itself")
 
 	doc2 := enSite.RegularPages[1]
-	permalink, err = doc2.Permalink()
+	permalink = doc2.Permalink()
 	assert.NoError(t, err, "permalink call failed")
 	assert.Equal(t, "http://example.com/blog/en/sect/doc2/", permalink, "invalid doc2 permalink")
 
 	doc3 := enSite.RegularPages[2]
-	permalink, err = doc3.Permalink()
+	permalink = doc3.Permalink()
 	assert.NoError(t, err, "permalink call failed")
 	// Note that /superbob is a custom URL set in frontmatter.
 	// We respect that URL literally (it can be /search.json)
@@ -246,7 +246,7 @@
 	assert.Equal(t, doc2.Next, doc3, "doc3 should follow doc2, in .Next")
 
 	doc1fr := doc1en.Translations()[0]
-	permalink, err = doc1fr.Permalink()
+	permalink = doc1fr.Permalink()
 	assert.NoError(t, err, "permalink call failed")
 	assert.Equal(t, "http://example.com/blog/fr/sect/doc1/", permalink, "invalid doc1fr permalink")
 
@@ -255,8 +255,7 @@
 	assert.Equal(t, "fr", doc1fr.Language().Lang)
 
 	doc4 := enSite.AllPages[4]
-	permalink, err = doc4.Permalink()
-	assert.NoError(t, err, "permalink call failed")
+	permalink = doc4.Permalink()
 	assert.Equal(t, "http://example.com/blog/fr/sect/doc4/", permalink, "invalid doc4 permalink")
 	assert.Equal(t, "/blog/fr/sect/doc4/", doc4.URL())
 
@@ -263,8 +262,7 @@
 	assert.Len(t, doc4.Translations(), 0, "found translations for doc4")
 
 	doc5 := enSite.AllPages[5]
-	permalink, err = doc5.Permalink()
-	assert.NoError(t, err, "permalink call failed")
+	permalink = doc5.Permalink()
 	assert.Equal(t, "http://example.com/blog/fr/somewhere/else/doc5", permalink, "invalid doc5 permalink")
 
 	// Taxonomies and their URLs
--- a/hugolib/menu_test.go
+++ b/hugolib/menu_test.go
@@ -560,7 +560,6 @@
 	s := setupMenuTests(t, menuPageSources)
 
 	home := s.getPage(KindHome)
-
 	homeMenuEntry := &MenuEntry{Name: home.Title, URL: home.URL()}
 
 	for i, this := range []struct {
@@ -583,7 +582,7 @@
 		if isMenuCurrent != this.isMenuCurrent {
 			fmt.Println("isMenuCurrent", isMenuCurrent)
 			fmt.Printf("this: %#v\n", this)
-			t.Errorf("[%d] Wrong result from IsMenuCurrent: %v for %q", i, isMenuCurrent, this.menu)
+			t.Errorf("[%d] Wrong result from IsMenuCurrent: %v for %q", i, isMenuCurrent, this.menuItem)
 		}
 
 		if hasMenuCurrent != this.hasMenuCurrent {
--- a/hugolib/node_as_page_test.go
+++ b/hugolib/node_as_page_test.go
@@ -394,6 +394,7 @@
 `)
 
 	viper.Set("paginate", 1)
+	viper.Set("baseURL", "http://base/")
 	viper.Set("title", "Hugo Rocks!")
 
 	s := newSiteDefaultLang()
@@ -403,7 +404,7 @@
 	}
 
 	assertFileContent(t, filepath.Join("public", "index.html"), true, "Home With Alias")
-	assertFileContent(t, filepath.Join("public", "my", "new", "home.html"), true, "content=\"0; url=/")
+	assertFileContent(t, filepath.Join("public", "my", "new", "home.html"), true, "content=\"0; url=http://base/")
 
 }
 
@@ -428,6 +429,47 @@
 	}
 
 	assertFileContent(t, filepath.Join("public", "sect", "index.html"), true, "My Section")
+
+}
+
+func TestNodesWithURLs(t *testing.T) {
+	testCommonResetState()
+
+	writeLayoutsForNodeAsPageTests(t)
+
+	writeRegularPagesForNodeAsPageTests(t)
+
+	writeSource(t, filepath.Join("content", "sect", "_index.md"), `---
+title: MySection
+url: foo.html
+---
+My Section Content
+`)
+
+	viper.Set("paginate", 1)
+	viper.Set("title", "Hugo Rocks!")
+	viper.Set("baseURL", "http://bep.is/base/")
+
+	s := newSiteDefaultLang()
+
+	if err := buildAndRenderSite(s); err != nil {
+		t.Fatalf("Failed to build site: %s", err)
+	}
+
+	assertFileContent(t, filepath.Join("public", "sect", "index.html"), true, "My Section")
+
+	p := s.RegularPages[0]
+
+	require.Equal(t, "/base/sect1/regular1/", p.URL())
+
+	// Section with front matter and url set (which should not be used)
+	sect := s.getPage(KindSection, "sect")
+	require.Equal(t, "/base/sect/", sect.URL())
+	require.Equal(t, "http://bep.is/base/sect/", sect.Permalink())
+	require.Equal(t, "/base/sect/", sect.RelPermalink())
+
+	// Home page without front matter
+	require.Equal(t, "/base/", s.getPage(KindHome).URL())
 
 }
 
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -63,6 +63,7 @@
 
 	// The following are (currently) temporary nodes,
 	// i.e. nodes we create just to render in isolation.
+	kindRSS       = "RSS"
 	kindSitemap   = "sitemap"
 	kindRobotsTXT = "robotsTXT"
 	kind404       = "404"
@@ -698,7 +699,18 @@
 }
 
 func (p *Page) permalink() (*url.URL, error) {
+	// TODO(bep) this should probably be set once during build. Maybe.
+	// And simplified.
 	baseURL := string(p.Site.BaseURL)
+
+	if p.IsNode() {
+		// No permalink config for nodes (currently)
+		pURL := strings.TrimSpace(p.Site.pathSpec.URLize(p.URLPath.URL))
+		pURL = p.addLangPathPrefix(pURL)
+		url := helpers.MakePermalink(baseURL, pURL)
+		return url, nil
+	}
+
 	dir := strings.TrimSpace(p.Site.pathSpec.MakePath(filepath.ToSlash(strings.ToLower(p.Source.Dir()))))
 	pSlug := strings.TrimSpace(p.Site.pathSpec.URLize(p.Slug))
 	pURL := strings.TrimSpace(p.Site.pathSpec.URLize(p.URLPath.URL))
@@ -802,36 +814,30 @@
 	return p.ExpiryDate.Before(time.Now())
 }
 
-func (p *Page) Permalink() (string, error) {
-	// TODO(bep) np permalink
-	if p.IsNode() {
-		return p.Site.permalink(p.URL()), nil
-	}
+func (p *Page) Permalink() string {
 	link, err := p.permalink()
 	if err != nil {
-		return "", err
+		return ""
 	}
-	return link.String(), nil
+
+	return link.String()
 }
 
 func (p *Page) URL() string {
-	// TODO(bep np URL
-	if p.IsNode() {
-		return p.addLangPathPrefix(p.URLPath.URL)
-	}
-	if p.URLPath.URL != "" {
+
+	if p.IsPage() && p.URLPath.URL != "" {
 		// This is the url set in front matter
 		return p.URLPath.URL
 	}
 	// Fall back to the relative permalink.
-	u, _ := p.RelPermalink()
+	u := p.RelPermalink()
 	return u
 }
 
-func (p *Page) RelPermalink() (string, error) {
+func (p *Page) RelPermalink() string {
 	link, err := p.permalink()
 	if err != nil {
-		return "", err
+		return ""
 	}
 
 	if viper.GetBool("canonifyURLs") {
@@ -839,9 +845,20 @@
 		// have to return the URL relative from baseURL
 		relpath, err := helpers.GetRelativePath(link.String(), string(p.Site.BaseURL))
 		if err != nil {
-			return "", err
+			return ""
 		}
-		return "/" + filepath.ToSlash(relpath), nil
+
+		relpath = filepath.ToSlash(relpath)
+
+		if relpath[0] == '.' {
+			relpath = relpath[1:]
+		}
+
+		if !strings.HasPrefix(relpath, "/") {
+			relpath = "/" + relpath
+		}
+
+		return relpath
 	}
 
 	link.Scheme = ""
@@ -848,7 +865,7 @@
 	link.Host = ""
 	link.User = nil
 	link.Opaque = ""
-	return link.String(), nil
+	return link.String()
 }
 
 var ErrHasDraftAndPublished = errors.New("both draft and published parameters were found in page's frontmatter")
@@ -1109,7 +1126,7 @@
 
 	// The following logic is kept from back when Hugo had both Page and Node types.
 	// TODO(bep) consolidate / clean
-	me := MenuEntry{Name: p.Title, URL: p.Site.createNodeMenuEntryURL(p.URL())}
+	me := MenuEntry{Name: p.Title, URL: p.URL()}
 
 	if !me.IsSameResource(inme) {
 		return false
@@ -1154,7 +1171,7 @@
 		p.pageMenus = PageMenus{}
 
 		if ms, ok := p.Params["menu"]; ok {
-			link, _ := p.RelPermalink()
+			link := p.RelPermalink()
 
 			me := MenuEntry{Name: p.LinkTitle(), Weight: p.Weight, URL: link}
 
@@ -1719,13 +1736,13 @@
 	// Set Node URL
 	switch p.Kind {
 	case KindHome:
-		p.URLPath.URL = ""
+		p.URLPath.URL = "/"
 	case KindSection:
-		p.URLPath.URL = p.sections[0]
+		p.URLPath.URL = "/" + p.sections[0] + "/"
 	case KindTaxonomy:
-		p.URLPath.URL = path.Join(p.sections...)
+		p.URLPath.URL = "/" + path.Join(p.sections...) + "/"
 	case KindTaxonomyTerm:
-		p.URLPath.URL = path.Join(p.sections...)
+		p.URLPath.URL = "/" + path.Join(p.sections...) + "/"
 	}
 
 	p.site = s
--- a/hugolib/page_permalink_test.go
+++ b/hugolib/page_permalink_test.go
@@ -81,10 +81,7 @@
 			})
 		}
 
-		u, err := p.Permalink()
-		if err != nil {
-			t.Errorf("Test %d: Unable to process permalink: %s", i, err)
-		}
+		u := p.Permalink()
 
 		expected := test.expectedAbs
 		if u != expected {
@@ -91,10 +88,7 @@
 			t.Errorf("Test %d: Expected abs url: %s, got: %s", i, expected, u)
 		}
 
-		u, err = p.RelPermalink()
-		if err != nil {
-			t.Errorf("Test %d: Unable to process permalink: %s", i, err)
-		}
+		u = p.RelPermalink()
 
 		expected = test.expectedRel
 		if u != expected {
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -299,14 +299,10 @@
 		}
 
 		if relative {
-			link, err = target.RelPermalink()
+			link = target.RelPermalink()
 		} else {
-			link, err = target.Permalink()
+			link = target.Permalink()
 		}
-
-		if err != nil {
-			return "", err
-		}
 	}
 
 	if refURL.Fragment != "" {
@@ -389,11 +385,8 @@
 			return "", fmt.Errorf("No page found for \"%s\" on page \"%s\".\n", ref, currentPage.Source.Path())
 		}
 
-		link, err = target.RelPermalink()
+		link = target.RelPermalink()
 
-		if err != nil {
-			return "", err
-		}
 	}
 
 	if refURL.Fragment != "" {
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -99,7 +99,7 @@
 
 		aliasPath := p.addLangPathPrefix(helpers.PaginateAliasPath(path.Join(p.sections...), 1))
 		//TODO(bep) np node.permalink
-		link, _ := p.Permalink()
+		link := p.Permalink()
 		s.writeDestAlias(aliasPath, link, nil)
 
 		pagers := p.paginator.Pagers()
@@ -144,6 +144,7 @@
 	// TODO(bep) np check RSS titles
 	// TODO(bep) np check RSS page limit, 50?
 	rssNode := p.copy()
+	rssNode.Kind = kindRSS
 
 	// TODO(bep) np todelido URL
 	rssURI := s.Language.GetString("rssURI")
@@ -248,10 +249,8 @@
 			continue
 		}
 
-		plink, err := p.Permalink()
-		if err != nil {
-			return err
-		}
+		plink := p.Permalink()
+
 		for _, a := range p.Aliases {
 			if err := s.writeDestAlias(a, plink, p); err != nil {
 				return err