github.com/kristoff-it/hugo@v0.47.1/tpl/path/path.go (about) 1 // Copyright 2018 The Hugo Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package path 15 16 import ( 17 "fmt" 18 _path "path" 19 "path/filepath" 20 21 "github.com/gohugoio/hugo/deps" 22 "github.com/spf13/cast" 23 ) 24 25 // New returns a new instance of the path-namespaced template functions. 26 func New(deps *deps.Deps) *Namespace { 27 return &Namespace{ 28 deps: deps, 29 } 30 } 31 32 // Namespace provides template functions for the "os" namespace. 33 type Namespace struct { 34 deps *deps.Deps 35 } 36 37 // DirFile holds the result from path.Split. 38 type DirFile struct { 39 Dir string 40 File string 41 } 42 43 // Used in test. 44 func (df DirFile) String() string { 45 return fmt.Sprintf("%s|%s", df.Dir, df.File) 46 } 47 48 // Ext returns the file name extension used by path. 49 // The extension is the suffix beginning at the final dot 50 // in the final slash-separated element of path; 51 // it is empty if there is no dot. 52 // The input path is passed into filepath.ToSlash converting any Windows slashes 53 // to forward slashes. 54 func (ns *Namespace) Ext(path interface{}) (string, error) { 55 spath, err := cast.ToStringE(path) 56 if err != nil { 57 return "", err 58 } 59 spath = filepath.ToSlash(spath) 60 return _path.Ext(spath), nil 61 } 62 63 // Dir returns all but the last element of path, typically the path's directory. 64 // After dropping the final element using Split, the path is Cleaned and trailing 65 // slashes are removed. 66 // If the path is empty, Dir returns ".". 67 // If the path consists entirely of slashes followed by non-slash bytes, Dir 68 // returns a single slash. In any other case, the returned path does not end in a 69 // slash. 70 // The input path is passed into filepath.ToSlash converting any Windows slashes 71 // to forward slashes. 72 func (ns *Namespace) Dir(path interface{}) (string, error) { 73 spath, err := cast.ToStringE(path) 74 if err != nil { 75 return "", err 76 } 77 spath = filepath.ToSlash(spath) 78 return _path.Dir(spath), nil 79 } 80 81 // Base returns the last element of path. 82 // Trailing slashes are removed before extracting the last element. 83 // If the path is empty, Base returns ".". 84 // If the path consists entirely of slashes, Base returns "/". 85 // The input path is passed into filepath.ToSlash converting any Windows slashes 86 // to forward slashes. 87 func (ns *Namespace) Base(path interface{}) (string, error) { 88 spath, err := cast.ToStringE(path) 89 if err != nil { 90 return "", err 91 } 92 spath = filepath.ToSlash(spath) 93 return _path.Base(spath), nil 94 } 95 96 // Split splits path immediately following the final slash, 97 // separating it into a directory and file name component. 98 // If there is no slash in path, Split returns an empty dir and 99 // file set to path. 100 // The input path is passed into filepath.ToSlash converting any Windows slashes 101 // to forward slashes. 102 // The returned values have the property that path = dir+file. 103 func (ns *Namespace) Split(path interface{}) (DirFile, error) { 104 spath, err := cast.ToStringE(path) 105 if err != nil { 106 return DirFile{}, err 107 } 108 spath = filepath.ToSlash(spath) 109 dir, file := _path.Split(spath) 110 111 return DirFile{Dir: dir, File: file}, nil 112 } 113 114 // Join joins any number of path elements into a single path, adding a 115 // separating slash if necessary. All the input 116 // path elements are passed into filepath.ToSlash converting any Windows slashes 117 // to forward slashes. 118 // The result is Cleaned; in particular, 119 // all empty strings are ignored. 120 func (ns *Namespace) Join(elements ...interface{}) (string, error) { 121 var pathElements []string 122 for _, elem := range elements { 123 switch v := elem.(type) { 124 case []interface{}: 125 for _, e := range v { 126 elemStr, err := cast.ToStringE(e) 127 if err != nil { 128 return "", err 129 } 130 pathElements = append(pathElements, filepath.ToSlash(elemStr)) 131 } 132 default: 133 elemStr, err := cast.ToStringE(elem) 134 if err != nil { 135 return "", err 136 } 137 pathElements = append(pathElements, filepath.ToSlash(elemStr)) 138 } 139 } 140 return _path.Join(pathElements...), nil 141 }