Add ability to canonify URLs in rendered XML output.

This commit is contained in:
Ryan Martinsen 2014-12-18 14:59:39 -05:00 committed by bep
parent f5a3fb149f
commit 7dacc999f8
3 changed files with 50 additions and 1 deletions

View 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) {

View 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="" + 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)

View 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)
}