mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Move AbUrlify to post content transformation
Currently the a@href and script@src elements will have BaseUrl applied to their elements prior to being written to disk.
This commit is contained in:
parent
c6fe87b14e
commit
6b0752e8c0
4 changed files with 69 additions and 33 deletions
|
@ -14,6 +14,7 @@
|
||||||
package hugolib
|
package hugolib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"bitbucket.org/pkg/inflect"
|
"bitbucket.org/pkg/inflect"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -21,6 +22,7 @@ import (
|
||||||
"github.com/spf13/hugo/target"
|
"github.com/spf13/hugo/target"
|
||||||
helpers "github.com/spf13/hugo/template"
|
helpers "github.com/spf13/hugo/template"
|
||||||
"github.com/spf13/hugo/template/bundle"
|
"github.com/spf13/hugo/template/bundle"
|
||||||
|
"github.com/spf13/hugo/transform"
|
||||||
"github.com/spf13/nitro"
|
"github.com/spf13/nitro"
|
||||||
"html/template"
|
"html/template"
|
||||||
"os"
|
"os"
|
||||||
|
@ -75,6 +77,7 @@ type Site struct {
|
||||||
Info SiteInfo
|
Info SiteInfo
|
||||||
Shortcodes map[string]ShortcodeFunc
|
Shortcodes map[string]ShortcodeFunc
|
||||||
timer *nitro.B
|
timer *nitro.B
|
||||||
|
Transformer *transform.Transformer
|
||||||
Target target.Output
|
Target target.Output
|
||||||
Alias target.AliasPublisher
|
Alias target.AliasPublisher
|
||||||
}
|
}
|
||||||
|
@ -154,7 +157,6 @@ func (s *Site) Render() (err error) {
|
||||||
s.timerStep("render and write aliases")
|
s.timerStep("render and write aliases")
|
||||||
s.ProcessShortcodes()
|
s.ProcessShortcodes()
|
||||||
s.timerStep("render shortcodes")
|
s.timerStep("render shortcodes")
|
||||||
s.AbsUrlify()
|
|
||||||
s.timerStep("absolute URLify")
|
s.timerStep("absolute URLify")
|
||||||
if err = s.RenderIndexes(); err != nil {
|
if err = s.RenderIndexes(); err != nil {
|
||||||
return
|
return
|
||||||
|
@ -246,20 +248,6 @@ func (s *Site) ProcessShortcodes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) AbsUrlify() {
|
|
||||||
baseWithoutTrailingSlash := strings.TrimRight(s.Config.BaseUrl, "/")
|
|
||||||
baseWithSlash := baseWithoutTrailingSlash + "/"
|
|
||||||
for _, page := range s.Pages {
|
|
||||||
content := string(page.Content)
|
|
||||||
content = strings.Replace(content, " src=\"/", " src=\""+baseWithSlash, -1)
|
|
||||||
content = strings.Replace(content, " src='/", " src='"+baseWithSlash, -1)
|
|
||||||
content = strings.Replace(content, " href='/", " href='"+baseWithSlash, -1)
|
|
||||||
content = strings.Replace(content, " href=\"/", " href=\""+baseWithSlash, -1)
|
|
||||||
content = strings.Replace(content, baseWithoutTrailingSlash+"//", baseWithSlash, -1)
|
|
||||||
page.Content = template.HTML(content)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Site) CreatePages() (err error) {
|
func (s *Site) CreatePages() (err error) {
|
||||||
for _, file := range s.Source.Files() {
|
for _, file := range s.Source.Files() {
|
||||||
page, err := ReadFrom(file.Contents, file.Name)
|
page, err := ReadFrom(file.Contents, file.Name)
|
||||||
|
@ -418,7 +406,7 @@ func (s *Site) RenderPages() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = s.WritePublic(p.OutFile, content.Bytes())
|
err = s.WritePublic(p.OutFile, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -447,7 +435,7 @@ func (s *Site) RenderIndexes() error {
|
||||||
|
|
||||||
var base string
|
var base string
|
||||||
base = plural + "/" + k
|
base = plural + "/" + k
|
||||||
err = s.WritePublic(base+".html", x.Bytes())
|
err = s.WritePublic(base+".html", x)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -458,7 +446,7 @@ func (s *Site) RenderIndexes() error {
|
||||||
n.Url = helpers.Urlize(plural + "/" + k + ".xml")
|
n.Url = helpers.Urlize(plural + "/" + k + ".xml")
|
||||||
n.Permalink = permalink(s, n.Url)
|
n.Permalink = permalink(s, n.Url)
|
||||||
s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
|
s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
|
||||||
err = s.WritePublic(base+".xml", y.Bytes())
|
err = s.WritePublic(base+".xml", y)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -487,7 +475,7 @@ func (s *Site) RenderIndexesIndexes() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.WritePublic(plural+"/index.html", x.Bytes())
|
err = s.WritePublic(plural+"/index.html", x)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -511,7 +499,7 @@ func (s *Site) RenderLists() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = s.WritePublic(section, content.Bytes())
|
err = s.WritePublic(section, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -522,7 +510,7 @@ func (s *Site) RenderLists() error {
|
||||||
n.Permalink = template.HTML(string(n.Site.BaseUrl) + n.Url)
|
n.Permalink = template.HTML(string(n.Site.BaseUrl) + n.Url)
|
||||||
y := s.NewXMLBuffer()
|
y := s.NewXMLBuffer()
|
||||||
s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
|
s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
|
||||||
err = s.WritePublic(section+"/index.xml", y.Bytes())
|
err = s.WritePublic(section+"/index.xml", y)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -547,7 +535,7 @@ func (s *Site) RenderHomePage() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = s.WritePublic("/", x.Bytes())
|
err = s.WritePublic("/", x)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -559,7 +547,7 @@ func (s *Site) RenderHomePage() error {
|
||||||
n.Permalink = permalink(s, "index.xml")
|
n.Permalink = permalink(s, "index.xml")
|
||||||
y := s.NewXMLBuffer()
|
y := s.NewXMLBuffer()
|
||||||
s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
|
s.Tmpl.ExecuteTemplate(y, "rss.xml", n)
|
||||||
err = s.WritePublic("index.xml", y.Bytes())
|
err = s.WritePublic("index.xml", y)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +559,7 @@ func (s *Site) RenderHomePage() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = s.WritePublic("404.html", x.Bytes())
|
err = s.WritePublic("404.html", x)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,14 +619,19 @@ func (s *Site) initTarget() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) WritePublic(path string, content []byte) (err error) {
|
func (s *Site) WritePublic(path string, content io.Reader) (err error) {
|
||||||
s.initTarget()
|
s.initTarget()
|
||||||
|
|
||||||
if s.Config.Verbose {
|
if s.Config.Verbose {
|
||||||
fmt.Println(path)
|
fmt.Println(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.Target.Publish(path, bytes.NewReader(content))
|
if s.Transformer == nil {
|
||||||
|
s.Transformer = &transform.Transformer{BaseURL: s.Config.BaseUrl}
|
||||||
|
}
|
||||||
|
final := new(bytes.Buffer)
|
||||||
|
s.Transformer.Apply(content, final)
|
||||||
|
return s.Target.Publish(path, final)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) WriteAlias(path string, permalink template.HTML) (err error) {
|
func (s *Site) WriteAlias(path string, permalink template.HTML) (err error) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ var TEMPLATE_FUNC = "{{ .Title | urlize }}"
|
||||||
var TEMPLATE_CONTENT = "{{ .Content }}"
|
var TEMPLATE_CONTENT = "{{ .Content }}"
|
||||||
var TEMPLATE_DATE = "{{ .Date }}"
|
var TEMPLATE_DATE = "{{ .Date }}"
|
||||||
var INVALID_TEMPLATE_FORMAT_DATE = "{{ .Date.Format time.RFC3339 }}"
|
var INVALID_TEMPLATE_FORMAT_DATE = "{{ .Date.Format time.RFC3339 }}"
|
||||||
|
var TEMPLATE_WITH_URL = "<a href=\"foobar.jpg\">Going</a>"
|
||||||
|
|
||||||
var PAGE_URL_SPECIFIED = `---
|
var PAGE_URL_SPECIFIED = `---
|
||||||
title: simple template
|
title: simple template
|
||||||
|
@ -185,3 +186,38 @@ func TestSetOutFile(t *testing.T) {
|
||||||
t.Errorf("Outfile does not match. Expected '%s', got '%s'", expected, p.OutFile)
|
t.Errorf("Outfile does not match. Expected '%s', got '%s'", expected, p.OutFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAbsUrlify(t *testing.T) {
|
||||||
|
files := make(map[string][]byte)
|
||||||
|
target := &InMemoryTarget{files: files}
|
||||||
|
s := &Site{
|
||||||
|
Target: target,
|
||||||
|
Config: Config{BaseUrl: "http://auth/bub/"},
|
||||||
|
Source: &inMemorySource{urlFakeSource},
|
||||||
|
}
|
||||||
|
s.initializeSiteInfo()
|
||||||
|
s.prepTemplates()
|
||||||
|
must(s.addTemplate("blue/single.html", TEMPLATE_WITH_URL))
|
||||||
|
|
||||||
|
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.RenderPages(); err != nil {
|
||||||
|
t.Fatalf("Unable to render pages. %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
content, ok := target.files["content/blue/slug-doc-1.html"]
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Unable to locate rendered content")
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := "<html><head></head><body><a href=\"http://auth/bub/foobar.jpg\">Going</a></body></html>"
|
||||||
|
if string(content) != expected {
|
||||||
|
t.Errorf("Expected: %q, got: %q", expected, string(content))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -96,8 +96,9 @@ func TestPageCount(t *testing.T) {
|
||||||
t.Errorf("No indexed rendered. %v", target.files)
|
t.Errorf("No indexed rendered. %v", target.files)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(blueIndex) != 2 {
|
expected := "<html><head></head><body>..</body></html>"
|
||||||
t.Errorf("Number of pages does not equal 2, got %d. %q", len(blueIndex), blueIndex)
|
if string(blueIndex) != expected {
|
||||||
|
t.Errorf("Index template does not match expected: %q, got: %q", expected, string(blueIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range []string{
|
for _, s := range []string{
|
||||||
|
|
|
@ -17,14 +17,18 @@ func (t *Transformer) Apply(r io.Reader, w io.Writer) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = t.absUrlify(tr); err != nil {
|
if err = t.absUrlify(tr, elattr{"a", "href"}, elattr{"script", "src"}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return tr.Render(w)
|
return tr.Render(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transformer) absUrlify(tr *htmltran.Transformer) (err error) {
|
type elattr struct {
|
||||||
|
tag, attr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transformer) absUrlify(tr *htmltran.Transformer, selectors ...elattr) (err error) {
|
||||||
var baseURL, inURL *url.URL
|
var baseURL, inURL *url.URL
|
||||||
|
|
||||||
if baseURL, err = url.Parse(t.BaseURL); err != nil {
|
if baseURL, err = url.Parse(t.BaseURL); err != nil {
|
||||||
|
@ -38,9 +42,11 @@ func (t *Transformer) absUrlify(tr *htmltran.Transformer) (err error) {
|
||||||
return baseURL.ResolveReference(inURL).String()
|
return baseURL.ResolveReference(inURL).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = tr.Apply(htmltran.TransformAttrib("src", replace), "script"); err != nil {
|
for _, el := range selectors {
|
||||||
return
|
if err = tr.Apply(htmltran.TransformAttrib(el.attr, replace), el.tag); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tr.Apply(htmltran.TransformAttrib("href", replace), "a")
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue