mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-28 22:19:59 +02:00
Add ContentTypes to config
This is an empty struct for now, but we will most likely expand on that. ``` [contentTypes] [contentTypes.'text/markdown'] ``` The above means that only Markdown will be considered a content type. E.g. HTML will be treated as plain text. Fixes #12274
This commit is contained in:
115
media/config.go
115
media/config.go
@@ -71,11 +71,15 @@ func init() {
|
||||
EmacsOrgMode: Builtin.EmacsOrgModeType,
|
||||
}
|
||||
|
||||
DefaultContentTypes.init()
|
||||
DefaultContentTypes.init(nil)
|
||||
}
|
||||
|
||||
var DefaultContentTypes ContentTypes
|
||||
|
||||
type ContentTypeConfig struct {
|
||||
// Empty for now.
|
||||
}
|
||||
|
||||
// ContentTypes holds the media types that are considered content in Hugo.
|
||||
type ContentTypes struct {
|
||||
HTML Type
|
||||
@@ -85,13 +89,36 @@ type ContentTypes struct {
|
||||
ReStructuredText Type
|
||||
EmacsOrgMode Type
|
||||
|
||||
types Types
|
||||
|
||||
// Created in init().
|
||||
types Types
|
||||
extensionSet map[string]bool
|
||||
}
|
||||
|
||||
func (t *ContentTypes) init() {
|
||||
t.types = Types{t.HTML, t.Markdown, t.AsciiDoc, t.Pandoc, t.ReStructuredText, t.EmacsOrgMode}
|
||||
func (t *ContentTypes) init(types Types) {
|
||||
sort.Slice(t.types, func(i, j int) bool {
|
||||
return t.types[i].Type < t.types[j].Type
|
||||
})
|
||||
|
||||
if tt, ok := types.GetByType(t.HTML.Type); ok {
|
||||
t.HTML = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.Markdown.Type); ok {
|
||||
t.Markdown = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.AsciiDoc.Type); ok {
|
||||
t.AsciiDoc = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.Pandoc.Type); ok {
|
||||
t.Pandoc = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.ReStructuredText.Type); ok {
|
||||
t.ReStructuredText = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.EmacsOrgMode.Type); ok {
|
||||
t.EmacsOrgMode = tt
|
||||
}
|
||||
|
||||
t.extensionSet = make(map[string]bool)
|
||||
for _, mt := range t.types {
|
||||
for _, suffix := range mt.Suffixes() {
|
||||
@@ -135,32 +162,6 @@ func (t ContentTypes) Types() Types {
|
||||
return t.types
|
||||
}
|
||||
|
||||
// FromTypes creates a new ContentTypes updated with the values from the given Types.
|
||||
func (t ContentTypes) FromTypes(types Types) ContentTypes {
|
||||
if tt, ok := types.GetByType(t.HTML.Type); ok {
|
||||
t.HTML = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.Markdown.Type); ok {
|
||||
t.Markdown = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.AsciiDoc.Type); ok {
|
||||
t.AsciiDoc = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.Pandoc.Type); ok {
|
||||
t.Pandoc = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.ReStructuredText.Type); ok {
|
||||
t.ReStructuredText = tt
|
||||
}
|
||||
if tt, ok := types.GetByType(t.EmacsOrgMode.Type); ok {
|
||||
t.EmacsOrgMode = tt
|
||||
}
|
||||
|
||||
t.init()
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// Hold the configuration for a given media type.
|
||||
type MediaTypeConfig struct {
|
||||
// The file suffixes used for this media type.
|
||||
@@ -169,6 +170,58 @@ type MediaTypeConfig struct {
|
||||
Delimiter string
|
||||
}
|
||||
|
||||
var defaultContentTypesConfig = map[string]ContentTypeConfig{
|
||||
Builtin.HTMLType.Type: {},
|
||||
Builtin.MarkdownType.Type: {},
|
||||
Builtin.AsciiDocType.Type: {},
|
||||
Builtin.PandocType.Type: {},
|
||||
Builtin.ReStructuredTextType.Type: {},
|
||||
Builtin.EmacsOrgModeType.Type: {},
|
||||
}
|
||||
|
||||
// DecodeContentTypes decodes the given map of content types.
|
||||
func DecodeContentTypes(in map[string]any, types Types) (*config.ConfigNamespace[map[string]ContentTypeConfig, ContentTypes], error) {
|
||||
buildConfig := func(v any) (ContentTypes, any, error) {
|
||||
var s map[string]ContentTypeConfig
|
||||
c := DefaultContentTypes
|
||||
m, err := maps.ToStringMapE(v)
|
||||
if err != nil {
|
||||
return c, nil, err
|
||||
}
|
||||
if len(m) == 0 {
|
||||
s = defaultContentTypesConfig
|
||||
} else {
|
||||
s = make(map[string]ContentTypeConfig)
|
||||
m = maps.CleanConfigStringMap(m)
|
||||
for k, v := range m {
|
||||
var ctc ContentTypeConfig
|
||||
if err := mapstructure.WeakDecode(v, &ctc); err != nil {
|
||||
return c, nil, err
|
||||
}
|
||||
s[k] = ctc
|
||||
}
|
||||
}
|
||||
|
||||
for k := range s {
|
||||
mediaType, found := types.GetByType(k)
|
||||
if !found {
|
||||
return c, nil, fmt.Errorf("unknown media type %q", k)
|
||||
}
|
||||
c.types = append(c.types, mediaType)
|
||||
}
|
||||
|
||||
c.init(types)
|
||||
|
||||
return c, s, nil
|
||||
}
|
||||
|
||||
ns, err := config.DecodeNamespace[map[string]ContentTypeConfig](in, buildConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode media types: %w", err)
|
||||
}
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
// DecodeTypes decodes the given map of media types.
|
||||
func DecodeTypes(in map[string]any) (*config.ConfigNamespace[map[string]MediaTypeConfig, Types], error) {
|
||||
buildConfig := func(v any) (Types, any, error) {
|
||||
@@ -220,6 +273,6 @@ func DecodeTypes(in map[string]any) (*config.ConfigNamespace[map[string]MediaTyp
|
||||
// TODO(bep) get rid of this.
|
||||
var DefaultPathParser = &paths.PathParser{
|
||||
IsContentExt: func(ext string) bool {
|
||||
return DefaultContentTypes.IsContentSuffix(ext)
|
||||
panic("not supported")
|
||||
},
|
||||
}
|
||||
|
Reference in New Issue
Block a user