diff options
Diffstat (limited to 'hugolib/page_paths.go')
-rw-r--r-- | hugolib/page_paths.go | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/hugolib/page_paths.go b/hugolib/page_paths.go deleted file mode 100644 index 9de7b0764..000000000 --- a/hugolib/page_paths.go +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2017 The Hugo Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package hugolib - -import ( - "fmt" - "path/filepath" - - "net/url" - "strings" - - "github.com/gohugoio/hugo/helpers" - "github.com/gohugoio/hugo/output" -) - -// targetPathDescriptor describes how a file path for a given resource -// should look like on the file system. The same descriptor is then later used to -// create both the permalinks and the relative links, paginator URLs etc. -// -// The big motivating behind this is to have only one source of truth for URLs, -// and by that also get rid of most of the fragile string parsing/encoding etc. -// -// Page.createTargetPathDescriptor is the Page adapter. -// -type targetPathDescriptor struct { - PathSpec *helpers.PathSpec - - Type output.Format - Kind string - - Sections []string - - // For regular content pages this is either - // 1) the Slug, if set, - // 2) the file base name (TranslationBaseName). - BaseName string - - // Source directory. - Dir string - - // Language prefix, set if multilingual and if page should be placed in its - // language subdir. - LangPrefix string - - // Whether this is a multihost multilingual setup. - IsMultihost bool - - // URL from front matter if set. Will override any Slug etc. - URL string - - // Used to create paginator links. - Addends string - - // The expanded permalink if defined for the section, ready to use. - ExpandedPermalink string - - // Some types cannot have uglyURLs, even if globally enabled, RSS being one example. - UglyURLs bool -} - -// createTargetPathDescriptor adapts a Page and the given output.Format into -// a targetPathDescriptor. This descriptor can then be used to create paths -// and URLs for this Page. -func (p *Page) createTargetPathDescriptor(t output.Format) (targetPathDescriptor, error) { - if p.targetPathDescriptorPrototype == nil { - panic(fmt.Sprintf("Must run initTargetPathDescriptor() for page %q, kind %q", p.title, p.Kind)) - } - d := *p.targetPathDescriptorPrototype - d.Type = t - return d, nil -} - -func (p *Page) initTargetPathDescriptor() error { - d := &targetPathDescriptor{ - PathSpec: p.s.PathSpec, - Kind: p.Kind, - Sections: p.sections, - UglyURLs: p.s.Info.uglyURLs(p), - Dir: filepath.ToSlash(p.Dir()), - URL: p.frontMatterURL, - IsMultihost: p.s.owner.IsMultihost(), - } - - if p.Slug != "" { - d.BaseName = p.Slug - } else { - d.BaseName = p.TranslationBaseName() - } - - if p.shouldAddLanguagePrefix() { - d.LangPrefix = p.Lang() - } - - // Expand only KindPage and KindTaxonomy; don't expand other Kinds of Pages - // like KindSection or KindTaxonomyTerm because they are "shallower" and - // the permalink configuration values are likely to be redundant, e.g. - // naively expanding /category/:slug/ would give /category/categories/ for - // the "categories" KindTaxonomyTerm. - if p.Kind == KindPage || p.Kind == KindTaxonomy { - if override, ok := p.Site.Permalinks[p.Section()]; ok { - opath, err := override.Expand(p) - if err != nil { - return err - } - - opath, _ = url.QueryUnescape(opath) - opath = filepath.FromSlash(opath) - d.ExpandedPermalink = opath - } - } - - p.targetPathDescriptorPrototype = d - return nil - -} - -func (p *Page) initURLs() error { - if len(p.outputFormats) == 0 { - p.outputFormats = p.s.outputFormats[p.Kind] - } - target := filepath.ToSlash(p.createRelativeTargetPath()) - rel := p.s.PathSpec.URLizeFilename(target) - - var err error - f := p.outputFormats[0] - p.permalink, err = p.s.permalinkForOutputFormat(rel, f) - if err != nil { - return err - } - - p.relTargetPathBase = strings.TrimPrefix(strings.TrimSuffix(target, f.MediaType.FullSuffix()), "/") - if prefix := p.s.GetLanguagePrefix(); prefix != "" { - // Any language code in the path will be added later. - p.relTargetPathBase = strings.TrimPrefix(p.relTargetPathBase, prefix+"/") - } - p.relPermalink = p.s.PathSpec.PrependBasePath(rel, false) - p.layoutDescriptor = p.createLayoutDescriptor() - return nil -} - -func (p *Page) initPaths() error { - if err := p.initTargetPathDescriptor(); err != nil { - return err - } - if err := p.initURLs(); err != nil { - return err - } - return nil -} - -// createTargetPath creates the target filename for this Page for the given -// output.Format. Some additional URL parts can also be provided, the typical -// use case being pagination. -func (p *Page) createTargetPath(t output.Format, noLangPrefix bool, addends ...string) (string, error) { - d, err := p.createTargetPathDescriptor(t) - if err != nil { - return "", nil - } - - if noLangPrefix { - d.LangPrefix = "" - } - - if len(addends) > 0 { - d.Addends = filepath.Join(addends...) - } - - return createTargetPath(d), nil -} - -func createTargetPath(d targetPathDescriptor) string { - - pagePath := helpers.FilePathSeparator - - // The top level index files, i.e. the home page etc., needs - // the index base even when uglyURLs is enabled. - needsBase := true - - isUgly := d.UglyURLs && !d.Type.NoUgly - - if d.ExpandedPermalink == "" && d.BaseName != "" && d.BaseName == d.Type.BaseName { - isUgly = true - } - - if d.Kind != KindPage && d.URL == "" && len(d.Sections) > 0 { - if d.ExpandedPermalink != "" { - pagePath = filepath.Join(pagePath, d.ExpandedPermalink) - } else { - pagePath = filepath.Join(d.Sections...) - } - needsBase = false - } - - if d.Type.Path != "" { - pagePath = filepath.Join(pagePath, d.Type.Path) - } - - if d.Kind != KindHome && d.URL != "" { - if d.IsMultihost && d.LangPrefix != "" && !strings.HasPrefix(d.URL, "/"+d.LangPrefix) { - pagePath = filepath.Join(d.LangPrefix, pagePath, d.URL) - } else { - pagePath = filepath.Join(pagePath, d.URL) - } - - if d.Addends != "" { - pagePath = filepath.Join(pagePath, d.Addends) - } - - if strings.HasSuffix(d.URL, "/") || !strings.Contains(d.URL, ".") { - pagePath = filepath.Join(pagePath, d.Type.BaseName+d.Type.MediaType.FullSuffix()) - } - - } else if d.Kind == KindPage { - if d.ExpandedPermalink != "" { - pagePath = filepath.Join(pagePath, d.ExpandedPermalink) - - } else { - if d.Dir != "" { - pagePath = filepath.Join(pagePath, d.Dir) - } - if d.BaseName != "" { - pagePath = filepath.Join(pagePath, d.BaseName) - } - } - - if d.Addends != "" { - pagePath = filepath.Join(pagePath, d.Addends) - } - - if isUgly { - pagePath += d.Type.MediaType.FullSuffix() - } else { - pagePath = filepath.Join(pagePath, d.Type.BaseName+d.Type.MediaType.FullSuffix()) - } - - if d.LangPrefix != "" { - pagePath = filepath.Join(d.LangPrefix, pagePath) - } - } else { - if d.Addends != "" { - pagePath = filepath.Join(pagePath, d.Addends) - } - - needsBase = needsBase && d.Addends == "" - - // No permalink expansion etc. for node type pages (for now) - base := "" - - if needsBase || !isUgly { - base = helpers.FilePathSeparator + d.Type.BaseName - } - - pagePath += base + d.Type.MediaType.FullSuffix() - - if d.LangPrefix != "" { - pagePath = filepath.Join(d.LangPrefix, pagePath) - } - } - - pagePath = filepath.Join(helpers.FilePathSeparator, pagePath) - - // Note: MakePathSanitized will lower case the path if - // disablePathToLower isn't set. - return d.PathSpec.MakePathSanitized(pagePath) -} - -func (p *Page) createRelativeTargetPath() string { - - if len(p.outputFormats) == 0 { - if p.Kind == kindUnknown { - panic(fmt.Sprintf("Page %q has unknown kind", p.title)) - } - panic(fmt.Sprintf("Page %q missing output format(s)", p.title)) - } - - // Choose the main output format. In most cases, this will be HTML. - f := p.outputFormats[0] - - 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 { - p.s.Log.ERROR.Printf("Failed to create permalink for page %q: %s", p.FullFilePath(), err) - return "" - } - - // For /index.json etc. we must use the full path. - if f.MediaType.FullSuffix() == ".html" && filepath.Base(tp) == "index.html" { - tp = strings.TrimSuffix(tp, f.BaseFilename()) - } - - return tp -} |