tpl/path: Add path.BaseName function

Closes #9973
This commit is contained in:
Joe Mooring 2022-06-04 13:40:32 -07:00 committed by Bjørn Erik Pedersen
parent 8e2fd55923
commit 953f215f32
9 changed files with 77 additions and 6 deletions

View file

@ -12,7 +12,7 @@ keywords: [path, base]
signature: ["path.Base PATH"]
workson: []
hugoversion: "0.40"
relatedfuncs: [path.Dir, path.Ext, path.Split]
relatedfuncs: [path.BaseName, path.Clean, path.Dir, path.Ext, path.Join, path.Split]
deprecated: false
---

View file

@ -0,0 +1,24 @@
---
title: path.BaseName
description: BaseName returns the last element of a path, removing the extension if present.
date: 2022-06-04
categories: [functions]
menu:
docs:
parent: "functions"
keywords: [path, base]
signature: ["path.BaseName PATH"]
relatedfuncs: [path.Base, path.Clean, path.Dir, path.Ext, path.Join, path.Split]
deprecated: false
---
If `PATH` is empty, `.` is returned.
**Note:** On Windows, `PATH` is converted to slash (`/`) separators.
```go-html-template
{{ path.BaseName "a/news.html" }} → "news"
{{ path.BaseName "news.html" }} → "news"
{{ path.BaseName "a/b/c" }} → "c"
{{ path.BaseName "/x/y/z/" }} → "z"
```

View file

@ -8,8 +8,9 @@ categories: [functions]
menu:
docs:
parent: "functions"
keywords: [path]
keywords: [path, clean]
signature: ["path.Clean PATH"]
relatedfuncs: [path.Base, path.BaseName, path.Dir, path.Ext, path.Join, path.Split]
---
`path.Clean` replaces path separators with slashes (`/`) and removes extraneous separators, including trailing separators.

View file

@ -12,7 +12,7 @@ keywords: [path, dir]
signature: ["path.Dir PATH"]
workson: []
hugoversion: "0.40"
relatedfuncs: [path.Base, path.Ext, path.Split]
relatedfuncs: [path.Base, path.BaseName, path.Clean, path.Ext, path.Join, path.Split]
deprecated: false
---

View file

@ -12,7 +12,7 @@ keywords: [path, ext, extension]
signature: ["path.Ext PATH"]
workson: []
hugoversion: "0.40"
relatedfuncs: [path.Base, path.Dir, path.Split]
relatedfuncs: [path.Base, path.BaseName, path.Clean, path.Dir, path.Join, path.Split]
deprecated: false
---

View file

@ -12,7 +12,7 @@ keywords: [path, join]
signature: ["path.Join ELEMENT..."]
workson: []
hugoversion: "0.39"
relatedfuncs: [path.Split]
relatedfuncs: [path.Base, path.BaseName, path.Clean, path.Dir, path.Ext, path.Split]
deprecated: false
---

View file

@ -12,7 +12,7 @@ keywords: [path, split]
signature: ["path.Split PATH"]
workson: []
hugoversion: "0.39"
relatedfuncs: [path.Split]
relatedfuncs: [path.Base, path.BaseName, path.Clean, path.Dir, path.Ext, path.Join]
deprecated: false
---

View file

@ -18,6 +18,7 @@ import (
"fmt"
_path "path"
"path/filepath"
"strings"
"github.com/gohugoio/hugo/deps"
"github.com/spf13/cast"
@ -94,6 +95,21 @@ func (ns *Namespace) Base(path any) (string, error) {
return _path.Base(spath), nil
}
// BaseName returns the last element of path, removing the extension if present.
// Trailing slashes are removed before extracting the last element.
// If the path is empty, Base returns ".".
// If the path consists entirely of slashes, Base returns "/".
// The input path is passed into filepath.ToSlash converting any Windows slashes
// to forward slashes.
func (ns *Namespace) BaseName(path any) (string, error) {
spath, err := cast.ToStringE(path)
if err != nil {
return "", err
}
spath = filepath.ToSlash(spath)
return strings.TrimSuffix(_path.Base(spath), _path.Ext(spath)), nil
}
// Split splits path immediately following the final slash,
// separating it into a directory and file name component.
// If there is no slash in path, Split returns an empty dir and

View file

@ -56,6 +56,36 @@ func TestBase(t *testing.T) {
}
}
func TestBaseName(t *testing.T) {
t.Parallel()
c := qt.New(t)
for _, test := range []struct {
path any
expect any
}{
{filepath.FromSlash(`foo/bar.txt`), `bar`},
{filepath.FromSlash(`foo/bar/txt `), `txt `},
{filepath.FromSlash(`foo/bar.t`), `bar`},
{`foo.bar.txt`, `foo.bar`},
{`.x`, ``},
{``, `.`},
// errors
{tstNoStringer{}, false},
} {
result, err := ns.BaseName(test.path)
if b, ok := test.expect.(bool); ok && !b {
c.Assert(err, qt.Not(qt.IsNil))
continue
}
c.Assert(err, qt.IsNil)
c.Assert(result, qt.Equals, test.expect)
}
}
func TestDir(t *testing.T) {
t.Parallel()
c := qt.New(t)