hugoio

2022-02-15
3分钟阅读时长

https://github.com/gohugoio/hugo/blob/0f8dc47037/hugolib/page__meta.go

for k, v := range frontmatter {
    loki := strings.ToLower(k)

    if loki == "published" { // Intentionally undocumented
        vv, err := cast.ToBoolE(v)
        if err == nil {
            published = &vv
        }
        // published may also be a date
        continue
    }

    if pm.s.frontmatterHandler.IsDateKey(loki) {
        continue
    }

    switch loki {
        case "title":
        pm.title = cast.ToString(v)
        pm.params[loki] = pm.title
        case "linktitle":
        pm.linkTitle = cast.ToString(v)
        pm.params[loki] = pm.linkTitle
        case "summary":
        pm.summary = cast.ToString(v)
        pm.params[loki] = pm.summary
        case "description":
        pm.description = cast.ToString(v)
        pm.params[loki] = pm.description
        case "slug":
        // Don't start or end with a -
        pm.urlPaths.Slug = strings.Trim(cast.ToString(v), "-")
        pm.params[loki] = pm.Slug()
        case "url":
        url := cast.ToString(v)
        if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
            return fmt.Errorf("URLs with protocol (http*) not supported: %q. In page %q", url, p.pathOrTitle())
        }
        lang := p.s.GetLanguagePrefix()
        if lang != "" && !strings.HasPrefix(url, "/") && strings.HasPrefix(url, lang+"/") {
            if strings.HasPrefix(hugo.CurrentVersion.String(), "0.55") {
                // We added support for page relative URLs in Hugo 0.55 and
                // this may get its language path added twice.
                // TODO(bep) eventually remove this.
                p.s.Log.Warnf(`Front matter in %q with the url %q with no leading / has what looks like the language prefix added. In Hugo 0.55 we added support for page relative URLs in front matter, no language prefix needed. Check the URL and consider to either add a leading / or remove the language prefix.`, p.pathOrTitle(), url)
            }
        }
        pm.urlPaths.URL = url
        pm.params[loki] = url
        case "type":
        pm.contentType = cast.ToString(v)
        pm.params[loki] = pm.contentType
        case "keywords":
        pm.keywords = cast.ToStringSlice(v)
        pm.params[loki] = pm.keywords
        case "headless":
        // Legacy setting for leaf bundles.
        // This is since Hugo 0.63 handled in a more general way for all
        // pages.
        isHeadless := cast.ToBool(v)
        pm.params[loki] = isHeadless
        if p.File().TranslationBaseName() == "index" && isHeadless {
            pm.buildConfig.List = pagemeta.Never
            pm.buildConfig.Render = pagemeta.Never
        }
        case "outputs":
        o := cast.ToStringSlice(v)
        if len(o) > 0 {
            // Output formats are explicitly set in front matter, use those.
            outFormats, err := p.s.outputFormatsConfig.GetByNames(o...)

            if err != nil {
                p.s.Log.Errorf("Failed to resolve output formats: %s", err)
            } else {
                pm.configuredOutputFormats = outFormats
                pm.params[loki] = outFormats
            }

        }
        case "draft":
        draft = new(bool)
        *draft = cast.ToBool(v)
        case "layout":
        pm.layout = cast.ToString(v)
        pm.params[loki] = pm.layout
        case "markup":
        pm.markup = cast.ToString(v)
        pm.params[loki] = pm.markup
        case "weight":
        pm.weight = cast.ToInt(v)
        pm.params[loki] = pm.weight
        case "aliases":
        pm.aliases = cast.ToStringSlice(v)
        for i, alias := range pm.aliases {
            if strings.HasPrefix(alias, "http://") || strings.HasPrefix(alias, "https://") {
                return fmt.Errorf("http* aliases not supported: %q", alias)
            }
            pm.aliases[i] = filepath.ToSlash(alias)
        }
        pm.params[loki] = pm.aliases
        case "sitemap":
        p.m.sitemap = config.DecodeSitemap(p.s.siteCfg.sitemap, maps.ToStringMap(v))
        pm.params[loki] = p.m.sitemap
        sitemapSet = true
        case "iscjklanguage":
        isCJKLanguage = new(bool)
        *isCJKLanguage = cast.ToBool(v)
        case "translationkey":
        pm.translationKey = cast.ToString(v)
        pm.params[loki] = pm.translationKey
        case "resources":
        var resources []map[string]any
        handled := true

        switch vv := v.(type) {
            case []map[any]any:
            for _, vvv := range vv {
                resources = append(resources, maps.ToStringMap(vvv))
            }
            case []map[string]any:
            resources = append(resources, vv...)
            case []any:
            for _, vvv := range vv {
                switch vvvv := vvv.(type) {
                    case map[any]any:
                    resources = append(resources, maps.ToStringMap(vvvv))
                    case map[string]any:
                    resources = append(resources, vvvv)
                }
            }
            default:
            handled = false
        }

        if handled {
            pm.params[loki] = resources
            pm.resourcesMetadata = resources
            break
        }
        fallthrough

        default:
        // If not one of the explicit values, store in Params
        switch vv := v.(type) {
            case bool:
            pm.params[loki] = vv
            case string:
            pm.params[loki] = vv
            case int64, int32, int16, int8, int:
            pm.params[loki] = vv
            case float64, float32:
            pm.params[loki] = vv
            case time.Time:
            pm.params[loki] = vv
            default: // handle array of strings as well
            switch vvv := vv.(type) {
                case []any:
                if len(vvv) > 0 {
                    switch vvv[0].(type) {
                        case map[any]any:
                        pm.params[loki] = vvv
                        case map[string]any:
                        pm.params[loki] = vvv
                        case []any:
                        pm.params[loki] = vvv
                        default:
                        a := make([]string, len(vvv))
                        for i, u := range vvv {
                            a[i] = cast.ToString(u)
                        }

                        pm.params[loki] = a
                    }
                } else {
                    pm.params[loki] = []string{}
                }
                default:
                pm.params[loki] = vv
            }
        }
    }
}