shithub: hugo

Download patch

ref: f0eecc6a4f541838e9930c98bc982546f65c7a4f
parent: 768ec5df9fa8f91610ee80a9e6194f94a7dbe117
author: Bjørn Erik Pedersen <[email protected]>
date: Wed Jan 10 05:20:08 EST 2018

Fix non-ASCII path handling for Page resources

Fixes #4241

--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -228,9 +228,9 @@
 	permalink    string
 	relPermalink string
 
-	// relPermalink without extension and any base path element from the baseURL.
+	// relative target path without extension and any base path element from the baseURL.
 	// This is used to construct paths in the page resources.
-	relPermalinkBase string
+	relTargetPathBase string
 
 	layoutDescriptor output.LayoutDescriptor
 
@@ -989,8 +989,8 @@
 	return p.relPermalink
 }
 
-func (p *Page) subResourceLinkFactory(base string) string {
-	return path.Join(p.relPermalinkBase, base)
+func (p *Page) subResourceTargetPathFactory(base string) string {
+	return path.Join(p.relTargetPathBase, base)
 }
 
 func (p *Page) prepareForRender(cfg *BuildCfg) error {
--- a/hugolib/page_bundler_capture_test.go
+++ b/hugolib/page_bundler_capture_test.go
@@ -144,6 +144,7 @@
 __bundle/en/work/base/_index.md/resources/en/work/base/_1.png
 __bundle/en/work/base/a/b/index.md/resources/en/work/base/a/b/ab1.md
 __bundle/en/work/base/b/index.md/resources/en/work/base/b/1.md|en/work/base/b/2.md|en/work/base/b/c/logo.png|en/work/base/b/custom-mime.bep|en/work/base/b/sunset1.jpg|en/work/base/b/sunset2.jpg
+__bundle/en/work/base/c/index.md/resources/en/work/base/c/logo-은행.png
 C:
 /work/base/assets/pic1.png
 /work/base/assets/pic2.png
--- a/hugolib/page_bundler_handlers.go
+++ b/hugolib/page_bundler_handlers.go
@@ -319,7 +319,7 @@
 		}
 
 		resource, err := c.s.resourceSpec.NewResourceFromFilename(
-			ctx.parentPage.subResourceLinkFactory,
+			ctx.parentPage.subResourceTargetPathFactory,
 			c.s.absPublishDir(),
 			ctx.source.Filename(), ctx.target)
 
--- a/hugolib/page_bundler_test.go
+++ b/hugolib/page_bundler_test.go
@@ -51,6 +51,7 @@
 				cfg.Set("permalinks", map[string]string{
 					"a": ":sections/:filename",
 					"b": ":year/:slug/",
+					"c": ":sections/:slug",
 				})
 
 				cfg.Set("outputFormats", map[string]interface{}{
@@ -74,7 +75,7 @@
 				th := testHelper{s.Cfg, s.Fs, t}
 
 				// Singles (2), Below home (1), Bundle (1)
-				assert.Len(s.RegularPages, 6)
+				assert.Len(s.RegularPages, 7)
 
 				singlePage := s.getPage(KindPage, "a/1.md")
 
@@ -99,6 +100,8 @@
 				assert.NotNil(leafBundle1)
 				leafBundle2 := s.getPage(KindPage, "a/b/index.md")
 				assert.NotNil(leafBundle2)
+				unicodeBundle := s.getPage(KindPage, "c/index.md")
+				assert.NotNil(unicodeBundle)
 
 				pageResources := leafBundle1.Resources.ByType(pageResourceType)
 				assert.Len(pageResources, 2)
@@ -136,6 +139,11 @@
 
 					assert.Equal("/a/b.html", leafBundle2.RelPermalink())
 
+					// 은행
+					assert.Equal("/c/%EC%9D%80%ED%96%89.html", unicodeBundle.RelPermalink())
+					th.assertFileContent(filepath.FromSlash("/work/public/c/은행.html"), "Content for 은행")
+					th.assertFileContent(filepath.FromSlash("/work/public/c/은행/logo-은행.png"), "은행 PNG")
+
 				} else {
 					assert.Equal("/2017/pageslug/", leafBundle1.RelPermalink())
 					th.assertFileContent(filepath.FromSlash("/work/public/2017/pageslug/index.html"), "TheContent")
@@ -142,6 +150,7 @@
 					th.assertFileContent(filepath.FromSlash("/work/public/cpath/2017/pageslug/cindex.html"), "TheContent")
 
 					assert.Equal("/a/b/", leafBundle2.RelPermalink())
+
 				}
 
 			})
