2017-03-05 12:23:00 -05:00
|
|
|
// Copyright 2017-present 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 output
|
|
|
|
|
|
|
|
import (
|
2017-03-08 07:45:33 -05:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2017-03-05 12:23:00 -05:00
|
|
|
"github.com/spf13/hugo/media"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2017-03-08 07:45:33 -05:00
|
|
|
// An ordered list of built-in output formats
|
2017-03-25 14:36:50 -04:00
|
|
|
//
|
2017-03-08 07:45:33 -05:00
|
|
|
// See https://www.ampproject.org/learn/overview/
|
2017-03-25 14:36:50 -04:00
|
|
|
AMPFormat = Format{
|
2017-03-08 07:45:33 -05:00
|
|
|
Name: "AMP",
|
|
|
|
MediaType: media.HTMLType,
|
|
|
|
BaseName: "index",
|
2017-03-09 13:19:29 -05:00
|
|
|
Path: "amp",
|
2017-03-22 04:54:56 -04:00
|
|
|
Rel: "amphtml",
|
2017-03-24 06:25:25 -04:00
|
|
|
IsHTML: true,
|
2017-03-08 07:45:33 -05:00
|
|
|
}
|
|
|
|
|
2017-03-25 14:36:50 -04:00
|
|
|
CalendarFormat = Format{
|
2017-03-23 12:31:05 -04:00
|
|
|
Name: "Calendar",
|
|
|
|
MediaType: media.CalendarType,
|
|
|
|
IsPlainText: true,
|
|
|
|
Protocol: "webcal://",
|
|
|
|
BaseName: "index",
|
|
|
|
Rel: "alternate",
|
|
|
|
}
|
|
|
|
|
2017-03-25 14:36:50 -04:00
|
|
|
CSSFormat = Format{
|
2017-04-01 09:12:31 -04:00
|
|
|
Name: "CSS",
|
|
|
|
MediaType: media.CSSType,
|
|
|
|
BaseName: "styles",
|
|
|
|
IsPlainText: true,
|
|
|
|
Rel: "stylesheet",
|
|
|
|
}
|
|
|
|
CSVFormat = Format{
|
|
|
|
Name: "CSV",
|
|
|
|
MediaType: media.CSVType,
|
|
|
|
BaseName: "index",
|
|
|
|
IsPlainText: true,
|
|
|
|
Rel: "alternate",
|
2017-03-08 07:45:33 -05:00
|
|
|
}
|
|
|
|
|
2017-03-25 14:36:50 -04:00
|
|
|
HTMLFormat = Format{
|
2017-03-05 12:23:00 -05:00
|
|
|
Name: "HTML",
|
|
|
|
MediaType: media.HTMLType,
|
2017-03-07 08:20:39 -05:00
|
|
|
BaseName: "index",
|
2017-03-22 04:54:56 -04:00
|
|
|
Rel: "canonical",
|
2017-03-24 06:25:25 -04:00
|
|
|
IsHTML: true,
|
2017-03-05 12:23:00 -05:00
|
|
|
}
|
|
|
|
|
2017-03-25 14:36:50 -04:00
|
|
|
JSONFormat = Format{
|
2017-03-08 07:45:33 -05:00
|
|
|
Name: "JSON",
|
2017-03-09 13:19:29 -05:00
|
|
|
MediaType: media.JSONType,
|
2017-03-08 07:45:33 -05:00
|
|
|
BaseName: "index",
|
|
|
|
IsPlainText: true,
|
2017-03-22 04:54:56 -04:00
|
|
|
Rel: "alternate",
|
2017-03-08 07:45:33 -05:00
|
|
|
}
|
|
|
|
|
2017-03-25 14:36:50 -04:00
|
|
|
RSSFormat = Format{
|
2017-03-05 12:23:00 -05:00
|
|
|
Name: "RSS",
|
|
|
|
MediaType: media.RSSType,
|
2017-03-07 08:20:39 -05:00
|
|
|
BaseName: "index",
|
2017-03-09 13:19:29 -05:00
|
|
|
NoUgly: true,
|
2017-03-22 04:54:56 -04:00
|
|
|
Rel: "alternate",
|
2017-03-05 12:23:00 -05:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2017-03-16 03:32:14 -04:00
|
|
|
var builtInTypes = map[string]Format{
|
2017-03-25 14:36:50 -04:00
|
|
|
strings.ToLower(AMPFormat.Name): AMPFormat,
|
|
|
|
strings.ToLower(CalendarFormat.Name): CalendarFormat,
|
|
|
|
strings.ToLower(CSSFormat.Name): CSSFormat,
|
|
|
|
strings.ToLower(HTMLFormat.Name): HTMLFormat,
|
|
|
|
strings.ToLower(JSONFormat.Name): JSONFormat,
|
|
|
|
strings.ToLower(RSSFormat.Name): RSSFormat,
|
2017-03-08 07:45:33 -05:00
|
|
|
}
|
|
|
|
|
2017-03-16 03:32:14 -04:00
|
|
|
type Formats []Format
|
2017-03-06 07:40:06 -05:00
|
|
|
|
2017-03-24 11:54:37 -04:00
|
|
|
func (formats Formats) GetByName(name string) (f Format, found bool) {
|
|
|
|
for _, ff := range formats {
|
|
|
|
if name == ff.Name {
|
|
|
|
f = ff
|
|
|
|
found = true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-03-27 19:19:46 -04:00
|
|
|
// Format represents an output representation, usually to a file on disk.
|
2017-03-16 03:32:14 -04:00
|
|
|
type Format struct {
|
|
|
|
// The Name is used as an identifier. Internal output formats (i.e. HTML and RSS)
|
2017-03-05 12:23:00 -05:00
|
|
|
// can be overridden by providing a new definition for those types.
|
|
|
|
Name string
|
|
|
|
|
|
|
|
MediaType media.Type
|
|
|
|
|
|
|
|
// Must be set to a value when there are two or more conflicting mediatype for the same resource.
|
|
|
|
Path string
|
|
|
|
|
2017-03-07 08:20:39 -05:00
|
|
|
// The base output file name used when not using "ugly URLs", defaults to "index".
|
|
|
|
BaseName string
|
|
|
|
|
2017-03-22 04:54:56 -04:00
|
|
|
// The value to use for rel links
|
|
|
|
//
|
|
|
|
// See https://www.w3schools.com/tags/att_link_rel.asp
|
|
|
|
//
|
|
|
|
// AMP has a special requirement in this department, see:
|
|
|
|
// https://www.ampproject.org/docs/guides/deploy/discovery
|
|
|
|
// I.e.:
|
|
|
|
// <link rel="amphtml" href="https://www.example.com/url/to/amp/document.html">
|
|
|
|
Rel string
|
|
|
|
|
2017-03-07 08:20:39 -05:00
|
|
|
// The protocol to use, i.e. "webcal://". Defaults to the protocol of the baseURL.
|
|
|
|
Protocol string
|
|
|
|
|
2017-03-05 12:23:00 -05:00
|
|
|
// IsPlainText decides whether to use text/template or html/template
|
|
|
|
// as template parser.
|
|
|
|
IsPlainText bool
|
2017-03-07 08:20:39 -05:00
|
|
|
|
2017-03-24 06:25:25 -04:00
|
|
|
// IsHTML returns whether this format is int the HTML family. This includes
|
|
|
|
// HTML, AMP etc. This is used to decide when to create alias redirects etc.
|
|
|
|
IsHTML bool
|
|
|
|
|
2017-03-07 08:20:39 -05:00
|
|
|
// Enable to ignore the global uglyURLs setting.
|
|
|
|
NoUgly bool
|
2017-03-05 12:23:00 -05:00
|
|
|
}
|
2017-03-08 07:45:33 -05:00
|
|
|
|
2017-03-19 16:09:31 -04:00
|
|
|
func GetFormat(key string) (Format, bool) {
|
2017-03-08 07:45:33 -05:00
|
|
|
found, ok := builtInTypes[key]
|
|
|
|
if !ok {
|
|
|
|
found, ok = builtInTypes[strings.ToLower(key)]
|
|
|
|
}
|
|
|
|
return found, ok
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(bep) outputs rewamp on global config?
|
2017-03-19 16:09:31 -04:00
|
|
|
func GetFormats(keys ...string) (Formats, error) {
|
2017-03-16 03:32:14 -04:00
|
|
|
var types []Format
|
2017-03-08 07:45:33 -05:00
|
|
|
|
|
|
|
for _, key := range keys {
|
2017-03-19 16:09:31 -04:00
|
|
|
tpe, ok := GetFormat(key)
|
2017-03-08 07:45:33 -05:00
|
|
|
if !ok {
|
2017-03-16 03:32:14 -04:00
|
|
|
return types, fmt.Errorf("OutputFormat with key %q not found", key)
|
2017-03-08 07:45:33 -05:00
|
|
|
}
|
|
|
|
types = append(types, tpe)
|
|
|
|
}
|
|
|
|
|
|
|
|
return types, nil
|
|
|
|
}
|
2017-03-09 13:19:29 -05:00
|
|
|
|
2017-03-16 03:32:14 -04:00
|
|
|
func (t Format) BaseFilename() string {
|
2017-03-09 13:19:29 -05:00
|
|
|
return t.BaseName + "." + t.MediaType.Suffix
|
|
|
|
}
|