mirror of
https://github.com/gohugoio/hugo.git
synced 2026-09-01 19:22:38 +00:00
Compare commits
109 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| da0437b481 | |||
| 90fe00df07 | |||
| 02efadc243 | |||
| 00e00da233 | |||
| 45c665d396 | |||
| a06c06a5c2 | |||
| 0256959a35 | |||
| eded9ac2a0 | |||
| 8d72512825 | |||
| e81aef0a95 | |||
| 673e622fa9 | |||
| 28bd06265e | |||
| 9f9191471e | |||
| 3727a9d111 | |||
| 48565de62f | |||
| 808e126216 | |||
| aa85a46dc6 | |||
| 35011bcb26 | |||
| 084624baac | |||
| 15163266c1 | |||
| a74f7d3cc0 | |||
| cb84d98169 | |||
| c91dbe4ce9 | |||
| 6e0452e189 | |||
| d2b1162680 | |||
| 6265184309 | |||
| 797127010d | |||
| 1672a332da | |||
| 823ce055ed | |||
| 5f7a65a080 | |||
| 25e3da3343 | |||
| 9df98ec49c | |||
| 2fc3380707 | |||
| f1916f114b | |||
| 6aa5c9117f | |||
| 12a65e76df | |||
| 58c0f5e617 | |||
| a1c3e3c1f3 | |||
| 42e150fbfa | |||
| 028b356787 | |||
| e9f87c4e3f | |||
| defd7106bf | |||
| beb6c03bc8 | |||
| 4a3efea7ef | |||
| c66dc6c74f | |||
| 127d5feb32 | |||
| 2d42ba912b | |||
| 5b7b5dea1f | |||
| ccfaeb678b | |||
| 057b1377c5 | |||
| 48dbb593f7 | |||
| f0266e2ef3 | |||
| 77aa385b84 | |||
| 545a1c1ced | |||
| 47aaa52e39 | |||
| 428907cc34 | |||
| a78b3e3415 | |||
| cfcb014515 | |||
| 0b579db80f | |||
| ee5d027cd5 | |||
| 4a340ba254 | |||
| 3466884e36 | |||
| 6ff435aa3f | |||
| 82abca32fa | |||
| fc045e12a9 | |||
| 9679023f2b | |||
| 0a9172672a | |||
| efa74c5c6e | |||
| 6408c1cbc8 | |||
| 522ba1cd98 | |||
| 889dc47ceb | |||
| f720fe56db | |||
| d6ed17c60f | |||
| 145b3fcce3 | |||
| 01e249e97c | |||
| 4b560cc119 | |||
| e3e627e6b7 | |||
| 83d03a5201 | |||
| fc0f13b684 | |||
| 7eeebe1e5a | |||
| 740fa4a91d | |||
| f8c67f93e1 | |||
| 3d9235e8fc | |||
| f7d909f394 | |||
| 8a7ef3cf4e | |||
| 2dfe242ea6 | |||
| 7a1464e547 | |||
| 41d50b4dd3 | |||
| 4d53ae697e | |||
| 626b16e024 | |||
| 9e1dcefc5f | |||
| 2919a6a503 | |||
| 432885c499 | |||
| 6a3e89743c | |||
| 9613e3e8a8 | |||
| c950c86b4e | |||
| 915202494b | |||
| b3e4f911f4 | |||
| a301f6b2ae | |||
| 646bc85088 | |||
| 5c0d10045d | |||
| 81f5633245 | |||
| 9698b0dab1 | |||
| 32344fe3db | |||
| 4d7fa9f114 | |||
| a985efcecf | |||
| 6c3c6686f5 | |||
| c34bf48560 | |||
| 833d16d467 |
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: 'Bug report'
|
||||
labels: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
about: Create a report to help us improve
|
||||
---
|
||||
|
||||
@@ -69,7 +69,13 @@ go install
|
||||
```
|
||||
|
||||
**If you are a Windows user, substitute the `$HOME` environment variable above with `%USERPROFILE%`.**
|
||||
|
||||
|
||||
If you want to compile with Sass/SCSS support use `--tags extended` and make sure `CGO_ENABLED=1` is set in your go environment. If you don't want to have CGO enabled, you may use the following command to temporarily enable CGO only for hugo compilation:
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=1 go install --tags extended
|
||||
```
|
||||
|
||||
## The Hugo Documentation
|
||||
|
||||
The Hugo documentation now lives in its own repository, see https://github.com/gohugoio/hugoDocs. But we do keep a version of that documentation as a `git subtree` in this repository. To build the sub folder `/docs` as a Hugo site, you need to clone this repo:
|
||||
|
||||
Vendored
-99
@@ -1,99 +0,0 @@
|
||||
// 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 cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Partition represents a cache partition where Load is the callback
|
||||
// for when the partition is needed.
|
||||
type Partition struct {
|
||||
Key string
|
||||
Load func() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// Lazy represents a lazily loaded cache.
|
||||
type Lazy struct {
|
||||
initSync sync.Once
|
||||
initErr error
|
||||
cache map[string]interface{}
|
||||
load func() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// NewLazy creates a lazy cache with the given load func.
|
||||
func NewLazy(load func() (map[string]interface{}, error)) *Lazy {
|
||||
return &Lazy{load: load}
|
||||
}
|
||||
|
||||
func (l *Lazy) init() error {
|
||||
l.initSync.Do(func() {
|
||||
c, err := l.load()
|
||||
l.cache = c
|
||||
l.initErr = err
|
||||
|
||||
})
|
||||
|
||||
return l.initErr
|
||||
}
|
||||
|
||||
// Get initializes the cache if not already initialized, then looks up the
|
||||
// given key.
|
||||
func (l *Lazy) Get(key string) (interface{}, bool, error) {
|
||||
l.init()
|
||||
if l.initErr != nil {
|
||||
return nil, false, l.initErr
|
||||
}
|
||||
v, found := l.cache[key]
|
||||
return v, found, nil
|
||||
}
|
||||
|
||||
// PartitionedLazyCache is a lazily loaded cache paritioned by a supplied string key.
|
||||
type PartitionedLazyCache struct {
|
||||
partitions map[string]*Lazy
|
||||
}
|
||||
|
||||
// NewPartitionedLazyCache creates a new NewPartitionedLazyCache with the supplied
|
||||
// partitions.
|
||||
func NewPartitionedLazyCache(partitions ...Partition) *PartitionedLazyCache {
|
||||
lazyPartitions := make(map[string]*Lazy, len(partitions))
|
||||
for _, partition := range partitions {
|
||||
lazyPartitions[partition.Key] = NewLazy(partition.Load)
|
||||
}
|
||||
cache := &PartitionedLazyCache{partitions: lazyPartitions}
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
// Get initializes the partition if not already done so, then looks up the given
|
||||
// key in the given partition, returns nil if no value found.
|
||||
func (c *PartitionedLazyCache) Get(partition, key string) (interface{}, error) {
|
||||
p, found := c.partitions[partition]
|
||||
|
||||
if !found {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
v, found, err := p.Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if found {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
Vendored
-138
@@ -1,138 +0,0 @@
|
||||
// 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 cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
func TestNewPartitionedLazyCache(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := qt.New(t)
|
||||
|
||||
p1 := Partition{
|
||||
Key: "p1",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"p1_1": "p1v1",
|
||||
"p1_2": "p1v2",
|
||||
"p1_nil": nil,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
p2 := Partition{
|
||||
Key: "p2",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"p2_1": "p2v1",
|
||||
"p2_2": "p2v2",
|
||||
"p2_3": "p2v3",
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
cache := NewPartitionedLazyCache(p1, p2)
|
||||
|
||||
v, err := cache.Get("p1", "p1_1")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.Equals, "p1v1")
|
||||
|
||||
v, err = cache.Get("p1", "p2_1")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.IsNil)
|
||||
|
||||
v, err = cache.Get("p1", "p1_nil")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.IsNil)
|
||||
|
||||
v, err = cache.Get("p2", "p2_3")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.Equals, "p2v3")
|
||||
|
||||
v, err = cache.Get("doesnotexist", "p1_1")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.IsNil)
|
||||
|
||||
v, err = cache.Get("p1", "doesnotexist")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.IsNil)
|
||||
|
||||
errorP := Partition{
|
||||
Key: "p3",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return nil, errors.New("Failed")
|
||||
},
|
||||
}
|
||||
|
||||
cache = NewPartitionedLazyCache(errorP)
|
||||
|
||||
v, err = cache.Get("p1", "doesnotexist")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.IsNil)
|
||||
|
||||
_, err = cache.Get("p3", "doesnotexist")
|
||||
c.Assert(err, qt.Not(qt.IsNil))
|
||||
|
||||
}
|
||||
|
||||
func TestConcurrentPartitionedLazyCache(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := qt.New(t)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
p1 := Partition{
|
||||
Key: "p1",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"p1_1": "p1v1",
|
||||
"p1_2": "p1v2",
|
||||
"p1_nil": nil,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
p2 := Partition{
|
||||
Key: "p2",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"p2_1": "p2v1",
|
||||
"p2_2": "p2v2",
|
||||
"p2_3": "p2v3",
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
cache := NewPartitionedLazyCache(p1, p2)
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < 10; j++ {
|
||||
v, err := cache.Get("p1", "p1_1")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(v, qt.Equals, "p1v1")
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
@@ -346,7 +346,10 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
|
||||
|
||||
cfg.Logger = logger
|
||||
c.logger = logger
|
||||
c.serverConfig = hconfig.DecodeServer(cfg.Cfg)
|
||||
c.serverConfig, err = hconfig.DecodeServer(cfg.Cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createMemFs := config.GetBool("renderToMemory")
|
||||
|
||||
|
||||
@@ -212,6 +212,7 @@ type hugoBuilderCommon struct {
|
||||
memprofile string
|
||||
mutexprofile string
|
||||
traceprofile string
|
||||
printm bool
|
||||
|
||||
// TODO(bep) var vs string
|
||||
logging bool
|
||||
@@ -299,6 +300,7 @@ func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().BoolP("path-warnings", "", false, "print warnings on duplicate target paths etc.")
|
||||
cmd.Flags().StringVarP(&cc.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`")
|
||||
cmd.Flags().StringVarP(&cc.memprofile, "profile-mem", "", "", "write memory profile to `file`")
|
||||
cmd.Flags().BoolVarP(&cc.printm, "print-mem", "", false, "print memory usage to screen at intervals")
|
||||
cmd.Flags().StringVarP(&cc.mutexprofile, "profile-mutex", "", "", "write Mutex profile to `file`")
|
||||
cmd.Flags().StringVarP(&cc.traceprofile, "trace", "", "", "write trace to `file` (not useful in general)")
|
||||
|
||||
|
||||
+7
-2
@@ -25,6 +25,9 @@ var _ cmder = (*deployCmd)(nil)
|
||||
// deployCmd supports deploying sites to Cloud providers.
|
||||
type deployCmd struct {
|
||||
*baseBuilderCmd
|
||||
|
||||
invalidateCDN bool
|
||||
maxDeletes int
|
||||
}
|
||||
|
||||
// TODO: In addition to the "deploy" command, consider adding a "--deploy"
|
||||
@@ -51,6 +54,8 @@ documentation.
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("invalidateCDN", cc.invalidateCDN)
|
||||
c.Set("maxDeletes", cc.maxDeletes)
|
||||
return nil
|
||||
}
|
||||
comm, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, cfgInit)
|
||||
@@ -69,8 +74,8 @@ documentation.
|
||||
cmd.Flags().Bool("confirm", false, "ask for confirmation before making changes to the target")
|
||||
cmd.Flags().Bool("dryRun", false, "dry run")
|
||||
cmd.Flags().Bool("force", false, "force upload of all files")
|
||||
cmd.Flags().Bool("invalidateCDN", true, "invalidate the CDN cache listed in the deployment target")
|
||||
cmd.Flags().Int("maxDeletes", 256, "maximum # of files to delete, or -1 to disable")
|
||||
cmd.Flags().BoolVar(&cc.invalidateCDN, "invalidateCDN", true, "invalidate the CDN cache listed in the deployment target")
|
||||
cmd.Flags().IntVar(&cc.maxDeletes, "maxDeletes", 256, "maximum # of files to delete, or -1 to disable")
|
||||
|
||||
cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ func (r Response) IsUserError() bool {
|
||||
// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
|
||||
// The args are usually filled with os.Args[1:].
|
||||
func Execute(args []string) Response {
|
||||
|
||||
hugoCmd := newCommandsBuilder().addAll().build()
|
||||
cmd := hugoCmd.getCommand()
|
||||
cmd.SetArgs(args)
|
||||
@@ -427,7 +428,37 @@ func (c *commandeer) initMutexProfile() (func(), error) {
|
||||
|
||||
}
|
||||
|
||||
func (c *commandeer) initMemTicker() func() {
|
||||
memticker := time.NewTicker(5 * time.Second)
|
||||
quit := make(chan struct{})
|
||||
printMem := func() {
|
||||
var m runtime.MemStats
|
||||
runtime.ReadMemStats(&m)
|
||||
fmt.Printf("\n\nAlloc = %v\nTotalAlloc = %v\nSys = %v\nNumGC = %v\n\n", formatByteCount(m.Alloc), formatByteCount(m.TotalAlloc), formatByteCount(m.Sys), m.NumGC)
|
||||
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-memticker.C:
|
||||
printMem()
|
||||
case <-quit:
|
||||
memticker.Stop()
|
||||
printMem()
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
return func() {
|
||||
close(quit)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *commandeer) initProfiling() (func(), error) {
|
||||
|
||||
stopCPUProf, err := c.initCPUProfile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -443,6 +474,11 @@ func (c *commandeer) initProfiling() (func(), error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var stopMemTicker func()
|
||||
if c.h.printm {
|
||||
stopMemTicker = c.initMemTicker()
|
||||
}
|
||||
|
||||
return func() {
|
||||
c.initMemProfile()
|
||||
|
||||
@@ -456,6 +492,10 @@ func (c *commandeer) initProfiling() (func(), error) {
|
||||
if stopTraceProf != nil {
|
||||
stopTraceProf()
|
||||
}
|
||||
|
||||
if stopMemTicker != nil {
|
||||
stopMemTicker()
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1175,3 +1215,17 @@ func pickOneWriteOrCreatePath(events []fsnotify.Event) string {
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func formatByteCount(b uint64) string {
|
||||
const unit = 1000
|
||||
if b < unit {
|
||||
return fmt.Sprintf("%d B", b)
|
||||
}
|
||||
div, exp := int64(unit), 0
|
||||
for n := b / unit; n >= unit; n /= unit {
|
||||
div *= unit
|
||||
exp++
|
||||
}
|
||||
return fmt.Sprintf("%.1f %cB",
|
||||
float64(b)/float64(div), "kMGTPE"[exp])
|
||||
}
|
||||
|
||||
+39
-8
@@ -292,6 +292,18 @@ type fileServer struct {
|
||||
s *serverCmd
|
||||
}
|
||||
|
||||
func (f *fileServer) rewriteRequest(r *http.Request, toPath string) *http.Request {
|
||||
r2 := new(http.Request)
|
||||
*r2 = *r
|
||||
r2.URL = new(url.URL)
|
||||
*r2.URL = *r.URL
|
||||
r2.URL.Path = toPath
|
||||
r2.Header.Set("X-Rewrite-Original-URI", r.URL.RequestURI())
|
||||
|
||||
return r2
|
||||
|
||||
}
|
||||
|
||||
func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, error) {
|
||||
baseURL := f.baseURLs[i]
|
||||
root := f.roots[i]
|
||||
@@ -356,29 +368,48 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
}
|
||||
|
||||
for _, header := range f.c.serverConfig.Match(r.RequestURI) {
|
||||
// Ignore any query params for the operations below.
|
||||
requestURI := strings.TrimSuffix(r.RequestURI, "?"+r.URL.RawQuery)
|
||||
|
||||
for _, header := range f.c.serverConfig.MatchHeaders(requestURI) {
|
||||
w.Header().Set(header.Key, header.Value)
|
||||
}
|
||||
|
||||
if redirect := f.c.serverConfig.MatchRedirect(requestURI); !redirect.IsZero() {
|
||||
// This matches Netlify's behaviour and is needed for SPA behaviour.
|
||||
// See https://docs.netlify.com/routing/redirects/rewrites-proxies/
|
||||
if redirect.Status == 200 {
|
||||
if r2 := f.rewriteRequest(r, strings.TrimPrefix(redirect.To, u.Path)); r2 != nil {
|
||||
requestURI = redirect.To
|
||||
r = r2
|
||||
}
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "")
|
||||
http.Redirect(w, r, redirect.To, redirect.Status)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if f.c.fastRenderMode && f.c.buildErr == nil {
|
||||
|
||||
p := strings.TrimSuffix(r.RequestURI, "?"+r.URL.RawQuery)
|
||||
if strings.HasSuffix(p, "/") || strings.HasSuffix(p, "html") || strings.HasSuffix(p, "htm") {
|
||||
if !f.c.visitedURLs.Contains(p) {
|
||||
if strings.HasSuffix(requestURI, "/") || strings.HasSuffix(requestURI, "html") || strings.HasSuffix(requestURI, "htm") {
|
||||
if !f.c.visitedURLs.Contains(requestURI) {
|
||||
// If not already on stack, re-render that single page.
|
||||
if err := f.c.partialReRender(p); err != nil {
|
||||
f.c.handleBuildErr(err, fmt.Sprintf("Failed to render %q", p))
|
||||
if err := f.c.partialReRender(requestURI); err != nil {
|
||||
f.c.handleBuildErr(err, fmt.Sprintf("Failed to render %q", requestURI))
|
||||
if f.c.showErrorInBrowser {
|
||||
http.Redirect(w, r, p, http.StatusMovedPermanently)
|
||||
http.Redirect(w, r, requestURI, http.StatusMovedPermanently)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f.c.visitedURLs.Add(p)
|
||||
f.c.visitedURLs.Add(requestURI)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2020 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 collections
|
||||
|
||||
type Order interface {
|
||||
// Ordinal is a zero-based ordinal that represents the order of an object
|
||||
// in a collection.
|
||||
Ordinal() int
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2020 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 constants
|
||||
|
||||
// Error IDs.
|
||||
// Do not change these values.
|
||||
const (
|
||||
ErrIDAmbigousDisableKindTaxonomy = "error-disable-taxonomy"
|
||||
ErrIDAmbigousOutputKindTaxonomy = "error-output-taxonomy"
|
||||
)
|
||||
@@ -16,7 +16,7 @@ package hugo
|
||||
// CurrentVersion represents the current build version.
|
||||
// This should be the only one.
|
||||
var CurrentVersion = Version{
|
||||
Number: 0.71,
|
||||
PatchLevel: 0,
|
||||
Number: 0.74,
|
||||
PatchLevel: 3,
|
||||
Suffix: "",
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2020 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 loggers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IgnorableLogger is a logger that ignores certain log statements.
|
||||
type IgnorableLogger struct {
|
||||
logger *Logger
|
||||
statements map[string]bool
|
||||
}
|
||||
|
||||
// NewIgnorableLogger wraps the given logger and ignores the log statement IDs given.
|
||||
func NewIgnorableLogger(logger *Logger, statements ...string) IgnorableLogger {
|
||||
statementsSet := make(map[string]bool)
|
||||
for _, s := range statements {
|
||||
statementsSet[strings.ToLower(s)] = true
|
||||
|
||||
}
|
||||
return IgnorableLogger{
|
||||
logger: logger,
|
||||
statements: statementsSet,
|
||||
}
|
||||
}
|
||||
|
||||
func (l IgnorableLogger) Errorf(statementID, format string, v ...interface{}) {
|
||||
if l.statements[statementID] {
|
||||
// Ignore.
|
||||
return
|
||||
}
|
||||
ignoreMsg := fmt.Sprintf(`
|
||||
If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config:
|
||||
ignoreErrors = [%q]`, statementID)
|
||||
|
||||
format += ignoreMsg
|
||||
|
||||
l.logger.ERROR.Printf(format, v...)
|
||||
}
|
||||
+10
-1
@@ -107,6 +107,15 @@ func (c *Scratch) Get(key string) interface{} {
|
||||
return val
|
||||
}
|
||||
|
||||
// Values returns the raw backing map. Note that you should just use
|
||||
// this method on the locally scoped Scratch instances you obtain via newScratch, not
|
||||
// .Page.Scratch etc., as that will lead to concurrency issues.
|
||||
func (c *Scratch) Values() map[string]interface{} {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
return c.values
|
||||
}
|
||||
|
||||
// SetInMap stores a value to a map with the given key in the Node context.
|
||||
// This map can later be retrieved with GetSortedMapValues.
|
||||
func (c *Scratch) SetInMap(key string, mapKey string, value interface{}) string {
|
||||
@@ -147,7 +156,7 @@ func (c *Scratch) GetSortedMapValues(key string) interface{} {
|
||||
return sortedArray
|
||||
}
|
||||
|
||||
// NewScratch returns a new instance Scratch.
|
||||
// NewScratch returns a new instance of Scratch.
|
||||
func NewScratch() *Scratch {
|
||||
return &Scratch{values: make(map[string]interface{})}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ func TestScratchAdd(t *testing.T) {
|
||||
scratch.Add("scratch", scratch)
|
||||
_, err := scratch.Add("scratch", scratch)
|
||||
|
||||
m := scratch.Values()
|
||||
c.Assert(m, qt.HasLen, 5)
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Expected error from invalid arithmetic")
|
||||
}
|
||||
|
||||
+14
-3
@@ -14,6 +14,7 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
@@ -59,10 +60,20 @@ func TypeToString(v interface{}) (string, bool) {
|
||||
|
||||
// ToString converts v to a string.
|
||||
func ToString(v interface{}) string {
|
||||
s, _ := ToStringE(v)
|
||||
return s
|
||||
}
|
||||
|
||||
// ToStringE converts v to a string.
|
||||
func ToStringE(v interface{}) (string, error) {
|
||||
if s, ok := TypeToString(v); ok {
|
||||
return s
|
||||
return s, nil
|
||||
}
|
||||
|
||||
return cast.ToString(v)
|
||||
|
||||
switch s := v.(type) {
|
||||
case json.RawMessage:
|
||||
return string(s), nil
|
||||
default:
|
||||
return cast.ToStringE(v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
@@ -27,3 +28,11 @@ func TestToStringSlicePreserveString(t *testing.T) {
|
||||
c.Assert(ToStringSlicePreserveString(nil), qt.IsNil)
|
||||
|
||||
}
|
||||
|
||||
func TestToString(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
c.Assert(ToString([]byte("Hugo")), qt.Equals, "Hugo")
|
||||
c.Assert(ToString(json.RawMessage("Hugo")), qt.Equals, "Hugo")
|
||||
|
||||
}
|
||||
|
||||
+71
-10
@@ -14,6 +14,8 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -101,26 +103,36 @@ func DecodeSitemap(prototype Sitemap, input map[string]interface{}) Sitemap {
|
||||
|
||||
// Config for the dev server.
|
||||
type Server struct {
|
||||
Headers []Headers
|
||||
Headers []Headers
|
||||
Redirects []Redirect
|
||||
|
||||
compiledInit sync.Once
|
||||
compiled []glob.Glob
|
||||
compiledInit sync.Once
|
||||
compiledHeaders []glob.Glob
|
||||
compiledRedirects []glob.Glob
|
||||
}
|
||||
|
||||
func (s *Server) Match(pattern string) []types.KeyValueStr {
|
||||
func (s *Server) init() {
|
||||
|
||||
s.compiledInit.Do(func() {
|
||||
for _, h := range s.Headers {
|
||||
s.compiled = append(s.compiled, glob.MustCompile(h.For))
|
||||
s.compiledHeaders = append(s.compiledHeaders, glob.MustCompile(h.For))
|
||||
}
|
||||
for _, r := range s.Redirects {
|
||||
s.compiledRedirects = append(s.compiledRedirects, glob.MustCompile(r.From))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if s.compiled == nil {
|
||||
func (s *Server) MatchHeaders(pattern string) []types.KeyValueStr {
|
||||
s.init()
|
||||
|
||||
if s.compiledHeaders == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var matches []types.KeyValueStr
|
||||
|
||||
for i, g := range s.compiled {
|
||||
for i, g := range s.compiledHeaders {
|
||||
if g.Match(pattern) {
|
||||
h := s.Headers[i]
|
||||
for k, v := range h.Values {
|
||||
@@ -137,18 +149,67 @@ func (s *Server) Match(pattern string) []types.KeyValueStr {
|
||||
|
||||
}
|
||||
|
||||
func (s *Server) MatchRedirect(pattern string) Redirect {
|
||||
s.init()
|
||||
|
||||
if s.compiledRedirects == nil {
|
||||
return Redirect{}
|
||||
}
|
||||
|
||||
pattern = strings.TrimSuffix(pattern, "index.html")
|
||||
|
||||
for i, g := range s.compiledRedirects {
|
||||
redir := s.Redirects[i]
|
||||
|
||||
// No redirect to self.
|
||||
if redir.To == pattern {
|
||||
return Redirect{}
|
||||
}
|
||||
|
||||
if g.Match(pattern) {
|
||||
return redir
|
||||
}
|
||||
}
|
||||
|
||||
return Redirect{}
|
||||
|
||||
}
|
||||
|
||||
type Headers struct {
|
||||
For string
|
||||
Values map[string]interface{}
|
||||
}
|
||||
|
||||
func DecodeServer(cfg Provider) *Server {
|
||||
type Redirect struct {
|
||||
From string
|
||||
To string
|
||||
Status int
|
||||
}
|
||||
|
||||
func (r Redirect) IsZero() bool {
|
||||
return r.From == ""
|
||||
}
|
||||
|
||||
func DecodeServer(cfg Provider) (*Server, error) {
|
||||
m := cfg.GetStringMap("server")
|
||||
s := &Server{}
|
||||
if m == nil {
|
||||
return s
|
||||
return s, nil
|
||||
}
|
||||
|
||||
_ = mapstructure.WeakDecode(m, s)
|
||||
return s
|
||||
|
||||
for i, redir := range s.Redirects {
|
||||
// Get it in line with the Hugo server.
|
||||
redir.To = strings.TrimSuffix(redir.To, "index.html")
|
||||
if !strings.HasPrefix(redir.To, "https") && !strings.HasSuffix(redir.To, "/") {
|
||||
// There are some tricky infinite loop situations when dealing
|
||||
// when the target does not have a trailing slash.
|
||||
// This can certainly be handled better, but not time for that now.
|
||||
return nil, errors.Errorf("unspported redirect to value %q in server config; currently this must be either a remote destination or a local folder, e.g. \"/blog/\" or \"/blog/index.html\"", redir.To)
|
||||
}
|
||||
s.Redirects[i] = redir
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -70,15 +70,73 @@ for = "/*.jpg"
|
||||
X-Frame-Options = "DENY"
|
||||
X-XSS-Protection = "1; mode=block"
|
||||
X-Content-Type-Options = "nosniff"
|
||||
|
||||
[[server.redirects]]
|
||||
from = "/foo/**"
|
||||
to = "/foo/index.html"
|
||||
status = 200
|
||||
|
||||
[[server.redirects]]
|
||||
from = "/google/**"
|
||||
to = "https://google.com/"
|
||||
status = 301
|
||||
|
||||
[[server.redirects]]
|
||||
from = "/**"
|
||||
to = "/default/index.html"
|
||||
status = 301
|
||||
|
||||
|
||||
|
||||
`, "toml")
|
||||
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
s := DecodeServer(cfg)
|
||||
s, err := DecodeServer(cfg)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
c.Assert(s.Match("/foo.jpg"), qt.DeepEquals, []types.KeyValueStr{
|
||||
c.Assert(s.MatchHeaders("/foo.jpg"), qt.DeepEquals, []types.KeyValueStr{
|
||||
{Key: "X-Content-Type-Options", Value: "nosniff"},
|
||||
{Key: "X-Frame-Options", Value: "DENY"},
|
||||
{Key: "X-XSS-Protection", Value: "1; mode=block"}})
|
||||
|
||||
c.Assert(s.MatchRedirect("/foo/bar/baz"), qt.DeepEquals, Redirect{
|
||||
From: "/foo/**",
|
||||
To: "/foo/",
|
||||
Status: 200,
|
||||
})
|
||||
|
||||
c.Assert(s.MatchRedirect("/someother"), qt.DeepEquals, Redirect{
|
||||
From: "/**",
|
||||
To: "/default/",
|
||||
Status: 301,
|
||||
})
|
||||
|
||||
c.Assert(s.MatchRedirect("/google/foo"), qt.DeepEquals, Redirect{
|
||||
From: "/google/**",
|
||||
To: "https://google.com/",
|
||||
Status: 301,
|
||||
})
|
||||
|
||||
// No redirect loop, please.
|
||||
c.Assert(s.MatchRedirect("/default/index.html"), qt.DeepEquals, Redirect{})
|
||||
c.Assert(s.MatchRedirect("/default/"), qt.DeepEquals, Redirect{})
|
||||
|
||||
for _, errorCase := range []string{`[[server.redirects]]
|
||||
from = "/**"
|
||||
to = "/file"
|
||||
status = 301`,
|
||||
`[[server.redirects]]
|
||||
from = "/**"
|
||||
to = "/foo/file.html"
|
||||
status = 301`,
|
||||
} {
|
||||
|
||||
cfg, err := FromConfigString(errorCase, "toml")
|
||||
c.Assert(err, qt.IsNil)
|
||||
_, err = DecodeServer(cfg)
|
||||
c.Assert(err, qt.Not(qt.IsNil))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
### Asking Support Questions
|
||||
|
||||
We have an active [discussion forum](https://discourse.gohugo.io) where users and developers can ask questions. Please don't use the GitHub issue tracker to ask questions.
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
|
||||
.header-link:after {
|
||||
position: relative;
|
||||
left: 0.5em;
|
||||
@@ -2,7 +2,7 @@
|
||||
@import '_tachyons';
|
||||
|
||||
/* purgecss start ignore */
|
||||
@import '_anchorforid';
|
||||
@import '_header-link';
|
||||
@import '_animation';
|
||||
@import '_documentation-styles';
|
||||
|
||||
@@ -36,4 +36,4 @@
|
||||
.mw-90 {
|
||||
max-width:90%;
|
||||
}
|
||||
/* purgecss end ignore */
|
||||
/* purgecss end ignore */
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
require("typeface-muli")
|
||||
import styles from './css/main.css';
|
||||
import './js/anchorforid.js'
|
||||
import './js/clipboardjs.js'
|
||||
import './js/codeblocks.js'
|
||||
import './js/docsearch.js'
|
||||
@@ -11,6 +10,3 @@ import './js/scrolldir.js'
|
||||
import './js/smoothscroll.js'
|
||||
import './js/tabs.js'
|
||||
import './js/nojs.js'
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Anchor for ID BPNY
|
||||
**/
|
||||
var anchorForId = function (id) {
|
||||
var anchor = document.createElement("a");
|
||||
anchor.className = "header-link";
|
||||
anchor.href = "#" + id;
|
||||
anchor.innerHTML = ' <svg class="fill-current o-60 hover-accent-color-light" height="22px" viewBox="0 0 24 24" width="22px" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>';
|
||||
return anchor;
|
||||
};
|
||||
|
||||
var linkifyAnchors = function (level, containingElement) {
|
||||
var headers = containingElement.getElementsByTagName("h" + level);
|
||||
for (var h = 0; h < headers.length; h++) {
|
||||
var header = headers[h];
|
||||
|
||||
if (typeof header.id !== "undefined" && header.id !== "") {
|
||||
header.appendChild(anchorForId(header.id));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
document.onreadystatechange = function () {
|
||||
if (this.readyState === "complete") {
|
||||
var contentBlock = document.getElementsByClassName("prose")[0]
|
||||
if (!contentBlock) {
|
||||
return;
|
||||
}
|
||||
for (var level = 2; level <= 4; level++) {
|
||||
linkifyAnchors(level, contentBlock);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
import styles from './../css/main.css';
|
||||
import './anchorforid.js'
|
||||
import './clipboardjs.js'
|
||||
import './codeblocks.js'
|
||||
import './docsearch.js'
|
||||
@@ -10,9 +9,7 @@ import './smoothscroll.js'
|
||||
import './tabs.js'
|
||||
import './nojs.js'
|
||||
|
||||
|
||||
|
||||
// TO use Jquery, just call the modules you want
|
||||
// TO use jQuery, just call the modules you want
|
||||
// var $ = require('jquery/src/core');
|
||||
// require('jquery/src/core/init');
|
||||
// require('jquery/src/manipulation');
|
||||
|
||||
@@ -5280,3 +5280,4 @@ code, .code, pre code, .highlight pre {
|
||||
max-width:90%;
|
||||
}
|
||||
/* purgecss end ignore */
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Generated
+5
@@ -0,0 +1,5 @@
|
||||
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}
|
||||
{{- if and (ge .Level 2) (le .Level 4) }}{{" " -}}
|
||||
<a class="header-link" href="#{{ .Anchor | safeURL }}"><svg class="fill-current o-60 hover-accent-color-light" height="22px" viewBox="0 0 24 24" width="22px" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg></a>
|
||||
{{- end -}}
|
||||
</h{{ .Level }}>
|
||||
@@ -67,7 +67,6 @@
|
||||
|
||||
{{ block "footer" . }}{{ partialCached "site-footer.html" . }}{{ end }}
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+22
-22
@@ -1,31 +1,31 @@
|
||||
{{ define "main" }}
|
||||
<article class="w-100 ph4 pb5 pb6-ns pt1 pt5-ns">
|
||||
<div class="flex-l">
|
||||
<article class="w-100 ph4 pb5 pb6-ns pt1 pt5-ns">
|
||||
<div class="flex-l">
|
||||
|
||||
<div class="order-2 w-100 w-20-l ph5-m ph0-l mb4 sticky">
|
||||
<div class="order-2 w-100 w-20-l ph5-m ph0-l mb4 sticky">
|
||||
{{- partial "toc.html" . -}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-1 w-60-l mw7 ph0 ph5-ns mid-gray nested-copy-line-height no-underline nested-links nested-img nested-copy-seperator nested-blockquote mt0-ns" style="flex-grow:1;">
|
||||
<div class="documentation-copy center measure-wide-l">
|
||||
<div id="readout" class="fixed right-0 bottom-0">
|
||||
</div>
|
||||
{{ .Render "page" }}
|
||||
{{ partial "related.html" . }}
|
||||
<div class="order-1 w-60-l mw7 ph0 ph5-ns mid-gray nested-copy-line-height no-underline nested-links nested-img nested-copy-seperator nested-blockquote mt0-ns" style="flex-grow:1;">
|
||||
<div class="documentation-copy center measure-wide-l">
|
||||
<div id="readout" class="fixed right-0 bottom-0">
|
||||
</div>
|
||||
{{ .Render "page" }}
|
||||
{{ partial "related.html" . }}
|
||||
</div>
|
||||
<div class="order-0 w-20 dn db-l">
|
||||
{{ partial "nav-links-docs.html" . }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div class="w-100 bg-light-gray">
|
||||
<div class="mw7 pa4 center nested-lh-copy lh-copy">
|
||||
{{ partial "docs/page-meta-data.html" . }}
|
||||
{{ partial "page-edit.html" . }}
|
||||
{{ partial "tags.html" . }}
|
||||
<div class="order-0 w-20 dn db-l">
|
||||
{{ partial "nav-links-docs.html" . }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
</article>
|
||||
|
||||
<div class="w-100 bg-light-gray">
|
||||
<div class="mw7 pa4 center nested-lh-copy lh-copy">
|
||||
{{ partial "docs/page-meta-data.html" . }}
|
||||
{{ partial "page-edit.html" . }}
|
||||
{{ partial "tags.html" . }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
@@ -17,10 +17,9 @@ var trackOutboundLink = function(id, url) {
|
||||
gtag('event', 'click', {
|
||||
'event_category': 'outbound',
|
||||
'event_label': id,
|
||||
'transport_type': 'beacon',
|
||||
'event_callback': function(){document.location = url;}
|
||||
'transport_type': 'beacon'
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
Generated
+1
-1
@@ -13,7 +13,7 @@
|
||||
{{ $url := printf "%s?%s" . (querify "utm_source" "homepage" "utm_medium" "banner" "utm_campaign" "hugosponsor") | safeURL }}
|
||||
{{ if eq (getenv "HUGO_ENV") "production" | or (eq $.cx.Site.Params.env "production") }}
|
||||
{{ $gtagID := printf "Sponsor %s %s" $banner.name $gtag | title }}
|
||||
<a href="{{ $url }}" onclick="trackOutboundLink({{ printf "'%s', '%s'" $gtagID $url | safeJS }}); return false;" class="grow">
|
||||
<a href="{{ $url }}" onclick="trackOutboundLink({{ printf "'%s', '%s'" $gtagID $url | safeJS }});" class="grow">
|
||||
{{ else }}
|
||||
<a href="{{ $url }}" class="grow">
|
||||
{{ end }}
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
<p class="dib">The Hugo Gopher is based on an original work by Renée French.</p>
|
||||
</div>
|
||||
|
||||
<img src="/images/gopher-side_color.svg" class="absolute-l bottom-0 dn db-l h4 right-0 z-999"/>
|
||||
<img src="/images/gopher-side_color.svg" alt="" class="absolute-l bottom-0 dn db-l h4 right-0 z-999"/>
|
||||
|
||||
<div class="bg-primary-color-dark bottom-0 left-0 right-0 dn-l fixed pb3 ph3 w-100">
|
||||
{{- partial "nav-mobile.html" . -}}
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ Showcase: {{ .Title }}
|
||||
</a>
|
||||
</li>
|
||||
{{end}}
|
||||
{{if ge $number_of_entries 20}}
|
||||
{{if gt $number_of_entries 20}}
|
||||
<li class="mt3">
|
||||
<a href="/showcase/page/2/" class="link blue">
|
||||
See More »
|
||||
|
||||
@@ -1 +1 @@
|
||||
# github.com/gohugoio/gohugoioTheme v0.0.0-20200128164921-1d0bc5482051
|
||||
# github.com/gohugoio/gohugoioTheme v0.0.0-20200711112515-b0dfe471654f
|
||||
|
||||
@@ -58,14 +58,6 @@ pattern = "2006"
|
||||
[social]
|
||||
twitter = "GoHugoIO"
|
||||
|
||||
# MARKDOWN
|
||||
## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday
|
||||
[blackfriday]
|
||||
plainIDAnchors = true
|
||||
# See https://github.com/gohugoio/hugo/issues/2424
|
||||
hrefTargetBlank = false
|
||||
angledQuotes = false
|
||||
latexDashes = true
|
||||
|
||||
[imaging]
|
||||
# See https://github.com/disintegration/imaging
|
||||
|
||||
@@ -14,12 +14,6 @@ pluralizeListTitles = false
|
||||
# We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below).
|
||||
disableAliases = true
|
||||
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
style = "trac"
|
||||
lineNumbersInTable = true
|
||||
noClasses = false
|
||||
|
||||
[outputs]
|
||||
home = [ "HTML", "RSS", "REDIR", "HEADERS" ]
|
||||
section = [ "HTML", "RSS"]
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
defaultMarkdownHandler = "goldmark"
|
||||
|
||||
[highlight]
|
||||
style = "trac"
|
||||
lineNumbersInTable = true
|
||||
noClasses = false
|
||||
|
||||
@@ -28,7 +28,7 @@ This has many benefits. The most noticeable is performance. HTTP servers are *ve
|
||||
## More on Static Site Generators
|
||||
|
||||
* ["An Introduction to Static Site Generators", David Walsh][]
|
||||
* ["Hugo vs. Wordpress page load speed comparison: Hugo leaves WordPress in its dust", GettingThingsTech][hugovwordpress]
|
||||
* ["Hugo vs. WordPress page load speed comparison: Hugo leaves WordPress in its dust", GettingThingsTech][hugovwordpress]
|
||||
* ["Static Site Generators", O'Reilly][]
|
||||
* [StaticGen: Top Open-Source Static Site Generators (GitHub Stars)][]
|
||||
* ["Top 10 Static Website Generators", Netlify blog][]
|
||||
|
||||
@@ -44,7 +44,7 @@ toc: true
|
||||
* Automatic and user defined [content summaries][]
|
||||
* [Shortcodes][] to enable rich content inside of Markdown
|
||||
* ["Minutes to Read"][pagevars] functionality
|
||||
* ["Wordcount"][pagevars] functionality
|
||||
* ["WordCount"][pagevars] functionality
|
||||
|
||||
## Additional Features
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
---
|
||||
title: Hugo and the General Data Protection Regulation (GDPR)
|
||||
linktitle: Hugo and GDPR
|
||||
@@ -98,7 +96,7 @@ useSessionStorage
|
||||
simple
|
||||
: If simple mode is enabled, a static and no-JS version of the Instagram image card will be built. Note that this only supports image cards and the image itself will be fetched from Instagram's servers.
|
||||
|
||||
**Note:** If you use the _simple mode_ for Instagram and a site styled with Bootstrap 4, you may want to disable the inlines styles provided by Hugo:
|
||||
**Note:** If you use the _simple mode_ for Instagram and a site styled with Bootstrap 4, you may want to disable the inline styles provided by Hugo:
|
||||
|
||||
{{< code-toggle file="config">}}
|
||||
[services]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Hugo's Security Model
|
||||
description: A summary of Hugo's security model.
|
||||
description: A summary of Hugo's security model.
|
||||
date: 2019-10-01
|
||||
layout: single
|
||||
keywords: ["Security", "Privacy"]
|
||||
@@ -19,7 +19,7 @@ toc: true
|
||||
|
||||
Hugo produces static output, so once built, the runtime is the browser (assuming the output is HTML) and any server (API) that you integrate with.
|
||||
|
||||
But when developing and building your site, the runtime is the `hugo` executable. Securing a runtime can be [a real challenge](https://blog.logrocket.com/how-to-protect-your-node-js-applications-from-malicious-dependencies-5f2e60ea08f9/).
|
||||
But when developing and building your site, the runtime is the `hugo` executable. Securing a runtime can be [a real challenge](https://blog.logrocket.com/how-to-protect-your-node-js-applications-from-malicious-dependencies-5f2e60ea08f9/).
|
||||
|
||||
**Hugo's main approach is that of sandboxing:**
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ Hugo is for people who want to hand code their own website without worrying abou
|
||||
|
||||
Hugo is for people building a blog, a company site, a portfolio site, documentation, a single landing page, or a website with thousands of pages.
|
||||
|
||||
|
||||
|
||||
[@spf13]: https://twitter.com/@spf13
|
||||
[@spf13]: https://twitter.com/spf13
|
||||
[Aerobatic]: https://www.aerobatic.com/
|
||||
[Amazon S3]: https://aws.amazon.com/s3/
|
||||
[Azure]: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website
|
||||
@@ -51,7 +49,7 @@ Hugo is for people building a blog, a company site, a portfolio site, documentat
|
||||
[GitHub Pages]: https://pages.github.com/
|
||||
[GitLab Pages]: https://about.gitlab.com/features/pages/
|
||||
[Go language]: https://golang.org/
|
||||
[GoDaddy]: https://www.godaddy.com/ "Godaddy.com Hosting"
|
||||
[GoDaddy]: https://www.godaddy.com/ "GoDaddy.com Hosting"
|
||||
[Google Cloud Storage]: https://cloud.google.com/storage/
|
||||
[Heroku]: https://www.heroku.com/
|
||||
[Jekyll]: https://jekyllrb.com/
|
||||
@@ -61,5 +59,5 @@ Hugo is for people building a blog, a company site, a portfolio site, documentat
|
||||
[Rackspace]: https://www.rackspace.com/cloud/files
|
||||
[Surge]: https://surge.sh
|
||||
[contributing to it]: https://github.com/gohugoio/hugo
|
||||
[rackspace]: https://www.rackspace.com/cloud/files
|
||||
[rackspace]: https://www.rackspace.com/openstack/public/files
|
||||
[static site generator]: /about/benefits/
|
||||
|
||||
@@ -15,7 +15,7 @@ hugo is the main command, used to build your Hugo site.
|
||||
Hugo is a Fast and Flexible Static Site Generator
|
||||
built with love by spf13 and friends in Go.
|
||||
|
||||
Complete documentation is available at http://gohugo.io/.
|
||||
Complete documentation is available at https://gohugo.io/.
|
||||
|
||||
```
|
||||
hugo [flags]
|
||||
|
||||
@@ -15,7 +15,6 @@ Delete the Hugo Module cache for the current project.
|
||||
Note that after you run this command, all of your dependencies will be re-downloaded next time you run "hugo".
|
||||
|
||||
Also note that if you configure a positive maxAge for the "modules" file cache, it will also be cleaned as part of "hugo --gc".
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
@@ -18,7 +18,7 @@ Some examples:
|
||||
Install the latest version possible for a given module:
|
||||
|
||||
hugo mod get github.com/gohugoio/testshortcodes
|
||||
|
||||
|
||||
Install a specific version:
|
||||
|
||||
hugo mod get github.com/gohugoio/testshortcodes@v0.3.0
|
||||
|
||||
@@ -18,8 +18,6 @@ toc: true
|
||||
comments: Before this page is published, need to also update both site- and page-level variables documentation.
|
||||
---
|
||||
|
||||
|
||||
|
||||
Larger sites often have multiple content authors. Hugo provides standardized author profiles to organize relationships between content and content creators for sites operating under a distributed authorship model.
|
||||
|
||||
## Author Profiles
|
||||
@@ -107,7 +105,7 @@ You can find a list of all template variables to access the profile information
|
||||
|
||||
### Link Social Network Accounts
|
||||
|
||||
As aforementioned, Hugo is able to generate links to profiles of the most popular social networks. The following social networks with their corresponding identifiers are supported: `github`, `facebook`, `twitter`, `pinterest`, `instagram`, `youtube` and `linkedin`.
|
||||
As aforementioned, Hugo is able to generate links to profiles of the most popular social networks. The following social networks with their corresponding identifiers are supported: `github`, `facebook`, `twitter`, `pinterest`, `instagram`, `youtube` and `linkedin`.
|
||||
|
||||
This is can be done with the `.Social.URL` function. Its only parameter is the name of the social network as they are defined in the profile (e.g. `facebook`, `twitter`). Custom variables like `website` remain as they are.
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Note that we extended this property from a boolean to an enum in Hugo 0.68.0.
|
||||
Valid values are:
|
||||
|
||||
never
|
||||
: The page will not be incldued in any page collection.
|
||||
: The page will not be included in any page collection.
|
||||
|
||||
always (default)
|
||||
: The page will be included in all page collections, e.g. `site.RegularPages`, `$page.Pages`.
|
||||
|
||||
@@ -56,12 +56,12 @@ There are a few alternatives to commenting on static sites for those who do not
|
||||
* [IntenseDebate](https://intensedebate.com/)
|
||||
* [Graph Comment][]
|
||||
* [Muut](https://muut.com/)
|
||||
* [isso](https://posativ.org/isso/) (Self-hosted, Python)
|
||||
* [Isso](https://posativ.org/isso/) (Self-hosted, Python)
|
||||
* [Tutorial on Implementing Isso with Hugo][issotutorial]
|
||||
* [Utterances](https://utteranc.es/) (Open source, GitHub comments widget built on GitHub issues)
|
||||
* [Remark](https://github.com/umputun/remark) (Open source, Golang, Easy to run docker)
|
||||
* [Commento](https://commento.io/) (Open Source, available as a service, local install, or docker image)
|
||||
* [JustComments](https://just-comments.com) (Open Source, available as a service, can be self-hosted)
|
||||
* [Hyvor Talk](https://talk.hyvor.com/) (Available as a service)
|
||||
|
||||
|
||||
[configuration]: /getting-started/configuration/
|
||||
|
||||
@@ -33,8 +33,8 @@ The current list of content formats in Hugo:
|
||||
| Blackfriday | blackfriday |Blackfriday will eventually be deprecated.|
|
||||
|MMark|mmark|Mmark is deprecated and will be removed in a future release.|
|
||||
|Emacs Org-Mode|org|See [go-org](https://github.com/niklasfasching/go-org).|
|
||||
|Asciidoc|asciidoc, adoc, ad|Needs Asciidoc or [Asciidoctor][ascii] installed.|
|
||||
|RST|rst|Needs [RST](https://docutils.sourceforge.io/rst.html) installed.|
|
||||
|AsciiDoc|asciidocext, adoc, ad|Needs [Asciidoctor][ascii] installed.|
|
||||
|RST|rst|Needs [RST](http://docutils.sourceforge.net/rst.html) installed.|
|
||||
|Pandoc|pandoc, pdc|Needs [Pandoc](https://www.pandoc.org/) installed.|
|
||||
|HTML|html, htm|To be treated as a content file, with layout, shortcodes etc., it must have front matter. If not, it will be copied as-is.|
|
||||
|
||||
@@ -43,19 +43,66 @@ The `markup identifier` is fetched from either the `markup` variable in front ma
|
||||
|
||||
## External Helpers
|
||||
|
||||
Some of the formats in the table above needs external helpers installed on your PC. For example, for Asciidoc files, Hugo will try to call the `asciidoctor` or `asciidoc` command. This means that you will have to install the associated tool on your machine to be able to use these formats. ([See the Asciidoctor docs for installation instructions](https://asciidoctor.org/docs/install-toolchain/)).
|
||||
Some of the formats in the table above needs external helpers installed on your PC. For example, for AsciiDoc files,
|
||||
Hugo will try to call the `asciidoctor` command. This means that you will have to install the associated
|
||||
tool on your machine to be able to use these formats.
|
||||
|
||||
Hugo passes reasonable default arguments to these external helpers by default:
|
||||
|
||||
- `asciidoc`: `--no-header-footer --safe -`
|
||||
- `asciidoctor`: `--no-header-footer --safe --trace -`
|
||||
- `asciidoctor`: `--no-header-footer --trace -`
|
||||
- `rst2html`: `--leave-comments --initial-header-level=2`
|
||||
- `pandoc`: `--mathjax`
|
||||
|
||||
{{% warning "Performance of External Helpers" %}}
|
||||
Because additional formats are external commands generation performance will rely heavily on the performance of the external tool you are using. As this feature is still in its infancy, feedback is welcome.
|
||||
Because additional formats are external commands, generation performance will rely heavily on the performance of the external tool you are using. As this feature is still in its infancy, feedback is welcome.
|
||||
{{% /warning %}}
|
||||
|
||||
### External Helper AsciiDoc
|
||||
|
||||
[AsciiDoc](https://github.com/asciidoc/asciidoc) implementation EOLs in Jan 2020 and is no longer supported.
|
||||
AsciiDoc development is being continued under [Asciidoctor](https://github.com/asciidoctor). The format AsciiDoc
|
||||
remains of course. Please continue with the implementation Asciidoctor.
|
||||
|
||||
### External Helper Asciidoctor
|
||||
|
||||
The Asciidoctor community offers a wide set of tools for the AsciiDoc format that can be installed additionally to Hugo.
|
||||
[See the Asciidoctor docs for installation instructions](https://asciidoctor.org/docs/install-toolchain/). Make sure that also all
|
||||
optional extensions like `asciidoctor-diagram` or `asciidoctor-html5s` are installed if required.
|
||||
|
||||
Asciidoctor parameters can be customized in Hugo:
|
||||
|
||||
Parameter | Default | Comment
|
||||
--- | --- | ---
|
||||
backend | `html5` | Don't change this unless you know what you are doing.
|
||||
doctype | `article` | Currently supported Document type is `article`.
|
||||
extensions | | Possible extensions are `asciidoctor-html5s`, `asciidoctor-bibtex`, `asciidoctor-diagram`, `asciidoctor-interdoc-reftext`, `asciidoctor-katex`, `asciidoctor-latex`, `asciidoctor-mathematical`, `asciidoctor-question`, `asciidoctor-rouge`.
|
||||
attributes | | Variables to be referenced in your `adoc` file. This is a list of variable name/value maps. See [Asciidoctor#attributes](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions).
|
||||
noheaderorfooter | true | Output an embeddable document, which excludes the header, the footer, and everything outside the body of the document. Don't change this unless you know what you are doing.
|
||||
safemode | `unsafe` | Safe mode level `unsafe`, `safe`, `server` or `secure`. Don't change this unless you know what you are doing.
|
||||
sectionnumbers | `false` | Auto-number section titles.
|
||||
verbose | `false` | Verbosely print processing information and configuration file checks to stderr.
|
||||
trace | `true` | Include backtrace information on errors.
|
||||
failurelevel | `fatal` | The minimum logging level that triggers a non-zero exit code (failure).
|
||||
workingfoldercurrent | `false` | Set the working folder to the rendered `adoc` file, so [include](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files) will work with relative paths. This setting uses the `asciidoctor` cli parameter `--base-dir` and attribute `outdir=`. For rendering [asciidoctor-diagram](https://asciidoctor.org/docs/asciidoctor-diagram/) `workingfoldercurrent` must be set to `true`.
|
||||
|
||||
```
|
||||
[markup.asciidocext]
|
||||
extensions = ["asciidoctor-html5s", "asciidoctor-diagram"]
|
||||
workingFolderCurrent = true
|
||||
[markup.asciidocext.attributes]
|
||||
my-base-url = "https://example.com/"
|
||||
my-attribute-name = "my value"
|
||||
```
|
||||
|
||||
Important: External `asciidoctor` requires Hugo rendering to _disk_ to a specific destination folder. It is required to run Hugo with the command option `--destination`!
|
||||
|
||||
In a complex Asciidoctor environment it is sometimes helpful to debug the exact call to your external helper with all
|
||||
parameters. Run Hugo with `-v`. You will get an output like
|
||||
|
||||
```
|
||||
INFO 2019/12/22 09:08:48 Rendering book-as-pdf.adoc with C:\Ruby26-x64\bin\asciidoctor.bat using asciidoc args [--no-header-footer -r asciidoctor-html5s -b html5s -r asciidoctor-diagram --base-dir D:\prototypes\hugo_asciidoc_ddd\docs -a outdir=D:\prototypes\hugo_asciidoc_ddd\build -] ...
|
||||
```
|
||||
|
||||
## Learn Markdown
|
||||
|
||||
Markdown syntax is simple enough to learn in a single sitting. The following are excellent resources to get you up and running:
|
||||
|
||||
@@ -135,7 +135,7 @@ videos
|
||||
: an array of paths to videos related to the page; used by the `opengraph` [internal template](/templates/internal) to populate `og:video`.
|
||||
|
||||
weight
|
||||
: used for [ordering your content in lists][ordering]. Lower weight gets higher precedence. So content with lower weight will come first.
|
||||
: used for [ordering your content in lists][ordering]. Lower weight gets higher precedence. So content with lower weight will come first. If set, weights should be non-zero, as 0 is interpreted as an *unset* weight.
|
||||
|
||||
\<taxonomies\>
|
||||
: field name of the *plural* form of the index. See `tags` and `categories` in the above front matter examples. _Note that the plural form of user-defined taxonomies cannot be the same as any of the predefined front matter variables._
|
||||
|
||||
@@ -98,7 +98,7 @@ Sometimes it can be useful to create the filter chain once and then reuse it:
|
||||
|
||||
Provides an [Exif](https://en.wikipedia.org/wiki/Exif) object with metadata about the image.
|
||||
|
||||
Note that this is only suported for JPEG and TIFF images, so it's recommended to wrap the access with a `with`, e.g.:
|
||||
Note that this is only supported for JPEG and TIFF images, so it's recommended to wrap the access with a `with`, e.g.:
|
||||
|
||||
```go-html-template
|
||||
{{ with $img.Exif }}
|
||||
@@ -180,7 +180,10 @@ Rotates an image by the given angle counter-clockwise. The rotation will be perf
|
||||
### Anchor
|
||||
|
||||
Only relevant for the `Fill` method. This is useful for thumbnail generation where the main motive is located in, say, the left corner.
|
||||
Valid are `Center`, `TopLeft`, `Top`, `TopRight`, `Left`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`.
|
||||
|
||||
Valid values are `Smart`, `Center`, `TopLeft`, `Top`, `TopRight`, `Left`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`.
|
||||
|
||||
Default value is `Smart`, which uses [Smartcrop](https://github.com/muesli/smartcrop) to determine the best crop.
|
||||
|
||||
```go
|
||||
{{ $image.Fill "300x200 BottomLeft" }}
|
||||
|
||||
@@ -63,7 +63,7 @@ When working with front matter `Params` in [single page templates][singles], omi
|
||||
|
||||
`defaultContentLanguage` sets the project's default language. If not set, the default language will be `en`.
|
||||
|
||||
If the default language needs to be rendererd below its own language code (`/en`) like the others, set `defaultContentLanguageInSubdir: true`.
|
||||
If the default language needs to be rendered below its own language code (`/en`) like the others, set `defaultContentLanguageInSubdir: true`.
|
||||
|
||||
Only the obvious non-global options can be overridden per language. Examples of global options are `baseURL`, `buildDrafts`, etc.
|
||||
|
||||
@@ -125,7 +125,7 @@ public
|
||||
|
||||
**All URLs (i.e `.Permalink` etc.) will be generated from that root. So the English home page above will have its `.Permalink` set to `https://example.com/`.**
|
||||
|
||||
When you run `hugo server` we will start multiple HTTP servers. You will typlically see something like this in the console:
|
||||
When you run `hugo server` we will start multiple HTTP servers. You will typically see something like this in the console:
|
||||
|
||||
```bash
|
||||
Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1)
|
||||
@@ -204,7 +204,7 @@ languages:
|
||||
|
||||
The value of `contentDir` can be any valid path -- even absolute path references. The only restriction is that the content directories cannot overlap.
|
||||
|
||||
Considering the following example in conjunction with the configuration above:
|
||||
Considering the following example in conjunction with the configuration above:
|
||||
|
||||
1. `/content/english/about.md`
|
||||
2. `/content/french/about.md`
|
||||
|
||||
@@ -23,9 +23,9 @@ Hugo `0.32` announced page-relative images and other resources packaged into `Pa
|
||||
|
||||
These terms are connected, and you also need to read about [Page Resources]({{< relref "/content-management/page-resources" >}}) and [Image Processing]({{< relref "/content-management/image-processing" >}}) to get the full picture.
|
||||
|
||||
{{% imgproc 1-featured Resize "300x" %}}
|
||||
{{< imgproc 1-featured Resize "300x" >}}
|
||||
The illustration shows 3 bundles. Note that the home page bundle cannot contain other content pages, but other files (images etc.) are fine.
|
||||
{{% /imgproc %}}
|
||||
{{< /imgproc >}}
|
||||
|
||||
|
||||
{{% note %}}
|
||||
@@ -112,7 +112,7 @@ Single content files in each of your sections are going to be rendered as [singl
|
||||
content/posts/my-first-hugo-post.md
|
||||
```
|
||||
|
||||
At the time Hugo builds your site, the content will be output to the following destination:
|
||||
When Hugo builds your site, the content will be outputted to the following destination:
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ GetMatch
|
||||
|
||||
## Page Resources Metadata
|
||||
|
||||
The page resources' metadata is managed from the corresponding page's front matter with an array/table parameter named `resources`. You can batch assign values using [wildcards](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm).
|
||||
The page resources' metadata is managed from the corresponding page's front matter with an array/table parameter named `resources`. You can batch assign values using [wildcards](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm).
|
||||
|
||||
{{% note %}}
|
||||
Resources of type `page` get `Title` etc. from their own front matter.
|
||||
|
||||
@@ -21,7 +21,7 @@ toc: true
|
||||
|
||||
## What a Shortcode is
|
||||
|
||||
Hugo loves Markdown because of its simple content format, but there are times when Markdown falls short. Often, content authors are forced to add raw HTML (e.g., video `<iframes>`) to Markdown content. We think this contradicts the beautiful simplicity of Markdown's syntax.
|
||||
Hugo loves Markdown because of its simple content format, but there are times when Markdown falls short. Often, content authors are forced to add raw HTML (e.g., video `<iframe>`'s) to Markdown content. We think this contradicts the beautiful simplicity of Markdown's syntax.
|
||||
|
||||
Hugo created **shortcodes** to circumvent these limitations.
|
||||
|
||||
@@ -418,7 +418,7 @@ To learn more about creating custom shortcodes, see the [shortcode template docu
|
||||
[`figure` shortcode]: #figure
|
||||
[contentmanagementsection]: /content-management/formats/
|
||||
[examplegist]: https://gist.github.com/spf13/7896402
|
||||
[figureelement]: http://html5doctor.com/the-figure-figcaption-elements/ "An article from HTML5 doctor discussing the fig and figcaption elements."
|
||||
[figureelement]: https://html5doctor.com/the-figure-figcaption-elements/ "An article from HTML5 doctor discussing the fig and figcaption elements."
|
||||
[Hugo and the GDPR]: /about/hugo-and-gdpr/
|
||||
[Instagram]: https://www.instagram.com/
|
||||
[pagevariables]: /variables/page/
|
||||
|
||||
@@ -43,10 +43,9 @@ Highlighting is carried out via the [built-in shortcode](/content-management/sho
|
||||
|
||||
Options:
|
||||
|
||||
* `linenos`: Valid values are `true`, `false`, `table`, `inline`. `table` will give copy-and-paste friendly code blocks) turns on line numbers.
|
||||
* Setting `linenos` to `false` will turn off linenumbers if it's configured to be on in site config.{{< new-in "0.60.0" >}}
|
||||
* `hl_lines` lists a set of line numbers or line number ranges to be highlighted.
|
||||
* `linenostart=199` starts the line number count from 199.
|
||||
* `linenos`: configure line numbers. Valid values are `true`, `false`, `table`, or `inline`. `false` will turn off line numbers if it's configured to be on in site config. {{< new-in "0.60.0" >}} `table` will give copy-and-paste friendly code blocks.
|
||||
* `hl_lines`: lists a set of line numbers or line number ranges to be highlighted.
|
||||
* `linenostart=199`: starts the line number count from 199.
|
||||
|
||||
### Example: Highlight Shortcode
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
---
|
||||
title: Taxonomies
|
||||
linktitle:
|
||||
description: Hugo includes support for user-defined taxonomies to help you demonstrate logical relationships between content for the end users of your website.
|
||||
description: Hugo includes support for user-defined taxonomies.
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
keywords: [taxonomies,metadata,front matter,terms]
|
||||
categories: [content management]
|
||||
menu:
|
||||
@@ -32,7 +31,6 @@ Term
|
||||
Value
|
||||
: a piece of content assigned to a term
|
||||
|
||||
{{< youtube pCPCQgqC8RA >}}
|
||||
|
||||
## Example Taxonomy: Movie Website
|
||||
|
||||
@@ -97,9 +95,13 @@ Without adding a single line to your [site config][config] file, Hugo will autom
|
||||
If you do not want Hugo to create any taxonomies, set `disableKinds` in your [site config][config] to the following:
|
||||
|
||||
{{< code-toggle copy="false" >}}
|
||||
disableKinds = ["taxonomy","taxonomyTerm"]
|
||||
disableKinds = ["taxonomy","term"]
|
||||
{{</ code-toggle >}}
|
||||
|
||||
{{< new-in "0.73.0" >}} We have fixed the before confusing page kinds used for taxonomies (see the listing below) to be in line with the terms used when we talk about taxonomies. We have been careful to avoid site breakage, and you should get an ERROR in the console if you need to adjust your `disableKinds` section.
|
||||
|
||||
{{% page-kinds %}}
|
||||
|
||||
### Default Destinations
|
||||
|
||||
When taxonomies are used---and [taxonomy templates][] are provided---Hugo will automatically create both a page listing all the taxonomy's terms and individual pages with lists of content associated with each term. For example, a `categories` taxonomy declared in your configuration and used in your content front matter will create the following pages:
|
||||
@@ -190,18 +192,17 @@ By using taxonomic weight, the same piece of content can appear in different pos
|
||||
Currently taxonomies only support the [default `weight => date` ordering of list content](/templates/lists/#default-weight-date). For more information, see the documentation on [taxonomy templates](/templates/taxonomy-templates/).
|
||||
{{% /note %}}
|
||||
|
||||
## Add custom metadata to a Taxonomy Term
|
||||
## Add custom metadata a Taxonomy or Term
|
||||
|
||||
If you need to add custom metadata to your taxonomy terms, you will need to create a page for that term at `/content/<TAXONOMY>/<TERM>/_index.md` and add your metadata in it's front matter. Continuing with our 'Actors' example, let's say you want to add a wikipedia page link to each actor. Your terms pages would be something like this:
|
||||
If you need to add custom metadata to your taxonomy terms, you will need to create a page for that term at `/content/<TAXONOMY>/<TERM>/_index.md` and add your metadata in it's front matter. Continuing with our 'Actors' example, let's say you want to add a Wikipedia page link to each actor. Your terms pages would be something like this:
|
||||
|
||||
{{< code file="/content/actors/bruce-willis/_index.md" >}}
|
||||
---
|
||||
title: "Bruce Willis"
|
||||
wikipedia: "https://en.wikipedia.org/wiki/Bruce_Willis"
|
||||
---
|
||||
---
|
||||
title: "Bruce Willis"
|
||||
wikipedia: "https://en.wikipedia.org/wiki/Bruce_Willis"
|
||||
---
|
||||
{{< /code >}}
|
||||
|
||||
You can later use your custom metadata as shown in the [Taxonomy Terms Templates documentation](/templates/taxonomy-templates/#displaying-custom-metadata-in-taxonomy-terms-templates).
|
||||
|
||||
[`urlize` template function]: /functions/urlize/
|
||||
[content section]: /content-management/sections/
|
||||
|
||||
@@ -38,6 +38,13 @@ permalinks:
|
||||
|
||||
Only the content under `posts/` will have the new URL structure. For example, the file `content/posts/sample-entry.md` with `date: 2017-02-27T19:20:00-05:00` in its front matter will render to `public/2017/02/sample-entry/index.html` at build time and therefore be reachable at `https://example.com/2017/02/sample-entry/`.
|
||||
|
||||
To configure the `permalinks` option for pages in the "root" section, use **/** as the key:
|
||||
|
||||
{{< code-toggle file="config" copy="false" >}}
|
||||
permalinks:
|
||||
/: /:year/:month/:filename/
|
||||
{{< /code-toggle >}}
|
||||
|
||||
If the standard date-based permalink configuration does not meet your needs, you can also format URL segments using [Go time formatting directives](https://golang.org/pkg/time/#Time.Format). For example, a URL structure with two digit years and month and day digits without zero padding can be accomplished with:
|
||||
|
||||
{{< code-toggle file="config" copy="false" >}}
|
||||
@@ -202,7 +209,7 @@ content/posts/post-1.md
|
||||
|
||||
## Ugly URLs
|
||||
|
||||
If you would like to have what are often referred to as "ugly URLs" (e.g., example.com/urls.html), set `uglyurls = true` or `uglyurls: true` in your site's `config.toml` or `config.yaml`, respectively. You can also use the `--uglyURLs=true` [flag from the command line][usage] with `hugo` or `hugo server`.
|
||||
If you would like to have what are often referred to as "ugly URLs" (e.g., example.com/urls.html), set `uglyurls = true` or `uglyurls: true` in your site's `config.toml` or `config.yaml`, respectively. You can also set the `HUGO_UGLYURLS` environment variable to `true` when running `hugo` or `hugo server`.
|
||||
|
||||
If you want a specific piece of content to have an exact URL, you can specify this in the [front matter][] under the `url` key. The following are examples of the same content directory and what the eventual URL structure will be when Hugo runs with its default behavior.
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ aliases: []
|
||||
toc: false
|
||||
layout: documentation-home
|
||||
---
|
||||
Hugo is the **world's fastest static website engine.** It's written in Go (aka Golang) and developed by [bep](https://github.com/bep), [spf13](https://github.com/spf13) and [friends](https://github.com/gohugoio/hugo/graphs/contributors).
|
||||
|
||||
Hugo is the **world's fastest static website engine.** It's written in Go (aka Golang) and developed by [bep](https://github.com/bep), [spf13](https://github.com/spf13) and [friends](https://github.com/gohugoio/hugo/graphs/contributors).
|
||||
|
||||
Below you will find some of the most common and helpful pages from our documentation.
|
||||
|
||||
@@ -18,8 +18,7 @@ deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
|
||||
By default all matches will be included. The number of matches can be limitted with an optional third parameter.
|
||||
By default all matches will be included. The number of matches can be limited with an optional third parameter.
|
||||
|
||||
The example below returns a list of all second level headers (`<h2>`) in the content:
|
||||
|
||||
@@ -40,7 +39,6 @@ Hugo uses Go's [Regular Expression package](https://golang.org/pkg/regexp/), whi
|
||||
If you are just learning RegEx, or at least Go's flavor, you can practice pattern matching in the browser at <https://regex101.com/>.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
[partials]: /templates/partials/
|
||||
[`plainify`]: /functions/plainify/
|
||||
[toc]: /content-management/toc/
|
||||
|
||||
@@ -20,7 +20,7 @@ aliases: []
|
||||
|
||||
Takes a string containing the name of the variable as input. Returns
|
||||
an empty string if the variable is not set, otherwise returns the
|
||||
value of the variable.
|
||||
value of the variable.
|
||||
|
||||
```
|
||||
{{ getenv "HOME" }}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: hmac
|
||||
linktitle: hmac
|
||||
description: Compute the cryptographic checksum of a message.
|
||||
godocref:
|
||||
date: 2020-05-29
|
||||
publishdate: 2020-05-29
|
||||
lastmod: 2020-05-29
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [hmac,checksum]
|
||||
signature: ["hmac HASH_TYPE KEY MESSAGE"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [hmac]
|
||||
deprecated: false
|
||||
aliases: [hmac]
|
||||
---
|
||||
|
||||
`hmac` returns a cryptographic hash that uses a key to sign a message.
|
||||
|
||||
```
|
||||
{{ hmac "sha256" "Secret key" "Hello world, gophers!"}},
|
||||
<!-- returns the string "b6d11b6c53830b9d87036272ca9fe9d19306b8f9d8aa07b15da27d89e6e34f40"
|
||||
```
|
||||
|
||||
Supported hash functions:
|
||||
|
||||
* md5
|
||||
* sha1
|
||||
* sha256
|
||||
* sha512
|
||||
@@ -22,5 +22,5 @@ aliases: []
|
||||
In the result `&` becomes `&` and so on. It escapes only: `<`, `>`, `&`, `'` and `"`.
|
||||
|
||||
```
|
||||
{{ htmlEscape "Hugo & Caddy > Wordpress & Apache" }} → "Hugo & Caddy > Wordpress & Apache"
|
||||
{{ htmlEscape "Hugo & Caddy > WordPress & Apache" }} → "Hugo & Caddy > WordPress & Apache"
|
||||
```
|
||||
|
||||
@@ -19,10 +19,10 @@ deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
`htmlUnescape` returns the given string with HTML escape codes un-escaped.
|
||||
`htmlUnescape` returns the given string with HTML escape codes un-escaped.
|
||||
|
||||
Remember to pass the output of this to `safeHTML` if fully un-escaped characters are desired. Otherwise, the output will be escaped again as normal.
|
||||
|
||||
```
|
||||
{{ htmlUnescape "Hugo & Caddy > Wordpress & Apache" }} → "Hugo & Caddy > Wordpress & Apache"
|
||||
{{ htmlUnescape "Hugo & Caddy > WordPress & Apache" }} → "Hugo & Caddy > WordPress & Apache"
|
||||
```
|
||||
|
||||
@@ -20,7 +20,7 @@ deprecated: false
|
||||
draft: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
|
||||
`hugo` returns an instance that contains the following functions:
|
||||
|
||||
hugo.Generator
|
||||
@@ -29,7 +29,7 @@ hugo.Generator
|
||||
hugo.Version
|
||||
: the current version of the Hugo binary you are using e.g. `0.63.2`
|
||||
|
||||
|
||||
|
||||
`hugo` returns an instance that contains the following functions:
|
||||
|
||||
hugo.Environment
|
||||
|
||||
@@ -38,8 +38,6 @@ The function takes multiple indices as arguments, and this can be used to get ne
|
||||
{{ index $map "c" "e" }} => 20
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Example: Load Data from a Path Based on Front Matter Params
|
||||
|
||||
Assume you want to add a `location = ""` field to your front matter for every article written in `content/vacations/`. You want to use this field to populate information about the location at the bottom of the article in your `single.html` template. You also have a directory in `data/locations/` that looks like the following:
|
||||
@@ -93,4 +91,3 @@ Now the call will return the specific file according to the location specified i
|
||||
{{ (index .Site.Data.locations .Params.location).pop_city }}
|
||||
=> 658390
|
||||
```
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ draft: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
|
||||
```
|
||||
{{ range last 10 .Pages }}
|
||||
{{ .Render "summary" }}
|
||||
|
||||
@@ -19,8 +19,6 @@ deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
|
||||
|
||||
```
|
||||
{{ md5 "Hello world, gophers!" }}
|
||||
<!-- returns the string "b3029f756f98f79e7f1b7f1d1f0dd53b" -->
|
||||
|
||||
@@ -14,7 +14,7 @@ keywords: [strings]
|
||||
signature: ["plainify INPUT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [jsonify,]
|
||||
relatedfuncs: [jsonify]
|
||||
deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
@@ -25,7 +25,4 @@ aliases: []
|
||||
|
||||
See also the `.PlainWords`, `.Plain`, and `.RawContent` [page variables][pagevars].
|
||||
|
||||
|
||||
[pagevars]: /variables/page/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: relURL
|
||||
description: Given a string, prepends the relative URL according to a page's position in the project directory structure.
|
||||
description: Creates a baseURL-relative URL.
|
||||
godocref:
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
|
||||
@@ -113,6 +113,11 @@ Removes the given key
|
||||
{{ .Scratch.Delete "greetings" }}
|
||||
```
|
||||
|
||||
#### .Values
|
||||
|
||||
`Values` returns the raw backing map. Note that you should just use this method on the locally scoped `Scratch` instances you obtain via `newScratch`, not
|
||||
`.Page.Scratch` etc., as that will lead to concurrency issues.
|
||||
|
||||
## Scope
|
||||
The scope of the backing data is global for the given `Page` or `Shortcode`, and spans partial and shortcode includes.
|
||||
|
||||
|
||||
@@ -48,4 +48,4 @@ $indexStartingAt1 := (add $index 1)
|
||||
```
|
||||
|
||||
|
||||
[GNU's seq]: http://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html#seq-invocation
|
||||
[GNU's seq]: https://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html#seq-invocation
|
||||
|
||||
@@ -22,7 +22,7 @@ toc: false
|
||||
deprecated: false
|
||||
---
|
||||
|
||||
A template file is any file living below the `layouts` directories of either the project or any of its theme components incudling partials and shortcodes.
|
||||
A template file is any file living below the `layouts` directories of either the project or any of its theme components including partials and shortcodes.
|
||||
|
||||
The function is particularly handy with dynamic path. The following example ensures the build will not break on a `.Type` missing its dedicated `header` partial.
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ aliases: []
|
||||
|
||||
## Example: Using `time` to get Month Index
|
||||
|
||||
The following example takes a UNIX timestamp---set as `utimestamp: "1489276800"` in a content's front matter---converts the timestamp (string) to an integer using the [`int` function][int], and then uses [`printf`][] to convert the `Month` property of `time` into an index.
|
||||
The following example takes a UNIX timestamp---set as `utimestamp: "1489276800"` in a content's front matter---converts the timestamp (string) to an integer using the [`int` function][int], and then uses [`printf`][] to convert the `Month` property of `time` into an index.
|
||||
|
||||
The following example may be useful when setting up [multilingual sites][multilingual]:
|
||||
|
||||
|
||||
@@ -33,6 +33,4 @@ Since both values are integers, they can be subtracted and then divided by the n
|
||||
Hugo's output is *static*. For the example above to be realistic, the site needs to be built every day.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
|
||||
[partial template]: /templates/partials/
|
||||
|
||||
@@ -21,7 +21,7 @@ aliases: []
|
||||
|
||||
|
||||
```
|
||||
{{ $url := urls.Parse "http://www.gohugo.io" }}
|
||||
{{ $url := urls.Parse "http://www.gohugo.io" }}
|
||||
```
|
||||
|
||||
and returns a [URL](https://godoc.org/net/url#URL) structure. The struct fields are accessed via the `.` notation:
|
||||
|
||||
@@ -85,9 +85,15 @@ ordered
|
||||
|
||||
Note that this is only supported with the [Goldmark](#goldmark) renderer.
|
||||
|
||||
These Render Hooks allow custom templates to render links and images from markdown.
|
||||
Render Hooks allow custom templates to override markdown rendering functionality. You can do this by creating templates with base names `render-{feature}` in `layouts/_default/_markup`.
|
||||
|
||||
You can do this by creating templates with base names `render-link` and/or `render-image` inside `layouts/_default/_markup`.
|
||||
You can also create type/section specific hooks in `layouts/[type/section]/_markup`, e.g.: `layouts/blog/_markup`.{{< new-in "0.71.0" >}}
|
||||
|
||||
The features currently supported are:
|
||||
|
||||
* `image`
|
||||
* `link`
|
||||
* `heading` {{< new-in "0.71.0" >}}
|
||||
|
||||
You can define [Output-Format-](/templates/output-formats) and [language-](/content-management/multilingual/)specific templates if needed.[^hooktemplate] Your `layouts` folder may look like this:
|
||||
|
||||
@@ -105,10 +111,11 @@ Some use cases for the above:
|
||||
* Resolve link references using `.GetPage`. This would make links portable as you could translate `./my-post.md` (and similar constructs that would work on GitHub) into `/blog/2019/01/01/my-post/` etc.
|
||||
* Add `target=_blank` to external links.
|
||||
* Resolve and [process](/content-management/image-processing/) images.
|
||||
* Add [header links](https://remysharp.com/2014/08/08/automatic-permalinks-for-blog-posts).
|
||||
|
||||
### Render Hook Templates
|
||||
|
||||
Both `render-link` and `render-image` templates will receive this context:
|
||||
The `render-link` and `render-image` templates will receive this context:
|
||||
|
||||
Page
|
||||
: The [Page](/variables/page/) being rendered.
|
||||
@@ -125,7 +132,24 @@ Text
|
||||
PlainText
|
||||
: The plain variant of the above.
|
||||
|
||||
#### Link with title Markdown example :
|
||||
The `render-heading` template will receive this context:
|
||||
|
||||
Page
|
||||
: The [Page](/variables/page/) being rendered.
|
||||
|
||||
Level
|
||||
: The header level (1--6)
|
||||
|
||||
Anchor
|
||||
: An auto-generated html id unique to the header within the page
|
||||
|
||||
Text
|
||||
: The rendered (HTML) text.
|
||||
|
||||
PlainText
|
||||
: The plain variant of the above.
|
||||
|
||||
#### Link with title Markdown example:
|
||||
|
||||
```md
|
||||
[Text](https://www.gohugo.io "Title")
|
||||
@@ -151,5 +175,24 @@ Here is a code example for how the render-image.html template could look:
|
||||
</p>
|
||||
{{< /code >}}
|
||||
|
||||
[^hooktemplate]: It's currently only possible to have one set of render hook templates, e.g. not per `Type` or `Section`. We may consider that in a future version.
|
||||
#### Heading link example
|
||||
|
||||
Given this template file
|
||||
|
||||
{{< code file="layouts/_default/_markup/render-heading.html" >}}
|
||||
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }} <a href="#{{ .Anchor | safeURL }}">¶</a></h{{ .Level }}>
|
||||
{{< /code >}}
|
||||
|
||||
And this markdown
|
||||
|
||||
```md
|
||||
### Section A
|
||||
```
|
||||
|
||||
The rendered html will be
|
||||
|
||||
```html
|
||||
<h3 id="section-a">Section A <a href="#section-a">¶</a></h3>
|
||||
```
|
||||
|
||||
[^hooktemplate]: It's currently only possible to have one set of render hook templates, e.g. not per `Type` or `Section`. We may consider that in a future version.
|
||||
|
||||
@@ -124,7 +124,7 @@ disableHugoGeneratorInject (false)
|
||||
: Hugo will, by default, inject a generator meta tag in the HTML head on the _home page only_. You can turn it off, but we would really appreciate if you don't, as this is a good way to watch Hugo's popularity on the rise.
|
||||
|
||||
disableKinds ([])
|
||||
: Enable disabling of all pages of the specified *Kinds*. Allowed values in this list: `"page"`, `"home"`, `"section"`, `"taxonomy"`, `"taxonomyTerm"`, `"RSS"`, `"sitemap"`, `"robotsTXT"`, `"404"`.
|
||||
: Enable disabling of all pages of the specified *Kinds*. Allowed values in this list: `"page"`, `"home"`, `"section"`, `"taxonomy"`, `"term"`, `"RSS"`, `"sitemap"`, `"robotsTXT"`, `"404"`.
|
||||
|
||||
disableLiveReload (false)
|
||||
: Disable automatic live reloading of browser window.
|
||||
@@ -349,6 +349,20 @@ Content-Security-Policy = "script-src localhost:1313"
|
||||
{{< /code-toggle >}}
|
||||
|
||||
|
||||
{{< new-in "0.72.0" >}}
|
||||
|
||||
You can also specify simple redirects rules for the server. The syntax is again similar to Netlify's.
|
||||
|
||||
Note that a `status` code of 200 will trigger a [URL rewrite](https://docs.netlify.com/routing/redirects/rewrites-proxies/), which is what you want in SPA situations, e.g:
|
||||
|
||||
{{< code-toggle file="config/development/server">}}
|
||||
[[redirects]]
|
||||
from = "/myspa/**"
|
||||
to = "/myspa/"
|
||||
status = 200
|
||||
{{< /code-toggle >}}
|
||||
|
||||
|
||||
|
||||
|
||||
## Configure Title Case
|
||||
@@ -500,7 +514,7 @@ Default configuration:
|
||||
|
||||
Since Hugo 0.52 you can configure more than just the `cacheDir`. This is the default configuration:
|
||||
|
||||
```toml
|
||||
{{< code-toggle >}}
|
||||
[caches]
|
||||
[caches.getjson]
|
||||
dir = ":cacheDir/:project"
|
||||
@@ -517,7 +531,7 @@ maxAge = -1
|
||||
[caches.modules]
|
||||
dir = ":cacheDir/modules"
|
||||
maxAge = -1
|
||||
```
|
||||
{{< /code-toggle >}}
|
||||
|
||||
You can override any of these cache settings in your own `config.toml`.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ description: A list of tutorials and books on Hugo.
|
||||
date: 2019-10-20
|
||||
publishdate: 2019-10-20
|
||||
lastmod: 2019-10-20
|
||||
keywords: [books,tutorials,learning,usage]
|
||||
keywords: [books, tutorials, learning, usage]
|
||||
menu:
|
||||
docs:
|
||||
parent: "getting-started"
|
||||
@@ -17,7 +17,9 @@ toc: false
|
||||
---
|
||||
|
||||
## Books
|
||||
|
||||
### Hugo In Action
|
||||
|
||||
[](https://www.manning.com/books/hugo-in-action)
|
||||
|
||||
Hugo in Action is a step-by-step guide to using Hugo to create static websites. Working with a complete example website and source code samples, you’ll learn how to build and host a low-maintenance, high-performance site that will wow your users and stay stable without relying on a third-party server.
|
||||
@@ -25,5 +27,7 @@ Hugo in Action is a step-by-step guide to using Hugo to create static websites.
|
||||
[Hugo In Action Home Page](https://www.manning.com/books/hugo-in-action)
|
||||
|
||||
## Video tutorials
|
||||
|
||||
### Video Playlist by Mike Dane
|
||||
Mike Dane expains the various features of via dedicated tutorials on [Youtube](https://www.youtube.com/watch?list=PLLAZ4kZ9dFpOnyRlyS-liKL5ReHDcj4G3&v=qtIqKaDlqXo).
|
||||
|
||||
Mike Dane explains the various features of Hugo via dedicated tutorials on [YouTube](https://www.youtube.com/watch?list=PLLAZ4kZ9dFpOnyRlyS-liKL5ReHDcj4G3&v=qtIqKaDlqXo).
|
||||
|
||||
@@ -44,6 +44,10 @@ Download the appropriate version for your platform from [Hugo Releases][releases
|
||||
|
||||
Ideally, you should install it somewhere in your `PATH` for easy use. `/usr/local/bin` is the most probable location.
|
||||
|
||||
### Docker
|
||||
|
||||
We currently do not offer official Hugo images for Docker, but we do recommend these up to date distributions: https://hub.docker.com/r/klakegg/hugo/
|
||||
|
||||
### Homebrew (macOS)
|
||||
|
||||
If you are on macOS and using [Homebrew][brew], you can install Hugo with the following one-liner:
|
||||
@@ -444,7 +448,7 @@ Directory of C:\hugo\sites\example.com
|
||||
|
||||
### Snap Package
|
||||
|
||||
In any of the [Linux distributions that support snaps][snaps], you may install install the "extended" Sass/SCSS version with this command:
|
||||
In any of the [Linux distributions that support snaps][snaps], you may install the "extended" Sass/SCSS version with this command:
|
||||
|
||||
snap install hugo --channel=extended
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ The above will create a new Hugo site in a folder named `quickstart`.
|
||||
|
||||
See [themes.gohugo.io](https://themes.gohugo.io/) for a list of themes to consider. This quickstart uses the beautiful [Ananke theme](https://themes.gohugo.io/gohugo-theme-ananke/).
|
||||
|
||||
First, download the theme from Github and add it to your site's `theme` directory:
|
||||
First, download the theme from GitHub and add it to your site's `themes` directory:
|
||||
|
||||
```bash
|
||||
cd quickstart
|
||||
@@ -83,7 +83,7 @@ echo 'theme = "ananke"' >> config.toml
|
||||
|
||||
## Step 4: Add Some Content
|
||||
|
||||
You can manually create content files (for example as `content/<CATEGORY>/<FILE>.<FORMAT>`) and provide metadata in them, however you can use the `new` command to do few things for you (like add title and date):
|
||||
You can manually create content files (for example as `content/<CATEGORY>/<FILE>.<FORMAT>`) and provide metadata in them, however you can use the `new` command to do a few things for you (like add title and date):
|
||||
|
||||
```
|
||||
hugo new posts/my-first-post.md
|
||||
|
||||
@@ -58,7 +58,7 @@ Next, execute this command to generate a new keypair called `rsa_id`:
|
||||
|
||||
You'll be prompted for a passphrase, which is an extra layer of protection. Enter the passphrase you'd like to use, and then enter it again when prompted, or leave it blank if you don't want to have a passphrase. Not using a passphrase will let you transfer files non-interactively, as you won't be prompted for a password when you log in, but it is slightly less secure.
|
||||
|
||||
To make logging in easier, add a definition for your web host to the file `~/.ssh/config` with the following command, replacing `HOST` with the IP address or hostname of your web host, and `USER` with the username you use to log in to your web host when transfering files:
|
||||
To make logging in easier, add a definition for your web host to the file `~/.ssh/config` with the following command, replacing `HOST` with the IP address or hostname of your web host, and `USER` with the username you use to log in to your web host when transferring files:
|
||||
|
||||
```
|
||||
~/.ssh/$ cat >> config <<EOF
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Host on AWS Amplify
|
||||
linktitle: Host on AWS Amplify
|
||||
description: Develop and deploy a cloud-powered web app with AWS Amplify.
|
||||
description: Develop and deploy a cloud-powered web app with AWS Amplify.
|
||||
date: 2018-01-31
|
||||
publishdate: 2018-01-31
|
||||
lastmod: 2018-01-31
|
||||
|
||||
@@ -57,8 +57,9 @@ This is a much simpler setup as your Hugo files and generated content are publis
|
||||
4. Paste your existing Hugo project into the new local `<YOUR-PROJECT>` repository. Make sure your website works locally (`hugo server` or `hugo server -t <YOURTHEME>`) and open your browser to <http://localhost:1313>.
|
||||
5. Once you are happy with the results:
|
||||
* Press <kbd>Ctrl</kbd>+<kbd>C</kbd> to kill the server
|
||||
* Before proceeding run `rm -rf public` to completely remove the `public` directory
|
||||
* Before proceeding run `rm -rf public` to completely remove the `public` directory
|
||||
6. `git submodule add -b master https://github.com/<USERNAME>/<USERNAME>.github.io.git public`. This creates a git [submodule][]. Now when you run the `hugo` command to build your site to `public`, the created `public` directory will have a different remote origin (i.e. hosted GitHub repository).
|
||||
7. Make sure the `baseURL` in your config file is updated with: `<USERNAME>.github.io`
|
||||
|
||||
### Put it Into a Script
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ draft: false
|
||||
|
||||
## Create a KeyCDN Pull Zone
|
||||
|
||||
The first step will be to login to your KeyCDN account and create a new zone. Name this whatever you like and select the [Pull Zone](https://www.keycdn.com/support/create-a-pull-zone/) option. As for the origin URL, your site will be running on [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/getting_started_part_one.html) with a URL of `https://youruser.gitlab.io/reponame/`. Use this as the Origin URL.
|
||||
The first step will be to login to your KeyCDN account and create a new zone. Name this whatever you like and select the [Pull Zone](https://www.keycdn.com/support/create-a-pull-zone/) option. As for the origin URL, your site will be running on [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/getting_started_part_one.html) with a URL of `https://youruser.gitlab.io/reponame/`. Use this as the Origin URL.
|
||||
|
||||

|
||||

|
||||
|
||||
While the origin location doesn’t exist yet, you will need to use your new Zone URL address (or [Zonealias](https://www.keycdn.com/support/create-a-zonealias/)) in the `.gitlab-ci.yml` file that will be uploaded to your GitLab project.
|
||||
While the origin location doesn’t exist yet, you will need to use your new Zone URL address (or [Zone Alias](https://www.keycdn.com/support/create-a-zone-alias/)) in the `.gitlab-ci.yml` file that will be uploaded to your GitLab project.
|
||||
|
||||
Ensure that you use your Zone URL or Zonealias as the `BASEURL` variable in the example below. This will be the user-visible website address.
|
||||
Ensure that you use your Zone URL or Zone alias as the `BASEURL` variable in the example below. This will be the user-visible website address.
|
||||
|
||||
## Configure Your .gitlab-ci.yml File
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Any of the above can be omitted.
|
||||
min
|
||||
: The minimum Hugo version supported, e.g. `0.55.0`
|
||||
|
||||
max
|
||||
max
|
||||
: The maximum Hugo version supported, e.g. `0.55.0`
|
||||
|
||||
extended
|
||||
@@ -73,7 +73,7 @@ extended
|
||||
ignoreConfig = false
|
||||
disable = false
|
||||
[[module.imports]]
|
||||
path = "my-shortcodes"
|
||||
path = "my-shortcodes"
|
||||
{{< /code-toggle >}}
|
||||
|
||||
path
|
||||
|
||||
@@ -30,9 +30,20 @@ Use `hugo mod init` to initialize a new Hugo Module. If it fails to guess the mo
|
||||
hugo mod init github.com/gohugoio/myShortcodes
|
||||
```
|
||||
|
||||
|
||||
Also see the [CLI Doc](/commands/hugo_mod_init/).
|
||||
|
||||
## Use a Module for a Theme
|
||||
The easiest way to use a Module for a theme is to import it in the config.
|
||||
|
||||
1. Initialize the hugo module system: `hugo mod init github.com/<your_user>/<your_project>`
|
||||
2. Import the theme in your `config.toml`:
|
||||
|
||||
```toml
|
||||
[module]
|
||||
[[module.imports]]
|
||||
path = "github.com/spf13/hyde/"
|
||||
```
|
||||
|
||||
## Update Modules
|
||||
|
||||
Modules will be downloaded and added when you add them as imports to your configuration, see [Module Imports](/hugo-modules/configuration/#module-config-imports).
|
||||
@@ -76,7 +87,7 @@ One way to do local development of a module imported in a project is to add a re
|
||||
replace github.com/bep/hugotestmods/mypartials => /Users/bep/hugotestmods/mypartials
|
||||
```
|
||||
|
||||
If you have the `hugo server` running, the configuration will be reloaded and `/Users/bep/hugotestmods/mypartials` put on the watch list.
|
||||
If you have the `hugo server` running, the configuration will be reloaded and `/Users/bep/hugotestmods/mypartials` put on the watch list.
|
||||
|
||||
|
||||
## Print Dependency Graph
|
||||
@@ -103,7 +114,7 @@ Also see the [CLI Doc](/commands/hugo_mod_graph/).
|
||||
|
||||
## Vendor Your Modules
|
||||
|
||||
`hugo mod vendor` will write all the module depencies to a `_vendor` folder, which will then be used for all subsequent builds.
|
||||
`hugo mod vendor` will write all the module dependencies to a `_vendor` folder, which will then be used for all subsequent builds.
|
||||
|
||||
Note that:
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ keywords: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "pipes"
|
||||
weight: 49
|
||||
weight: 49
|
||||
sections_weight: 49
|
||||
weight: 48
|
||||
weight: 48
|
||||
sections_weight: 48
|
||||
draft: false
|
||||
---
|
||||
|
||||
|
||||
@@ -15,12 +15,10 @@ sections_weight: 60
|
||||
draft: false
|
||||
---
|
||||
|
||||
|
||||
Asset files of the same MIME type can be bundled into one resource using `resources.Concat` which takes two arguments, a target path and a slice of resource objects.
|
||||
|
||||
|
||||
```go-html-template
|
||||
{{ $plugins := resources.Get "js/plugins.js" }}
|
||||
{{ $global := resources.Get "js/global.js" }}
|
||||
{{ $js := slice $plugins $global | resources.Concat "js/bundle.js" }}
|
||||
```
|
||||
```
|
||||
|
||||
@@ -16,7 +16,7 @@ draft: false
|
||||
---
|
||||
|
||||
|
||||
Fingerprinting and [SRI](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) can be applied to any asset file using `resources.Fingerprint` which takes two arguments, the resource object and a [hash function](https://en.wikipedia.org/wiki/Cryptographic_hash_function).
|
||||
Fingerprinting and [SRI](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) can be applied to any asset file using `resources.Fingerprint` which takes two arguments, the resource object and a [hash function](https://en.wikipedia.org/wiki/Cryptographic_hash_function).
|
||||
|
||||
The default hash function is `sha256`. Other available functions are `sha384` (from Hugo `0.55`), `sha512` and `md5`.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ weight: 01
|
||||
sections_weight: 01
|
||||
draft: false
|
||||
aliases: [/assets/]
|
||||
---
|
||||
---
|
||||
|
||||
### Asset directory
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: JavaScript Building
|
||||
description: Hugo Pipes can process JavaScript files with [ESBuild](https://github.com/evanw/esbuild).
|
||||
date: 2020-07-20
|
||||
publishdate: 2020-07-20
|
||||
lastmod: 2020-07-20
|
||||
categories: [asset management]
|
||||
keywords: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "pipes"
|
||||
weight: 45
|
||||
weight: 45
|
||||
sections_weight: 45
|
||||
draft: false
|
||||
---
|
||||
|
||||
Any JavaScript resource file can be transpiled and "tree shaken" using `js.Build` which takes for argument either a string for the filepath or a dict of options listed below.
|
||||
|
||||
### Options
|
||||
|
||||
targetPath [string]
|
||||
: If not set, the source path will be used as the base target path.
|
||||
Note that the target path's extension may change if the target MIME type is different, e.g. when the source is TypeScript.
|
||||
|
||||
minify [bool]
|
||||
: Let `js.Build` handle the minification.
|
||||
|
||||
target [string]
|
||||
: The language target.
|
||||
One of: `es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020` or `esnext`.
|
||||
Default is `esnext`.
|
||||
|
||||
externals [slice]
|
||||
: External dependencies. If a dependency should not be included in the bundle (Ex. library loaded from a CDN.), it should be listed here.
|
||||
|
||||
```go-html-template
|
||||
{{ $externals := slice "react" "react-dom" }}
|
||||
```
|
||||
|
||||
defines [map]
|
||||
: Allow to define a set of string replacement to be performed when building. Should be a map where each key is to be replaced by its value.
|
||||
|
||||
```go-html-template
|
||||
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
|
||||
```
|
||||
|
||||
format [string] {{< new-in "0.75.0" >}}
|
||||
: The output format.
|
||||
One of: `iife`, `cjs`, `esm`.
|
||||
Default is `iife`, a self-executing function, suitable for inclusion as a <script> tag.
|
||||
|
||||
### Examples
|
||||
|
||||
```go-html-template
|
||||
{{ $built := resources.Get "js/index.js" | js.Build "main.js" }}
|
||||
```
|
||||
|
||||
Or with options:
|
||||
|
||||
```go-html-template
|
||||
{{ $externals := slice "react" "react-dom" }}
|
||||
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
|
||||
|
||||
{{ $opts := dict "targetPath" "main.js" "externals" $externals "defines" $defines }}
|
||||
{{ $built := resources.Get "scripts/main.js" | js.Build $opts }}
|
||||
<script type="text/javascript" src="{{ $built.RelPermalink }}" defer></script>
|
||||
```
|
||||
@@ -16,7 +16,7 @@ draft: false
|
||||
---
|
||||
|
||||
|
||||
Any resource of the aforementioned types can be minifed using `resources.Minify` which takes for argument the resource object.
|
||||
Any resource of the aforementioned types can be minified using `resources.Minify` which takes for argument the resource object.
|
||||
|
||||
|
||||
```go-html-template
|
||||
|
||||
@@ -20,7 +20,7 @@ There are currently two limitations to this:
|
||||
|
||||
1. This only works in `*.html` templates (i.e. templates that produces HTML files).
|
||||
2. You cannot manipulate the values returned from the resource's methods. E.g. the `upper` in this example will not work as expected:
|
||||
|
||||
|
||||
```go-html-template
|
||||
{{ $css := resources.Get "css/main.css" }}
|
||||
{{ $css = $css | resources.PostCSS | minify | fingerprint | resources.PostProcess }}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 205 KiB |
@@ -1,14 +1,15 @@
|
||||
|
||||
---
|
||||
date: 2020-05-18
|
||||
title: "0.71.0"
|
||||
description: "0.71.0"
|
||||
title: "Markdown Render Hooks for Headings"
|
||||
description: "Render hooks for headings, update to Go 1.14.3, several bug fixes etc."
|
||||
categories: ["Releases"]
|
||||
---
|
||||
|
||||
Hugo 0.71 brings Markdown render hooks for headings, but the main reason why this release comes sooner rather than later is to get out a release built on Go 1.14.3 which comes with a fix for [this bug](https://github.com/golang/go/issues/37833) that caused Hugo to sometimes spin up with 100% CPU on MacOS.
|
||||
Hugo 0.71 brings [Markdown render hooks for headings](https://gohugo.io/getting-started/configuration-markup#markdown-render-hooks), a set of bug fixes and more.
|
||||
|
||||
This release represents **12 contributions by 7 contributors** to the main Hugo code base. [@bep](https://github.com/bep) leads the Hugo development with a significant amount of contributions, but also a big shoutout to [@anthonyfok](https://github.com/anthonyfok), [@apexskier](https://github.com/apexskier), and [@johnweldon](https://github.com/johnweldon) for their ongoing contributions.
|
||||
|
||||
This release represents **12 contributions by 7 contributors** to the main Hugo code base.[@bep](https://github.com/bep) leads the Hugo development with a significant amount of contributions, but also a big shoutout to [@anthonyfok](https://github.com/anthonyfok), [@apexskier](https://github.com/apexskier), and [@johnweldon](https://github.com/johnweldon) for their ongoing contributions.
|
||||
And a big thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) and [@onedrawingperday](https://github.com/onedrawingperday) for their relentless work on keeping the themes site in pristine condition and to [@davidsneighbour](https://github.com/davidsneighbour) and [@kaushalmodi](https://github.com/kaushalmodi) for all the great work on the documentation site.
|
||||
|
||||
Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
---
|
||||
date: 2020-05-25
|
||||
title: "Hugo 0.71.1: A couple of Bug Fixes"
|
||||
description: "This version fixes a couple of bugs."
|
||||
categories: ["Releases"]
|
||||
images:
|
||||
- images/blog/hugo-bug-poster.png
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
This is a bug-fix release with a couple of important fixes.
|
||||
|
||||
* Add some more date test cases [81f56332](https://github.com/gohugoio/hugo/commit/81f5633245bf123fbe7ad78eec51ae7b4e6c177a) [@bep](https://github.com/bep) [#7310](https://github.com/gohugoio/hugo/issues/7310)
|
||||
* Fix RenderString vs render hooks [9698b0da](https://github.com/gohugoio/hugo/commit/9698b0dab11f52d52145e85ff71311d2f103cb4e) [@bep](https://github.com/bep) [#7265](https://github.com/gohugoio/hugo/issues/7265)
|
||||
* Prevent WARNINGs in RenderString [32344fe3](https://github.com/gohugoio/hugo/commit/32344fe3db862584e3f926d63bdf33b7fa7d22f7) [@bep](https://github.com/bep)
|
||||
* Fix IsAncestor/IsDescendant for taxonomies [4d7fa9f1](https://github.com/gohugoio/hugo/commit/4d7fa9f114c62ae2ec12257203ed21b0e4d69a04) [@bep](https://github.com/bep) [#7305](https://github.com/gohugoio/hugo/issues/7305)
|
||||
* Fix GetPage on section/bundle name overlaps [a985efce](https://github.com/gohugoio/hugo/commit/a985efcecf44afe1d252690ec0a00cf077974f44) [@bep](https://github.com/bep) [#7301](https://github.com/gohugoio/hugo/issues/7301)
|
||||
* Fix Go template script escaping [6c3c6686](https://github.com/gohugoio/hugo/commit/6c3c6686f5d3c7155e2d455b07ac8ab70f42cb88) [@bep](https://github.com/bep) [#6695](https://github.com/gohugoio/hugo/issues/6695)
|
||||
* Add a test helper [c34bf485](https://github.com/gohugoio/hugo/commit/c34bf48560c91c8a2fa106867af7b08a569609b5) [@bep](https://github.com/bep)
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 251 KiB |
@@ -0,0 +1,41 @@
|
||||
|
||||
---
|
||||
date: 2020-05-31
|
||||
title: URL rewrites in dev server
|
||||
description: "Hugo 0.72.0 comes with dev server redirects and URL rewrites, Goldmark typography extension fixes, Scratch.Values."
|
||||
categories: ["Releases"]
|
||||
---
|
||||
|
||||
This is a rather small release, its probably main motivation being the fixes in Goldmark's [Typographer extension](https://github.com/gohugoio/hugo/commit/432885c499849efb29d3e50196f377fe0e908333).
|
||||
|
||||
This release also adds [redirect and URL rewrite support](https://gohugo.io/getting-started/configuration/#configure-server) to the development server, with mostly Netlify-compatible configuration syntax. This is especially useful if you're building a [SPA](https://en.wikipedia.org/wiki/Single-page_application) with client-side routing.
|
||||
|
||||
|
||||
This release represents **13 contributions by 3 contributors** to the main Hugo code base.
|
||||
|
||||
Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
|
||||
which has received **9 contributions by 6 contributors**. A special thanks to [@faraixyz](https://github.com/faraixyz), [@bep](https://github.com/bep), [@coliff](https://github.com/coliff), and [@Leon0824](https://github.com/Leon0824) for their work on the documentation site.
|
||||
|
||||
|
||||
Hugo now has:
|
||||
|
||||
* 44383+ [stars](https://github.com/gohugoio/hugo/stargazers)
|
||||
* 437+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
|
||||
* 327+ [themes](http://themes.gohugo.io/)
|
||||
|
||||
## Enhancements
|
||||
|
||||
### Other
|
||||
|
||||
* Add Scratch.Values [2919a6a5](https://github.com/gohugoio/hugo/commit/2919a6a503f7b369154d6eb787023a1fe58a9ad4) [@bep](https://github.com/bep) [#7335](https://github.com/gohugoio/hugo/issues/7335)
|
||||
* Update Goldmark to improve Typographer [432885c4](https://github.com/gohugoio/hugo/commit/432885c499849efb29d3e50196f377fe0e908333) [@bep](https://github.com/bep) [#7289](https://github.com/gohugoio/hugo/issues/7289)
|
||||
* Add redirect support to the server [6a3e8974](https://github.com/gohugoio/hugo/commit/6a3e89743ccad58097a6dd203a63448946a2304d) [@bep](https://github.com/bep) [#7323](https://github.com/gohugoio/hugo/issues/7323)
|
||||
|
||||
## Fixes
|
||||
|
||||
### Other
|
||||
|
||||
* Fix tag collector for nested table elements [c950c86b](https://github.com/gohugoio/hugo/commit/c950c86b4e5fb93f787ec78ca823bded9ef9fa3a) [@bep](https://github.com/bep) [#7318](https://github.com/gohugoio/hugo/issues/7318)
|
||||
* Fix build error: my previous commits did not fix it [91520249](https://github.com/gohugoio/hugo/commit/915202494b140882d594e0542153531f6afada02) [@anthonyfok](https://github.com/anthonyfok)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user