URI: 
       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 }