Add ability to canonify URLs in rendered XML output.
authorRyan Martinsen <rmartinsen@about.com>
Thu, 18 Dec 2014 19:59:39 +0000 (14:59 -0500)
committerbep <bjorn.erik.pedersen@gmail.com>
Fri, 26 Dec 2014 15:24:28 +0000 (16:24 +0100)
hugolib/site.go
transform/absurl.go
transform/chain_test.go

index 6ff64b48e7f4da5adc39f6f68521f588c7fac277..172ac8d30dd17eaa529828c7dd42cacfaff75446 100644 (file)
@@ -1195,7 +1195,17 @@ func (s *Site) layoutExists(layouts ...string) bool {
 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) {
index 6fb1cb4a1aeb73d5c61392d42a79593755a91b75..0a0cd7239b463727d449bea2346485c947f3c988 100644 (file)
@@ -31,6 +31,31 @@ func AbsURL(absURL string) (trs []link, err error) {
        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=&#34;" + base + "/")
+               hrefedq = []byte(" href=&#34;" + base + "/")
+               srcesq  = []byte(" src=&#39;" + base + "/")
+               hrefesq = []byte(" href=&#39;" + base + "/")
+       )
+       trs = append(trs, func(content []byte) []byte {
+               content = guardReplace(content, []byte(" src=&#34;//"), []byte(" src=&#34;/"), srcedq)
+               content = guardReplace(content, []byte(" src=&#39;//"), []byte(" src=&#39;/"), srcesq)
+               content = guardReplace(content, []byte(" href=&#34;//"), []byte(" href=&#34;/"), hrefedq)
+               content = guardReplace(content, []byte(" href=&#39;//"), []byte(" href=&#39;/"), hrefesq)
+               return content
+       })
+       return
+}
+
 func guardReplace(content, guard, match, replace []byte) []byte {
        if !bytes.Contains(content, guard) {
                content = bytes.Replace(content, match, replace, -1)
index 94135f6d7232b5830d1bdfa5593a7c4724643aa1..936a6a1ad7ebf28b49560c6b5a1c7a3eda40bddd 100644 (file)
@@ -9,10 +9,18 @@ const H5_JS_CONTENT_ABS_URL_WITH_NAV = "<!DOCTYPE html><html><head><script src=\
 
 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\">&lt;p&gt;&lt;a href=&#34;/foobar&#34;&gt;foobar&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A video: &lt;iframe src=&#39;/foo&#39;&gt;&lt;/iframe&gt;&lt;/p&gt;</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\">&lt;p&gt;&lt;a href=&#34;http://xml/foobar&#34;&gt;foobar&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A video: &lt;iframe src=&#39;http://xml/foo&#39;&gt;&lt;/iframe&gt;&lt;/p&gt;</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)
@@ -31,3 +39,9 @@ func BenchmarkChain(b *testing.B) {
                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)
+}