@@ -260,6 +269,18 @@
 	writeSource(t, fs, filepath.Join(workDir, "base", "b", "2.md"), pageContent)
 	writeSource(t, fs, filepath.Join(workDir, "base", "b", "custom-mime.bep"), "bepsays")
 	writeSource(t, fs, filepath.Join(workDir, "base", "b", "c", "logo.png"), "content")
+
+	// Bundle with 은행 slug
+	// See https://github.com/gohugoio/hugo/issues/4241
+	writeSource(t, fs, filepath.Join(workDir, "base", "c", "index.md"), `---
+title: "은행 은행"
+slug: 은행
+date: 2017-10-09
+---
+
+Content for 은행.
+`)
+	writeSource(t, fs, filepath.Join(workDir, "base", "c", "logo-은행.png"), "은행 PNG")
 
 	// Write a real image into one of the bundle above.
 	src, err := os.Open("testdata/sunset.jpg")
--- a/hugolib/page_paths.go
+++ b/hugolib/page_paths.go
@@ -129,7 +129,8 @@
 	if len(p.outputFormats) == 0 {
 		p.outputFormats = p.s.outputFormats[p.Kind]
 	}
-	rel := p.createRelativePermalink()
+	target := filepath.ToSlash(p.createRelativeTargetPath())
+	rel := p.s.PathSpec.URLizeFilename(target)
 
 	var err error
 	f := p.outputFormats[0]
@@ -138,7 +139,7 @@
 		return err
 	}
 
-	p.relPermalinkBase = strings.TrimSuffix(rel, f.MediaType.FullSuffix())
+	p.relTargetPathBase = strings.TrimSuffix(target, f.MediaType.FullSuffix())
 	p.relPermalink = p.s.PathSpec.PrependBasePath(rel)
 	p.layoutDescriptor = p.createLayoutDescriptor()
 	return nil
@@ -267,7 +268,7 @@
 	return d.PathSpec.MakePathSanitized(pagePath)
 }
 
