shithub: hugo

Download patch

ref: 2f10da15707e1db0fab90524a247bc8a2d3ded90
parent: 74b55fc7c87f2887c42ce8626cb461fee5d7b907
author: Noah Campbell <[email protected]>
date: Thu Sep 12 12:17:53 EDT 2013

Move alias rendering to target

--- a/hugolib/planner.go
+++ b/hugolib/planner.go
@@ -22,9 +22,19 @@
 		if err != nil {
 			return err
 		}
-
 		fmt.Fprintf(out, "%s\n", trns)
 
+		if s.Alias == nil {
+			continue
+		}
+
+		for _, alias := range p.Aliases {
+			aliasTrans, err := s.Alias.Translate(alias)
+			if err != nil {
+				return err
+			}
+			fmt.Fprintf(out, " %s => %s\n", alias, aliasTrans)
+		}
 	}
 	return
 }
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -76,6 +76,7 @@
 	Shortcodes map[string]ShortcodeFunc
 	timer      *nitro.B
 	Target     target.Output
+	Alias      target.Translator
 }
 
 type SiteInfo struct {
@@ -192,6 +193,12 @@
 		Base:       s.absContentDir(),
 	}
 
+	s.initializeSiteInfo()
+
+	s.Shortcodes = make(map[string]ShortcodeFunc)
+}
+
+func (s *Site) initializeSiteInfo() {
 	s.Info = SiteInfo{
 		BaseUrl: template.URL(s.Config.BaseUrl),
 		Title:   s.Config.Title,
@@ -198,8 +205,6 @@
 		Recent:  &s.Pages,
 		Config:  &s.Config,
 	}
-
-	s.Shortcodes = make(map[string]ShortcodeFunc)
 }
 
 // Check if File / Directory Exists
@@ -405,14 +410,10 @@
 				t = "alias-xhtml"
 			}
 			content, err := s.RenderThing(p, t)
-			if strings.HasSuffix(a, "/") {
-				a = a + "index.html"
-			}
 			if err != nil {
 				return err
 			}
-			err = s.WritePublic(a, content.Bytes())
-			if err != nil {
+			if err = s.WriteAlias(a, content.Bytes()); err != nil {
 				return err
 			}
 		}
@@ -653,5 +654,21 @@
 		fmt.Println(path)
 	}
 
+	return s.Target.Publish(path, bytes.NewReader(content))
+}
+
+func (s *Site) WriteAlias(path string, content []byte) (err error) {
+	if s.Alias == nil {
+		s.initTarget()
+		s.Alias = new(target.HTMLRedirectAlias)
+	}
+
+	if s.Config.Verbose {
+		fmt.Println(path)
+	}
+
+	if path, err = s.Alias.Translate(path); err != nil {
+		return err
+	}
 	return s.Target.Publish(path, bytes.NewReader(content))
 }
--- a/hugolib/site_show_plan_test.go
+++ b/hugolib/site_show_plan_test.go
@@ -7,19 +7,26 @@
 	"testing"
 )
 
