Move AbUrlify to post content transformation
authorNoah Campbell <noahcampbell@gmail.com>
Tue, 17 Sep 2013 21:16:06 +0000 (14:16 -0700)
committerNoah Campbell <noahcampbell@gmail.com>
Tue, 17 Sep 2013 21:16:06 +0000 (14:16 -0700)
Currently the a@href and script@src elements will have BaseUrl applied
to their elements prior to being written to disk.

hugolib/site.go
hugolib/site_test.go
hugolib/site_url_test.go
transform/post.go

index b3a3a7659000b96d552d03f9cb53012672c5316c..bfbb4ab24d1fce7411db62f8093f5c7639f39ec9 100644 (file)
@@ -14,6 +14,7 @@
 package hugolib
 
 import (
+       "io"
        "bitbucket.org/pkg/inflect"
        "bytes"
        "fmt"
@@ -21,6 +22,7 @@ import (
        "github.com/spf13/hugo/target"
        helpers "github.com/spf13/hugo/template"
        "github.com/spf13/hugo/template/bundle"
+       "github.com/spf13/hugo/transform"
        "github.com/spf13/nitro"
        "html/template"
        "os"
@@ -75,6 +77,7 @@ type Site struct {
        Info       SiteInfo
        Shortcodes map[string]ShortcodeFunc
        timer      *nitro.B
+       Transformer *transform.Transformer
        Target     target.Output
        Alias      target.AliasPublisher
 }
@@ -154,7 +157,6 @@ func (s *Site) Render() (err error) {
        s.timerStep("render and write aliases")
        s.ProcessShortcodes()
        s.timerStep("render shortcodes")
-       s.AbsUrlify()
        s.timerStep("absolute URLify")
        if err = s.RenderIndexes(); err != nil {
                return
@@ -246,20 +248,6 @@ func (s *Site) ProcessShortcodes() {
        }
 }
 
-func (s *Site) AbsUrlify() {
-       baseWithoutTrailingSlash := strings.TrimRight(s.Config.BaseUrl, "/")
-       baseWithSlash := baseWithoutTrailingSlash + "/"
-       for _, page := range s.Pages {
-               content := string(page.Content)
-               content = strings.Replace(content, " src=\"/", " src=\""+baseWithSlash, -1)
-               content = strings.Replace(content, " src='/", " src='"+baseWithSlash, -1)
-               content = strings.Replace(content, " href='/", " href='"+baseWithSlash, -1)
-               content = strings.Replace(content, " href=\"/", " href=\""+baseWithSlash, -1)
-               content = strings.Replace(content, baseWithoutTrailingSlash+"//", baseWithSlash, -1)
-               page.Content = template.HTML(content)
-       }
-}
-
 func (s *Site) CreatePages() (err error) {
        for _, file := range s.Source.Files() {
                page, err := ReadFrom(file.Contents, file.Name)
@@ -418,7 +406,7 @@ func (s *Site) RenderPages() error {
                if err != nil {
                        return err
                }
-               err = s.WritePublic(p.OutFile, content.Bytes())
+               err = s.WritePublic(p.OutFile, content)
                if err != nil {
                        return err
                }
@@ -447,7 +435,7 @@ func (s *Site) RenderIndexes() error {
 
                        var base string
                        base = plural + "/" + k
-                       err = s.WritePublic(base+".html", x.Bytes())
+                       err = s.WritePublic(base+".html", x)
                        if err != nil {
                                return err
                        }
@@ -458,7 +446,7 @@ func (s *Site) RenderIndexes() error {
                                n.Url = helpers.Urlize(plural + "/" + k + ".xml")
                                n.Permalink = permalink(s, n.Url)
                                s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
-                               err = s.WritePublic(base+".xml", y.Bytes())
+                               err = s.WritePublic(base+".xml", y)
                                if err != nil {
                                        return err
                                }
@@ -487,7 +475,7 @@ func (s *Site) RenderIndexesIndexes() (err error) {
                                return err
                        }
 
-                       err = s.WritePublic(plural+"/index.html", x.Bytes())
+                       err = s.WritePublic(plural+"/index.html", x)
                        if err != nil {
                                return err
                        }
@@ -511,7 +499,7 @@ func (s *Site) RenderLists() error {
                if err != nil {
                        return err
                }
-               err = s.WritePublic(section, content.Bytes())
+               err = s.WritePublic(section, content)
                if err != nil {
                        return err
                }
@@ -522,7 +510,7 @@ func (s *Site) RenderLists() error {
                        n.Permalink = template.HTML(string(n.Site.BaseUrl) + n.Url)
                        y := s.NewXMLBuffer()
                        s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
-                       err = s.WritePublic(section+"/index.xml", y.Bytes())
+                       err = s.WritePublic(section+"/index.xml", y)
                        return err
                }
        }
@@ -547,7 +535,7 @@ func (s *Site) RenderHomePage() error {
        if err != nil {
                return err
        }
-       err = s.WritePublic("/", x.Bytes())
+       err = s.WritePublic("/", x)
        if err != nil {
                return err
        }
@@ -559,7 +547,7 @@ func (s *Site) RenderHomePage() error {
                n.Permalink = permalink(s, "index.xml")
                y := s.NewXMLBuffer()
                s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
-               err = s.WritePublic("index.xml", y.Bytes())
+               err = s.WritePublic("index.xml", y)
                return err
        }
 
@@ -571,7 +559,7 @@ func (s *Site) RenderHomePage() error {
                if err != nil {
                        return err
                }
-               err = s.WritePublic("404.html", x.Bytes())
+               err = s.WritePublic("404.html", x)
                return err
        }
 
@@ -631,14 +619,19 @@ func (s *Site) initTarget() {
        }
 }
 
-func (s *Site) WritePublic(path string, content []byte) (err error) {
+func (s *Site) WritePublic(path string, content io.Reader) (err error) {
        s.initTarget()
 
        if s.Config.Verbose {
                fmt.Println(path)
        }
 
-       return s.Target.Publish(path, bytes.NewReader(content))
+       if s.Transformer == nil {
+               s.Transformer = &transform.Transformer{BaseURL: s.Config.BaseUrl}
+       }
+       final := new(bytes.Buffer)
+       s.Transformer.Apply(content, final)
+       return s.Target.Publish(path, final)
 }
 
 func (s *Site) WriteAlias(path string, permalink template.HTML) (err error) {
index bbcf0f80a9212cbe0ed2041943db8a102afee59f..38b384064549361c3ea2e8cec7d36e565f5c2f81 100644 (file)
@@ -19,6 +19,7 @@ var TEMPLATE_FUNC = "{{ .Title | urlize }}"
 var TEMPLATE_CONTENT = "{{ .Content }}"
 var TEMPLATE_DATE = "{{ .Date }}"
 var INVALID_TEMPLATE_FORMAT_DATE = "{{ .Date.Format time.RFC3339 }}"
+var TEMPLATE_WITH_URL = "<a href=\"foobar.jpg\">Going</a>"
 
 var PAGE_URL_SPECIFIED = `---
 title: simple template
@@ -185,3 +186,38 @@ func TestSetOutFile(t *testing.T) {
                t.Errorf("Outfile does not match.  Expected '%s', got '%s'", expected, p.OutFile)
        }
 }
+
+func TestAbsUrlify(t *testing.T) {
+       files := make(map[string][]byte)
+       target := &InMemoryTarget{files: files}
+       s := &Site{
+               Target: target,
+               Config: Config{BaseUrl: "http://auth/bub/"},
+               Source: &inMemorySource{urlFakeSource},
+       }
+       s.initializeSiteInfo()
+       s.prepTemplates()
+       must(s.addTemplate("blue/single.html", TEMPLATE_WITH_URL))
+
+       if err := s.CreatePages(); err != nil {
+               t.Fatalf("Unable to create pages: %s", err)
+       }
+
+       if err := s.BuildSiteMeta(); err != nil {
+               t.Fatalf("Unable to build site metadata: %s", err)
+       }
+
+       if err := s.RenderPages(); err != nil {
+               t.Fatalf("Unable to render pages. %s", err)
+       }
+
+       content, ok := target.files["content/blue/slug-doc-1.html"]
+       if !ok {
+               t.Fatalf("Unable to locate rendered content")
+       }
+
+       expected := "<html><head></head><body><a href=\"http://auth/bub/foobar.jpg\">Going</a></body></html>"
+       if string(content) != expected {
+               t.Errorf("Expected: %q, got: %q", expected, string(content))
+       }
+}
index 6d969fde22f444603fb8c7239da339cc359ace37..40a38eef695c0c1f128b4ac69469aa3a6d393496 100644 (file)
@@ -96,8 +96,9 @@ func TestPageCount(t *testing.T) {
                t.Errorf("No indexed rendered. %v", target.files)
        }
 
-       if len(blueIndex) != 2 {
-               t.Errorf("Number of pages does not equal 2, got %d. %q", len(blueIndex), blueIndex)
+       expected := "<html><head></head><body>..</body></html>"
+       if string(blueIndex) != expected {
+               t.Errorf("Index template does not match expected: %q, got: %q", expected, string(blueIndex))
        }
 
        for _, s := range []string{
index f54688cb2c9d628ff715ecc1bf2f9cbab60cb48b..f63f1683b5a5d5537265575d31976bbf60dff9f1 100644 (file)
@@ -17,14 +17,18 @@ func (t *Transformer) Apply(r io.Reader, w io.Writer) (err error) {
                return
        }
 
-       if err = t.absUrlify(tr); err != nil {
+       if err = t.absUrlify(tr, elattr{"a", "href"}, elattr{"script", "src"}); err != nil {
                return
        }
 
        return tr.Render(w)
 }
 
-func (t *Transformer) absUrlify(tr *htmltran.Transformer) (err error) {
+type elattr struct {
+       tag, attr string
+}
+
+func (t *Transformer) absUrlify(tr *htmltran.Transformer, selectors ...elattr) (err error) {
        var baseURL, inURL *url.URL
 
        if baseURL, err = url.Parse(t.BaseURL); err != nil {
@@ -38,9 +42,11 @@ func (t *Transformer) absUrlify(tr *htmltran.Transformer) (err error) {
                return baseURL.ResolveReference(inURL).String()
        }
 
-       if err = tr.Apply(htmltran.TransformAttrib("src", replace), "script"); err != nil {
-               return
+       for _, el := range selectors {
+               if err = tr.Apply(htmltran.TransformAttrib(el.attr, replace), el.tag); err != nil {
+                       return
+               }
        }
 
-       return tr.Apply(htmltran.TransformAttrib("href", replace), "a")
+       return
 }