Add `canonifyurls` config option.
authorPhil Pennock <pdp@spodhuis.org>
Fri, 3 Jan 2014 23:36:53 +0000 (18:36 -0500)
committerspf13 <steve.francia@gmail.com>
Mon, 13 Jan 2014 15:06:12 +0000 (10:06 -0500)
Be able to inhibit AbsURL canonicalization of content, on a site
configuration basis. Advantages of being able to inhibit this include
making it easier to rendering on other hostnames, and being able to
include resources on http or https depending on how this page was
retrieved, avoiding mixed-mode client complaints without adding latency
for plain http.

docs/content/extras/urls.md [new file with mode: 0644]
docs/content/overview/configuration.md
hugolib/config.go
hugolib/site.go
hugolib/site_test.go
transform/chain.go

diff --git a/docs/content/extras/urls.md b/docs/content/extras/urls.md
new file mode 100644 (file)
index 0000000..b386eff
--- /dev/null
@@ -0,0 +1,21 @@
+---
+title: "URLs"
+date: "2014-01-03"
+aliases:
+  - "/doc/urls/"
+groups: ["extras"]
+groups_weight: 40
+---
+By default, all relative URLs encountered in the input will be canonicalized
+using `baseurl`, so that a link `/css/foo.css` becomes
+`http://yoursite.example.com/css/foo.css`.
+
+Setting `canonifyurls` to `false` will prevent this canonicalization.
+
+Benefits of canonicalization include fixing all URLs to be absolute, which may
+aid with some parsing tasks.  Note though that all real browsers handle this
+client-side without issues.
+
+Benefits of non-canonicalization include being able to have resource inclusion
+be scheme-relative, so that http vs https can be decided based on how this
+page was retrieved.
index 5721df13301c1a254c47fea6eccf53a82a9f89af..30a33a7c700b32fdbb0238688a04a09ed2ad1af9 100644 (file)
@@ -30,6 +30,7 @@ indexes:
    category: "categories"
    tag: "tags"
 baseurl: "http://yoursite.example.com/"
+canonifyurls: true
 ...
 {{% /highlight %}}
 
@@ -46,6 +47,7 @@ The following is an example of a json config file with the default values:
        "tag": "tags"
     },
     "baseurl": "http://yoursite.example.com/"
+    "canonifyurls": true
 }
 {{% /highlight %}}
 
@@ -56,6 +58,7 @@ The following is an example of a toml config file with the default values:
     publishdir = "public"
     builddrafts = false
     baseurl = "http://yoursite.example.com/"
+    canonifyurls = true
     [indexes]
        category = "categories"
        tag = "tags"
index e2d3049372a708483e35b62a32c77af40040296e..f3e1d3ec9a8211764541b73bcee95546a799f27f 100644 (file)
@@ -36,6 +36,7 @@ type Config struct {
        Params                                     map[string]interface{}
        Permalinks                                 PermalinkOverrides
        BuildDrafts, UglyUrls, Verbose             bool
+       CanonifyUrls                                                       bool
 }
 
 var c Config
@@ -61,6 +62,7 @@ func SetupConfig(cfgfile *string, path *string) *Config {
        c.BuildDrafts = false
        c.UglyUrls = false
        c.Verbose = false
+       c.CanonifyUrls = true
 
        c.readInConfig()
 
index 3bc122e0a506689c496614ddf1daa90e846f5c86..3fd5b3d58872ef834f3315248360b744f6fe9a39 100644 (file)
@@ -573,11 +573,17 @@ func (s *Site) render(d interface{}, out string, layouts ...string) (err error)
                return
        }
 