-var fakeSource = []struct {
+const ALIAS_DOC_1 = "---\ntitle: alias doc\naliases:\n  - \"alias1/\"\n  - \"alias-2/\"\n---\naliases\n"
+
+type byteSource struct {
 	name    string
 	content []byte
-}{
+}
+
+var fakeSource = []byteSource{
 	{"foo/bar/file.md", []byte(SIMPLE_PAGE)},
+	{"alias/test/file1.md", []byte(ALIAS_DOC_1)},
+	//{"slug/test/file1.md", []byte(SLUG_DOC_1)},
 }
 
 type inMemorySource struct {
+	byteSource []byteSource
 }
 
-func (i inMemorySource) Files() (files []*source.File) {
-	files = make([]*source.File, len(fakeSource))
-	for i, fake := range fakeSource {
+func (i *inMemorySource) Files() (files []*source.File) {
+	files = make([]*source.File, len(i.byteSource))
+	for i, fake := range i.byteSource {
 		files[i] = &source.File{
 			Name:     fake.name,
 			Contents: bytes.NewReader(fake.content),
@@ -44,28 +51,42 @@
 }
 
 func TestDegenerateNoTarget(t *testing.T) {
-	s := &Site{Source: new(inMemorySource)}
+	s := &Site{
+		Source: &inMemorySource{fakeSource},
+	}
 	must(s.CreatePages())
-	expected := "foo/bar/file.md\n canonical => !no target specified!\n"
+	expected := "foo/bar/file.md\n canonical => !no target specified!\n" +
+		"alias/test/file1.md\n canonical => !no target specified!\n"
 	checkShowPlanExpected(t, s, expected)
 }
 
 func TestFileTarget(t *testing.T) {
 	s := &Site{
-		Source: new(inMemorySource),
+		Source: &inMemorySource{fakeSource},
 		Target: new(target.Filesystem),
+		Alias:  new(target.HTMLRedirectAlias),
 	}
 	must(s.CreatePages())
-	checkShowPlanExpected(t, s, "foo/bar/file.md\n canonical => foo/bar/file/index.html\n")
+	expected := "foo/bar/file.md\n canonical => foo/bar/file/index.html\n" +
+		"alias/test/file1.md\n" +
+		" canonical => alias/test/file1/index.html\n" +
+		" alias1/ => alias1/index.html\n" +
+		" alias-2/ => alias-2/index.html\n"
+	checkShowPlanExpected(t, s, expected)
 }
 
 func TestFileTargetUgly(t *testing.T) {
 	s := &Site{
 		Target: &target.Filesystem{UglyUrls: true},
-		Source: new(inMemorySource),
+		Source: &inMemorySource{fakeSource},
+		Alias:  new(target.HTMLRedirectAlias),
 	}
 	s.CreatePages()
-	expected := "foo/bar/file.md\n canonical => foo/bar/file.html\n"
+	expected := "foo/bar/file.md\n canonical => foo/bar/file.html\n" +
+		"alias/test/file1.md\n" +
+		" canonical => alias/test/file1.html\n" +
+		" alias1/ => alias1/index.html\n" +
+		" alias-2/ => alias-2/index.html\n"
 	checkShowPlanExpected(t, s, expected)
 }
 
@@ -72,10 +93,15 @@
 func TestFileTargetPublishDir(t *testing.T) {
 	s := &Site{
 		Target: &target.Filesystem{PublishDir: "../public"},
-		Source: new(inMemorySource),
+		Source: &inMemorySource{fakeSource},
+		Alias:  &target.HTMLRedirectAlias{PublishDir: "../public"},
 	}
 
 	must(s.CreatePages())
-	expected := "foo/bar/file.md\n canonical => ../public/foo/bar/file/index.html\n"
+	expected := "foo/bar/file.md\n canonical => ../public/foo/bar/file/index.html\n" +
+		"alias/test/file1.md\n" +
+		" canonical => ../public/alias/test/file1/index.html\n" +
+		" alias1/ => ../public/alias1/index.html\n" +
+		" alias-2/ => ../public/alias-2/index.html\n"
 	checkShowPlanExpected(t, s, expected)
 }
--- a/hugolib/site_url_test.go
+++ b/hugolib/site_url_test.go
@@ -3,11 +3,12 @@
 import (
 	"bytes"
 	"io"
-	"strings"
 	"testing"
 )
 
-const SLUG_DOC_1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\n---\nslug doc 1 content"
+const SLUG_DOC_1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\naliases:\n - sd1/foo/\n - sd2\n - sd3/\n - sd4.php\n---\nslug doc 1 content"
+
+//const SLUG_DOC_1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\n---\nslug doc 1 content"
 const SLUG_DOC_2 = "---\ntitle: slug doc 2\nslug: slug-doc-2\n---\nslug doc 2 content"
 
 const INDEX_TEMPLATE = "{{ range .Data.Pages }}.{{ end }}"
@@ -43,14 +44,25 @@
 	return label, nil
 }
 
+var urlFakeSource = []byteSource{
+	{"content/blue/doc1.md", []byte(SLUG_DOC_1)},
+	{"content/blue/doc2.md", []byte(SLUG_DOC_2)},
+}
+
 func TestPageCount(t *testing.T) {
 	target := new(InMemoryTarget)
-	s := &Site{Target: target}
+	s := &Site{
+		Target: target,
+		Config: Config{UglyUrls: false},
+		Source: &inMemorySource{urlFakeSource},
+	}
+	s.initializeSiteInfo()
 	s.prepTemplates()
 	must(s.addTemplate("indexes/blue.html", INDEX_TEMPLATE))
-	s.Pages = append(s.Pages, mustReturn(ReadFrom(strings.NewReader(SLUG_DOC_1), "content/blue/doc1.md")))
-	s.Pages = append(s.Pages, mustReturn(ReadFrom(strings.NewReader(SLUG_DOC_2), "content/blue/doc2.md")))
 
+	if err := s.CreatePages(); err != nil {
+		t.Errorf("Unable to create pages: %s", err)
+	}
 	if err := s.BuildSiteMeta(); err != nil {
 		t.Errorf("Unable to build site metadata: %s", err)
 	}
@@ -59,6 +71,10 @@
 		t.Errorf("Unable to render site lists: %s", err)
 	}
 
+	if err := s.RenderAliases(); err != nil {
+		t.Errorf("Unable to render site lists: %s", err)
+	}
+
 	blueIndex := target.files["blue"]
 	if blueIndex == nil {
 		t.Errorf("No indexed rendered. %v", target.files)
@@ -66,5 +82,16 @@
 
 	if len(blueIndex) != 2 {
 		t.Errorf("Number of pages does not equal 2, got %d. %q", len(blueIndex), blueIndex)
+	}
+
+	for _, s := range []string{
+		"sd1/foo/index.html",
+		"sd2",
+		"sd3/index.html",
+		"sd4.php",
+	} {
+		if _, ok := target.files[s]; !ok {
+			t.Errorf("No alias rendered: %s", s)
+		}
 	}
 }
--- /dev/null
+++ b/target/alias_test.go
@@ -1,0 +1,31 @@
+package target
+
+import (
+	"testing"
+)
+
+func TestHTMLRedirectAlias(t *testing.T) {
+	var o Translator
+	o = new(HTMLRedirectAlias)
+
+	tests := []struct {
+		value    string
+		expected string
+	}{
+		{"", ""},
+		{"alias 1", "alias-1"},
+		{"alias 2/", "alias-2/index.html"},
+		{"alias 3.html", "alias-3.html"},
+	}
+
+	for _, test := range tests {
+		path, err := o.Translate(test.value)
+		if err != nil {
+			t.Fatalf("Translate returned an error: %s", err)
+		}
+
+		if path != test.expected {
+			t.Errorf("Expected: %s, got: %s", test.expected, path)
+		}
+	}
+}
--- /dev/null
+++ b/target/htmlredirect.go
@@ -1,0 +1,18 @@
+package target
+
+import (
+	helpers "github.com/spf13/hugo/template"
+	"path"
+	"strings"
+)
+
+type HTMLRedirectAlias struct {
+	PublishDir string
+}
+
+func (h *HTMLRedirectAlias) Translate(alias string) (aliasPath string, err error) {
+	if strings.HasSuffix(alias, "/") {
+		alias = alias + "index.html"
+	}
+	return path.Join(h.PublishDir, helpers.Urlize(alias)), nil
+}