urls.go - hugo - [fork] hugo port for 9front
HTML git clone https://git.drkhsh.at/hugo.git
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
urls.go (5502B)
---
1 // Copyright 2017 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 urls provides template functions to deal with URLs.
15 package urls
16
17 import (
18 "errors"
19 "fmt"
20 "net/url"
21
22 "github.com/gohugoio/hugo/common/urls"
23 "github.com/gohugoio/hugo/deps"
24 "github.com/spf13/cast"
25 )
26
27 // New returns a new instance of the urls-namespaced template functions.
28 func New(deps *deps.Deps) *Namespace {
29 return &Namespace{
30 deps: deps,
31 multihost: deps.Conf.IsMultihost(),
32 }
33 }
34
35 // Namespace provides template functions for the "urls" namespace.
36 type Namespace struct {
37 deps *deps.Deps
38 multihost bool
39 }
40
41 // AbsURL takes the string s and converts it to an absolute URL.
42 func (ns *Namespace) AbsURL(s any) (string, error) {
43 ss, err := cast.ToStringE(s)
44 if err != nil {
45 return "", err
46 }
47
48 return ns.deps.PathSpec.AbsURL(ss, false), nil
49 }
50
51 // Parse parses rawurl into a URL structure. The rawurl may be relative or
52 // absolute.
53 func (ns *Namespace) Parse(rawurl any) (*url.URL, error) {
54 s, err := cast.ToStringE(rawurl)
55 if err != nil {
56 return nil, fmt.Errorf("error in Parse: %w", err)
57 }
58
59 return url.Parse(s)
60 }
61
62 // RelURL takes the string s and prepends the relative path according to a
63 // page's position in the project directory structure.
64 func (ns *Namespace) RelURL(s any) (string, error) {
65 ss, err := cast.ToStringE(s)
66 if err != nil {
67 return "", err
68 }
69
70 return ns.deps.PathSpec.RelURL(ss, false), nil
71 }
72
73 // URLize returns the strings s formatted as an URL.
74 func (ns *Namespace) URLize(s any) (string, error) {
75 ss, err := cast.ToStringE(s)
76 if err != nil {
77 return "", err
78 }
79 return ns.deps.PathSpec.URLize(ss), nil
80 }
81
82 // Anchorize creates sanitized anchor name version of the string s that is compatible
83 // with how your configured markdown renderer does it.
84 func (ns *Namespace) Anchorize(s any) (string, error) {
85 ss, err := cast.ToStringE(s)
86 if err != nil {
87 return "", err
88 }
89 return ns.deps.ContentSpec.SanitizeAnchorName(ss), nil
90 }
91
92 // Ref returns the absolute URL path to a given content item from Page p.
93 func (ns *Namespace) Ref(p any, args any) (string, error) {
94 pp, ok := p.(urls.RefLinker)
95 if !ok {
96 return "", errors.New("invalid Page received in Ref")
97 }
98 argsm, err := ns.refArgsToMap(args)
99 if err != nil {
100 return "", err
101 }
102 s, err := pp.Ref(argsm)
103 return s, err
104 }
105
106 // RelRef returns the relative URL path to a given content item from Page p.
107 func (ns *Namespace) RelRef(p any, args any) (string, error) {
108 pp, ok := p.(urls.RefLinker)
109 if !ok {
110 return "", errors.New("invalid Page received in RelRef")
111 }
112 argsm, err := ns.refArgsToMap(args)
113 if err != nil {
114 return "", err
115 }
116
117 s, err := pp.RelRef(argsm)
118 return s, err
119 }
120
121 func (ns *Namespace) refArgsToMap(args any) (map[string]any, error) {
122 var (
123 s string
124 of string
125 )
126
127 v := args
128 if _, ok := v.([]any); ok {
129 v = cast.ToStringSlice(v)
130 }
131
132 switch v := v.(type) {
133 case map[string]any:
134 return v, nil
135 case map[string]string:
136 m := make(map[string]any)
137 for k, v := range v {
138 m[k] = v
139 }
140 return m, nil
141 case []string:
142 if len(v) == 0 || len(v) > 2 {
143 return nil, fmt.Errorf("invalid number of arguments to ref")
144 }
145 // These were the options before we introduced the map type:
146 s = v[0]
147 if len(v) == 2 {
148 of = v[1]
149 }
150 default:
151 var err error
152 s, err = cast.ToStringE(args)
153 if err != nil {
154 return nil, err
155 }
156
157 }
158
159 return map[string]any{
160 "path": s,
161 "outputFormat": of,
162 }, nil
163 }
164
165 // RelLangURL takes the string s and prepends the relative path according to a
166 // page's position in the project directory structure and the current language.
167 func (ns *Namespace) RelLangURL(s any) (string, error) {
168 ss, err := cast.ToStringE(s)
169 if err != nil {
170 return "", err
171 }
172
173 return ns.deps.PathSpec.RelURL(ss, !ns.multihost), nil
174 }
175
176 // AbsLangURL the string s and converts it to an absolute URL according
177 // to a page's position in the project directory structure and the current
178 // language.
179 func (ns *Namespace) AbsLangURL(s any) (string, error) {
180 ss, err := cast.ToStringE(s)
181 if err != nil {
182 return "", err
183 }
184
185 return ns.deps.PathSpec.AbsURL(ss, !ns.multihost), nil
186 }
187
188 // JoinPath joins the provided elements into a URL string and cleans the result
189 // of any ./ or ../ elements. If the argument list is empty, JoinPath returns
190 // an empty string.
191 func (ns *Namespace) JoinPath(elements ...any) (string, error) {
192 if len(elements) == 0 {
193 return "", nil
194 }
195
196 var selements []string
197 for _, e := range elements {
198 switch v := e.(type) {
199 case []string:
200 selements = append(selements, v...)
201 case []any:
202 for _, e := range v {
203 se, err := cast.ToStringE(e)
204 if err != nil {
205 return "", err
206 }
207 selements = append(selements, se)
208 }
209 default:
210 se, err := cast.ToStringE(e)
211 if err != nil {
212 return "", err
213 }
214 selements = append(selements, se)
215 }
216 }
217
218 result, err := url.JoinPath(selements[0], selements[1:]...)
219 if err != nil {
220 return "", err
221 }
222 return result, nil
223 }