ref: 438c2198923022a3e4d299b06a7df18268041dd8
parent: 2ff108fcb7059dd9b73526b1bfce42b43579fc25
author: Phil Pennock <[email protected]>
date: Fri Jan 3 13:36:53 EST 2014
Add `canonifyurls` config option. 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.
--- /dev/null
+++ b/docs/content/extras/urls.md
@@ -1,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.
--- a/docs/content/overview/configuration.md
+++ b/docs/content/overview/configuration.md
@@ -30,6 +30,7 @@
category: "categories"
tag: "tags"
baseurl: "http://yoursite.example.com/"
+canonifyurls: true
...
{{% /highlight %}}
@@ -46,6 +47,7 @@
"tag": "tags"
},
"baseurl": "http://yoursite.example.com/"
+ "canonifyurls": true
}
{{% /highlight %}}
@@ -56,6 +58,7 @@
publishdir = "public"
builddrafts = false
baseurl = "http://yoursite.example.com/"
+ canonifyurls = true
[indexes]
category = "categories"
tag = "tags"
--- a/hugolib/config.go
+++ b/hugolib/config.go
@@ -36,6 +36,7 @@
Params map[string]interface{}
Permalinks PermalinkOverrides
BuildDrafts, UglyUrls, Verbose bool
+ CanonifyUrls bool
}
var c Config
@@ -61,6 +62,7 @@
c.BuildDrafts = false
c.UglyUrls = false
c.Verbose = false
+ c.CanonifyUrls = true
c.readInConfig()
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -573,11 +573,17 @@
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
--- a/hugolib/site_test.go
+++ b/hugolib/site_test.go
@@ -234,7 +234,11 @@
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 @@
{"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))
+ 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.CreatePages(); err != nil {
- t.Fatalf("Unable to create pages: %s", err)
- }
+ 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.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)
- }
+ if err := s.RenderPages(); err != nil {
+ t.Fatalf("Unable to render pages. %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>"},
- }
-
- 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))
+ }
}
}
}
--- a/transform/chain.go
+++ b/transform/chain.go
@@ -15,6 +15,10 @@
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)