ref: 7dacc999f8c0bb2554ddae7a256928b4c499403b
parent: f5a3fb149fff3a44c2b3be8a0c46d02594d755c8
author: Ryan Martinsen <rmartinsen@about.com>
date: Thu Dec 18 09:59:39 EST 2014
Add ability to canonify URLs in rendered XML output.
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -1195,7 +1195,17 @@
func (s *Site) renderXML(name string, d interface{}, layouts ...string) (io.Reader, error) {renderBuffer := s.NewXMLBuffer()
err := s.render(name, d, renderBuffer, layouts...)
- return renderBuffer, err
+
+ var outBuffer = new(bytes.Buffer)
+
+ absURLInXML, err := transform.AbsURLInXML(viper.GetString("BaseUrl"))+ if err != nil {+ return nil, err
+ }
+
+ transformer := transform.NewChain(absURLInXML...)
+ transformer.Apply(outBuffer, renderBuffer)
+ return outBuffer, err
}
func (s *Site) renderPage(name string, d interface{}, layouts ...string) (io.Reader, error) {--- a/transform/absurl.go
+++ b/transform/absurl.go
@@ -31,6 +31,31 @@
return
}
+func AbsURLInXML(absURL string) (trs []link, err error) {+ var baseURL *url.URL
+
+ if baseURL, err = url.Parse(absURL); err != nil {+ return
+ }
+
+ base := strings.TrimRight(baseURL.String(), "/")
+
+ var (
+ srcedq = []byte(" src="" + base + "/")+ hrefedq = []byte(" href="" + base + "/")+ srcesq = []byte(" src='" + base + "/")+ hrefesq = []byte(" href='" + base + "/")+ )
+ trs = append(trs, func(content []byte) []byte {+ content = guardReplace(content, []byte(" src="//"), []byte(" src="/"), srcedq)+ content = guardReplace(content, []byte(" src='//"), []byte(" src='/"), srcesq)+ content = guardReplace(content, []byte(" href="//"), []byte(" href="/"), hrefedq)+ content = guardReplace(content, []byte(" href='//"), []byte(" href='/"), hrefesq)+ return content
+ })
+ return
+}
+
func guardReplace(content, guard, match, replace []byte) []byte { if !bytes.Contains(content, guard) {content = bytes.Replace(content, match, replace, -1)
--- a/transform/chain_test.go
+++ b/transform/chain_test.go
@@ -9,10 +9,18 @@
const CORRECT_OUTPUT_SRC_HREF_WITH_NAV = "<!DOCTYPE html><html><head><script src=\"http://two/foobar.js\"></script></head><body><nav><ul><li hugo-nav=\"section_0\"></li><li hugo-nav=\"section_1\"></li></ul></nav><article>content <a href=\"http://two/foobar\">foobar</a>. Follow up</article></body></html>"
+const H5_XML_CONTENT_ABS_URL = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?><feed xmlns=\"http://www.w3.org/2005/Atom\"><entry><content type=\"html\"><p><a href="/foobar">foobar</a></p> <p>A video: <iframe src='/foo'></iframe></p></content></entry></feed>"
+
+const CORRECT_OUTPUT_SRC_HREF_IN_XML = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?><feed xmlns=\"http://www.w3.org/2005/Atom\"><entry><content type=\"html\"><p><a href="http://xml/foobar">foobar</a></p> <p>A video: <iframe src='http://xml/foo'></iframe></p></content></entry></feed>"
+
var two_chain_tests = []test{ {H5_JS_CONTENT_ABS_URL_WITH_NAV, CORRECT_OUTPUT_SRC_HREF_WITH_NAV},}
+var xml_abs_url_tests = []test{+ {H5_XML_CONTENT_ABS_URL, CORRECT_OUTPUT_SRC_HREF_IN_XML},+}
+
func TestChainZeroTransformers(t *testing.T) {tr := NewChain()
in := new(bytes.Buffer)
@@ -30,4 +38,10 @@
for i := 0; i < b.N; i++ {apply(b.Errorf, tr, two_chain_tests)
}
+}
+
+func TestXMLAbsUrl(t *testing.T) {+ absURLInXML, _ := AbsURLInXML("http://xml")+ tr := NewChain(absURLInXML...)
+ apply(t.Errorf, tr, xml_abs_url_tests)
}
--
⑨