Make Page an interface

The main motivation of this commit is to add a `page.Page` interface to replace the very file-oriented `hugolib.Page` struct.
This is all a preparation step for issue  #5074, "pages from other data sources".

But this also fixes a set of annoying limitations, especially related to custom output formats, and shortcodes.

Most notable changes:

* The inner content of shortcodes using the `{{%` as the outer-most delimiter will now be sent to the content renderer, e.g. Blackfriday.
  This means that any markdown will partake in the global ToC and footnote context etc.
* The Custom Output formats are now "fully virtualized". This removes many of the current limitations.
* The taxonomy list type now has a reference to the `Page` object.
  This improves the taxonomy template `.Title` situation and make common template constructs much simpler.

See #5074
Fixes #5763
Fixes #5758
Fixes #5090
Fixes #5204
Fixes #4695
Fixes #5607
Fixes #5707
Fixes #5719
Fixes #3113
Fixes #5706
Fixes #5767
Fixes #5723
Fixes #5769
Fixes #5770
Fixes #5771
Fixes #5759
Fixes #5776
Fixes #5777
Fixes #5778
This commit is contained in:
Bjørn Erik Pedersen
2019-01-02 12:33:26 +01:00
parent 44f5c1c14c
commit 597e418cb0
206 changed files with 14442 additions and 9679 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2018 The Hugo Authors. All rights reserved.
// Copyright 2019 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.
@@ -92,9 +92,7 @@ func appendToInterfaceSlice(tov reflect.Value, from ...interface{}) ([]interface
tos = append(tos, tov.Index(i).Interface())
}
for _, v := range from {
tos = append(tos, v)
}
tos = append(tos, from...)
return tos, nil
}

View File

@@ -1,4 +1,4 @@
// Copyright 2018 The Hugo Authors. All rights reserved.
// Copyright 2019 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.
@@ -75,11 +75,11 @@ func (p *tstSlicerIn2) Slice(in interface{}) (interface{}, error) {
}
func (p *tstSlicerIn1) Name() string {
return p.Name()
return p.name
}
func (p *tstSlicerIn2) Name() string {
return p.Name()
return p.name
}
func (p *tstSlicer) Slice(in interface{}) (interface{}, error) {

View File

@@ -1,4 +1,4 @@
// Copyright 2018 The Hugo Authors. All rights reserved.
// Copyright 2019 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.
@@ -32,6 +32,7 @@ type ReadSeekCloser interface {
}
// ReadSeekerNoOpCloser implements ReadSeekCloser by doing nothing in Close.
// TODO(bep) rename this and simila to ReadSeekerNopCloser, naming used in stdlib, which kind of makes sense.
type ReadSeekerNoOpCloser struct {
ReadSeeker
}

View File

@@ -1,24 +0,0 @@
// Copyright 2018 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 hugo
import "github.com/gohugoio/hugo/langs"
// Site represents a site in the build. This is currently a very narrow interface,
// but the actual implementation will be richer, see hugolib.SiteInfo.
type Site interface {
Language() *langs.Language
IsServer() bool
Hugo() Info
}

View File

@@ -1,4 +1,4 @@
// Copyright 2018 The Hugo Authors. All rights reserved.
// Copyright 2019 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.
@@ -28,6 +28,24 @@ type Scratch struct {
mu sync.RWMutex
}
// Scratcher provides a scratching service.
type Scratcher interface {
Scratch() *Scratch
}
type scratcher struct {
s *Scratch
}
func (s scratcher) Scratch() *Scratch {
return s.s
}
// NewScratcher creates a new Scratcher.
func NewScratcher() Scratcher {
return scratcher{s: NewScratch()}
}
// Add will, for single values, add (using the + operator) the addend to the existing addend (if found).
// Supports numeric values and strings.
//

View File

@@ -1,4 +1,4 @@
// Copyright 2018 The Hugo Authors. All rights reserved.
// Copyright 2019 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.
@@ -16,6 +16,7 @@ package types
import (
"fmt"
"reflect"
"github.com/spf13/cast"
)
@@ -56,3 +57,24 @@ func NewKeyValuesStrings(key string, values ...string) KeyValues {
type Zeroer interface {
IsZero() bool
}
// IsNil reports whether v is nil.
func IsNil(v interface{}) bool {
if v == nil {
return true
}
value := reflect.ValueOf(v)
switch value.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
return value.IsNil()
}
return false
}
// DevMarker is a marker interface for types that should only be used during
// development.
type DevMarker interface {
DevOnly()
}