-func (p *Page) createRelativePermalink() string {
+func (p *Page) createRelativeTargetPath() string {
 
 	if len(p.outputFormats) == 0 {
 		if p.Kind == kindUnknown {
@@ -279,11 +280,15 @@
 	// Choose the main output format. In most cases, this will be HTML.
 	f := p.outputFormats[0]
 
-	return p.createRelativePermalinkForOutputFormat(f)
+	return p.createRelativeTargetPathForOutputFormat(f)
 
 }
 
 func (p *Page) createRelativePermalinkForOutputFormat(f output.Format) string {
+	return p.s.PathSpec.URLizeFilename(p.createRelativeTargetPathForOutputFormat(f))
+}
+
+func (p *Page) createRelativeTargetPathForOutputFormat(f output.Format) string {
 	tp, err := p.createTargetPath(f, p.s.owner.IsMultihost())
 
 	if err != nil {
@@ -296,7 +301,7 @@
 		tp = strings.TrimSuffix(tp, f.BaseFilename())
 	}
 
-	return p.s.PathSpec.URLizeFilename(tp)
+	return tp
 }
 
 func (p *Page) TargetPath() (outfile string) {
--- a/resource/image.go
+++ b/resource/image.go
@@ -185,7 +185,7 @@
 }
 
 func (i *Image) isJPEG() bool {
-	name := strings.ToLower(i.rel)
+	name := strings.ToLower(i.relTargetPath)
 	return strings.HasSuffix(name, ".jpg") || strings.HasSuffix(name, ".jpeg")
 }
 
@@ -206,7 +206,7 @@
 		conf.Filter = imageFilters[conf.FilterStr]
 	}
 
-	key := i.relPermalinkForRel(i.filenameFromConfig(conf), false)
+	key := i.relTargetPathForRel(i.filenameFromConfig(conf), false)
 
 	return i.spec.imageCache.getOrCreate(i.spec, key, func(resourceCacheFilename string) (*Image, error) {
 		ci := i.clone()
@@ -521,11 +521,11 @@
 }
 
 func (i *Image) setBasePath(conf imageConfig) {
-	i.rel = i.filenameFromConfig(conf)
+	i.relTargetPath = i.filenameFromConfig(conf)
 }
 
 func (i *Image) filenameFromConfig(conf imageConfig) string {
-	p1, p2 := helpers.FileAndExt(i.rel)
+	p1, p2 := helpers.FileAndExt(i.relTargetPath)
 	idStr := fmt.Sprintf("_hu%s_%d", i.hash, i.osFileInfo.Size())
 
 	// Do not change for no good reason.
--- a/resource/resource.go
+++ b/resource/resource.go
@@ -112,15 +112,16 @@
 }
 
 func (r *Spec) NewResourceFromFile(
-	linker func(base string) string,
+	targetPathBuilder func(base string) string,
 	absPublishDir string,
 	file source.File, relTargetFilename string) (Resource, error) {
 
-	return r.newResource(linker, absPublishDir, file.Filename(), file.FileInfo(), relTargetFilename)
+	return r.newResource(targetPathBuilder, absPublishDir, file.Filename(), file.FileInfo(), relTargetFilename)
 }
 
+//  p.s.PathSpec.URLizeFilename
 func (r *Spec) NewResourceFromFilename(
-	linker func(base string) string,
+	targetPathBuilder func(base string) string,
 	absPublishDir,
 	absSourceFilename, relTargetFilename string) (Resource, error) {
 
@@ -128,11 +129,11 @@
 	if err != nil {
 		return nil, err
 	}
-	return r.newResource(linker, absPublishDir, absSourceFilename, fi, relTargetFilename)
+	return r.newResource(targetPathBuilder, absPublishDir, absSourceFilename, fi, relTargetFilename)
 }
 
 func (r *Spec) newResource(
-	linker func(base string) string,
+	targetPathBuilder func(base string) string,
 	absPublishDir,
 	absSourceFilename string, fi os.FileInfo, relTargetFilename string) (Resource, error) {
 
@@ -150,7 +151,7 @@
 		}
 	}
 
-	gr := r.newGenericResource(linker, fi, absPublishDir, absSourceFilename, filepath.ToSlash(relTargetFilename), mimeType)
+	gr := r.newGenericResource(targetPathBuilder, fi, absPublishDir, absSourceFilename, filepath.ToSlash(relTargetFilename), mimeType)
 
 	if mimeType == "image" {
 		f, err := r.Fs.Source.Open(absSourceFilename)
@@ -203,7 +204,7 @@
 // genericResource represents a generic linkable resource.
 type genericResource struct {
 	// The relative path to this resource.
-	rel string
+	relTargetPath string
 
 	// Base is set when the output format's path has a offset, e.g. for AMP.
 	base string
@@ -214,16 +215,16 @@
 	resourceType      string
 	osFileInfo        os.FileInfo
 
-	spec *Spec
-	link func(rel string) string
+	spec              *Spec
+	targetPathBuilder func(rel string) string
 }
 
 func (l *genericResource) Permalink() string {
-	return l.spec.PermalinkForBaseURL(l.relPermalinkForRel(l.rel, false), l.spec.BaseURL.String())
+	return l.spec.PermalinkForBaseURL(l.relPermalinkForRel(l.relTargetPath, false), l.spec.BaseURL.String())
 }
 
 func (l *genericResource) RelPermalink() string {
-	return l.relPermalinkForRel(l.rel, true)
+	return l.relPermalinkForRel(l.relTargetPath, true)
 }
 
 // Implement the Cloner interface.
@@ -233,8 +234,12 @@
 }
 
 func (l *genericResource) relPermalinkForRel(rel string, addBasePath bool) string {
-	if l.link != nil {
-		rel = l.link(rel)
+	return l.spec.PathSpec.URLizeFilename(l.relTargetPathForRel(rel, addBasePath))
+}
+
+func (l *genericResource) relTargetPathForRel(rel string, addBasePath bool) string {
+	if l.targetPathBuilder != nil {
+		rel = l.targetPathBuilder(rel)
 	}
 
 	if l.base != "" {
@@ -249,7 +254,7 @@
 		rel = "/" + rel
 	}
 
-	return l.spec.PathSpec.URLizeFilename(rel)
+	return rel
 }
 
 func (l *genericResource) ResourceType() string {
@@ -273,7 +278,7 @@
 }
 
 func (l *genericResource) target() string {
-	target := l.relPermalinkForRel(l.rel, false)
+	target := l.relTargetPathForRel(l.relTargetPath, false)
 	if l.spec.PathSpec.Languages.IsMultihost() {
 		target = path.Join(l.spec.PathSpec.Language.Lang, target)
 	}
@@ -281,7 +286,7 @@
 }
 
 func (r *Spec) newGenericResource(
-	linker func(base string) string,
+	targetPathBuilder func(base string) string,
 	osFileInfo os.FileInfo,
 	absPublishDir,
 	absSourceFilename,
@@ -289,11 +294,11 @@
 	resourceType string) *genericResource {
 
 	return &genericResource{
-		link:              linker,
+		targetPathBuilder: targetPathBuilder,
 		osFileInfo:        osFileInfo,
 		absPublishDir:     absPublishDir,
 		absSourceFilename: absSourceFilename,
-		rel:               baseFilename,
+		relTargetPath:     baseFilename,
 		resourceType:      resourceType,
 		spec:              r,
 	}