-       absURL, err := transform.AbsURL(s.Config.BaseUrl)
-       if err != nil {
-               return
+       transformLinks := transform.NewEmptyTransforms()
+
+       if s.Config.CanonifyUrls {
+               absURL, err := transform.AbsURL(s.Config.BaseUrl)
+               if err != nil {
+                       return err
+               }
+               transformLinks = append(transformLinks, absURL...)
        }
-       transformer := transform.NewChain(absURL...)
+
+       transformer := transform.NewChain(transformLinks...)
 
        var renderBuffer *bytes.Buffer
 
index 5f6fe6e7f1421025df186b2b3dbc92cd3e95bcbe..a13ddec24de689ffb17c6f3a52c9f4e824554e13 100644 (file)
@@ -234,7 +234,11 @@ func TestSkipRender(t *testing.T) {
 
        s := &Site{
                Target: target,
-               Config: Config{Verbose: true, BaseUrl: "http://auth/bub"},
+               Config: Config{
+                       Verbose: true,
+                       BaseUrl: "http://auth/bub",
+                       CanonifyUrls: true,
+               },
                Source: &source.InMemorySource{sources},
        }
 
@@ -290,43 +294,52 @@ func TestAbsUrlify(t *testing.T) {
                {"sect/doc1.html", []byte("<!doctype html><html><head></head><body><a href=\"#frag1\">link</a></body></html>"), "sect"},
                {"content/blue/doc2.html", []byte("---\nf: t\n---\n<!doctype html><html><body>more content</body></html>"), "blue"},
        }
-       s := &Site{
-               Target: target,
-               Config: Config{BaseUrl: "http://auth/bub"},
-               Source: &source.InMemorySource{sources},
-       }
-       s.initializeSiteInfo()
-       s.prepTemplates()
-       must(s.addTemplate("blue/single.html", TEMPLATE_WITH_URL_ABS))
-
-       if err := s.CreatePages(); err != nil {
-               t.Fatalf("Unable to create pages: %s", err)
-       }
+       for _, canonify := range []bool{true, false} {
+               s := &Site{
+                       Target: target,
+                       Config: Config{
+                               BaseUrl: "http://auth/bub",
+                               CanonifyUrls: canonify,
+                       },
+                       Source: &source.InMemorySource{sources},
+               }
+               t.Logf("Rendering with BaseUrl %q and CanonifyUrls set %v", s.Config.BaseUrl, canonify)
+               s.initializeSiteInfo()
+               s.prepTemplates()
+               must(s.addTemplate("blue/single.html", TEMPLATE_WITH_URL_ABS))
 
-       if err := s.BuildSiteMeta(); err != nil {
-               t.Fatalf("Unable to build site metadata: %s", err)
-       }
+               if err := s.CreatePages(); err != nil {
+                       t.Fatalf("Unable to create pages: %s", err)
+               }
 
-       if err := s.RenderPages(); err != nil {
-               t.Fatalf("Unable to render pages. %s", err)
-       }
+               if err := s.BuildSiteMeta(); err != nil {
+                       t.Fatalf("Unable to build site metadata: %s", err)
+               }
 
-       tests := []struct {
-               file, expected string
-       }{
-               {"content/blue/doc2.html", "<a href=\"http://auth/bub/foobar.jpg\">Going</a>"},
-               {"sect/doc1.html", "<!doctype html><html><head></head><body><a href=\"#frag1\">link</a></body></html>"},
-       }
+               if err := s.RenderPages(); err != nil {
+                       t.Fatalf("Unable to render pages. %s", err)
+               }
 
-       for _, test := range tests {
-               content, ok := target.Files[test.file]
-               if !ok {
-                       t.Fatalf("Unable to locate rendered content: %s", test.file)
+               tests := []struct {
+                       file, expected string
+               }{
+                       {"content/blue/doc2.html", "<a href=\"http://auth/bub/foobar.jpg\">Going</a>"},
+                       {"sect/doc1.html", "<!doctype html><html><head></head><body><a href=\"#frag1\">link</a></body></html>"},
                }
 
-               expected := test.expected
-               if string(content) != expected {
-                       t.Errorf("AbsUrlify content expected:\n%q\ngot\n%q", expected, string(content))
+               for _, test := range tests {
+                       content, ok := target.Files[test.file]
+                       if !ok {
+                               t.Fatalf("Unable to locate rendered content: %s", test.file)
+                       }
+
+                       expected := test.expected
+                       if !canonify {
+                               expected = strings.Replace(expected, s.Config.BaseUrl, "", -1)
+                       }
+                       if string(content) != expected {
+                               t.Errorf("AbsUrlify content expected:\n%q\ngot\n%q", expected, string(content))
+                       }
                }
        }
 }
index fb3c2985c5300a42a68a9a83cb7eb664a6282480..c673c5d6a6729d52f470b9ecff9edcc0d7e15a02 100644 (file)
@@ -15,6 +15,10 @@ func NewChain(trs ...link) chain {
        return trs
 }
 
+func NewEmptyTransforms() []link {
+       return make([]link, 0, 20)
+}
+
 func (c *chain) Apply(w io.Writer, r io.Reader) (err error) {
 
        buffer := new(bytes.Buffer)