Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7bc28c529 | |||
| 20e9c08e1f | |||
| 37140a093b | |||
| da80163c75 | |||
| 60e66d12ea | |||
| 558825cc20 | |||
| ed8bf081fd | |||
| 10c33c17cd | |||
| 2c54f1ad48 | |||
| eb15ac37ef | |||
| eb42774e58 | |||
| f27977809c | |||
| 7a634898c3 | |||
| 1823c053c8 | |||
| 511d5d3b76 | |||
| 8299fa885c | |||
| 06495f713b | |||
| 93e24a03ce | |||
| e9c7b6205f | |||
| 3d1a6e109c | |||
| b6798ee867 | |||
| 0a23baa6a9 | |||
| 84f4b731d2 | |||
| 61f6e9f63b | |||
| 904a3d9ddf | |||
| f0052b6d0f | |||
| da88015776 | |||
| debd3663dd | |||
| af67ad8af1 | |||
| e46ab29bd2 | |||
| 10fef32de6 | |||
| 70005364a2 | |||
| ffaec4ca8c | |||
| 3886fc1fef | |||
| 91fb8f1b59 | |||
| ac12d51e7e | |||
| 3fbc75534d | |||
| e427ba4268 | |||
| 79dd7cb31a | |||
| 0dbf79c2f8 | |||
| f12ad7d56a | |||
| ce6e4310fe | |||
| 95d62004a0 | |||
| c029065582 | |||
| 68bf1511f2 | |||
| f8dc47eeff | |||
| ae3fa349de | |||
| 64cec07293 | |||
| 9ac6206584 | |||
| f414966b94 | |||
| c29a2ed2f5 | |||
| dfb6484a41 | |||
| 8a02968393 | |||
| e7fda289b1 | |||
| 50a03a5acc | |||
| ba94abbf5d | |||
| 55fb0eac20 | |||
| 06e5ee6526 |
@@ -1,7 +1,7 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
daysUntilStale: 120
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
daysUntilClose: 30
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Keep
|
||||
@@ -20,4 +20,4 @@ markComment: >
|
||||
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
closeComment: false
|
||||
|
||||
@@ -12,6 +12,7 @@ cover.out
|
||||
*~
|
||||
vendor/*/
|
||||
*.bench
|
||||
*.debug
|
||||
coverage*.out
|
||||
|
||||
GoBuilds
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
language: go
|
||||
sudo: required
|
||||
dist: precise
|
||||
sudo: false
|
||||
dist: trusty
|
||||
go:
|
||||
- 1.9.4
|
||||
- "1.10"
|
||||
@@ -14,12 +14,12 @@ matrix:
|
||||
fast_finish: true
|
||||
install:
|
||||
- go get github.com/magefile/mage
|
||||
- mage vendor
|
||||
- mage -v vendor
|
||||
script:
|
||||
- mage hugoRace
|
||||
- mage -v hugoRace
|
||||
- mage -v check
|
||||
- ./hugo -s docs/
|
||||
- ./hugo --renderToMemory -s docs/
|
||||
before_install:
|
||||
# gem install must be run with sudo on OSX
|
||||
- sudo gem install asciidoctor | gem install asciidoctor
|
||||
- gem install asciidoctor
|
||||
- type asciidoctor
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/alecthomas/chroma"
|
||||
packages = [
|
||||
".",
|
||||
@@ -29,6 +30,7 @@
|
||||
"lexers/a",
|
||||
"lexers/b",
|
||||
"lexers/c",
|
||||
"lexers/circular",
|
||||
"lexers/d",
|
||||
"lexers/e",
|
||||
"lexers/f",
|
||||
@@ -53,8 +55,7 @@
|
||||
"lexers/y",
|
||||
"styles"
|
||||
]
|
||||
revision = "563aadc53c53292c4c1def1b0a547be498bba83e"
|
||||
version = "v0.3.0"
|
||||
revision = "85c342e3e3d715ad780edd0ba8728161e99cce24"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -162,6 +163,7 @@
|
||||
".",
|
||||
"hcl/ast",
|
||||
"hcl/parser",
|
||||
"hcl/printer",
|
||||
"hcl/scanner",
|
||||
"hcl/strconv",
|
||||
"hcl/token",
|
||||
@@ -273,6 +275,12 @@
|
||||
packages = ["."]
|
||||
revision = "55d61fa8aa702f59229e6cff85793c22e580eaf5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/sanity-io/litter"
|
||||
packages = ["."]
|
||||
revision = "ae543b7ba8fd6af63e4976198f146e1348ae53c1"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/shurcooL/sanitized_anchor_name"
|
||||
@@ -285,8 +293,8 @@
|
||||
".",
|
||||
"mem"
|
||||
]
|
||||
revision = "bb8f1927f2a9d3ab41c9340aa034f6b803f4359c"
|
||||
version = "v1.0.2"
|
||||
revision = "63644898a8da0bc22138abf860edaf5277b6102e"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/cast"
|
||||
@@ -330,8 +338,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/spf13/viper"
|
||||
packages = ["."]
|
||||
revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7"
|
||||
version = "v1.0.0"
|
||||
revision = "b5e8006cbee93ec955a89ab31e0e3ce3204f3736"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/stretchr/testify"
|
||||
@@ -416,6 +424,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "960c7cc0b7d1739f5c1f116cc7fa31056b76cf16e63d865f31be875b8e674da7"
|
||||
inputs-digest = "edb250b53926de21df1740c379c76351b7e9b110c96a77078a10ba69bf31a2d4"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/alecthomas/chroma"
|
||||
version = "0.3.0"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/afero"
|
||||
version = "^1.0.1"
|
||||
version = "^1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/cast"
|
||||
@@ -141,3 +141,7 @@
|
||||
name = "github.com/muesli/smartcrop"
|
||||
branch = "master"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/sanity-io/litter"
|
||||
version = "1.1.0"
|
||||
|
||||
@@ -14,6 +14,18 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/gohugoio/hugo/utils"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
|
||||
"github.com/gohugoio/hugo/common/types"
|
||||
"github.com/gohugoio/hugo/deps"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
@@ -23,11 +35,22 @@ import (
|
||||
|
||||
type commandeer struct {
|
||||
*deps.DepsCfg
|
||||
|
||||
subCmdVs []*cobra.Command
|
||||
|
||||
pathSpec *helpers.PathSpec
|
||||
visitedURLs *types.EvictingStringQueue
|
||||
|
||||
staticDirsConfig []*src.Dirs
|
||||
|
||||
// We watch these for changes.
|
||||
configFiles []string
|
||||
|
||||
doWithCommandeer func(c *commandeer) error
|
||||
|
||||
// We can do this only once.
|
||||
fsCreate sync.Once
|
||||
|
||||
serverPorts []int
|
||||
languages helpers.Languages
|
||||
|
||||
@@ -65,16 +88,158 @@ func (c *commandeer) initFs(fs *hugofs.Fs) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCommandeer(cfg *deps.DepsCfg, running bool) (*commandeer, error) {
|
||||
cfg.Running = running
|
||||
func newCommandeer(running bool, doWithCommandeer func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
|
||||
|
||||
var languages helpers.Languages
|
||||
c := &commandeer{
|
||||
doWithCommandeer: doWithCommandeer,
|
||||
subCmdVs: append([]*cobra.Command{hugoCmdV}, subCmdVs...),
|
||||
visitedURLs: types.NewEvictingStringQueue(10)}
|
||||
|
||||
if l, ok := cfg.Cfg.Get("languagesSorted").(helpers.Languages); ok {
|
||||
languages = l
|
||||
return c, c.loadConfig(running)
|
||||
}
|
||||
|
||||
func (c *commandeer) loadConfig(running bool) error {
|
||||
|
||||
if c.DepsCfg == nil {
|
||||
c.DepsCfg = &deps.DepsCfg{}
|
||||
}
|
||||
|
||||
c := &commandeer{DepsCfg: cfg, languages: languages, visitedURLs: types.NewEvictingStringQueue(10)}
|
||||
cfg := c.DepsCfg
|
||||
c.configured = false
|
||||
cfg.Running = running
|
||||
|
||||
var dir string
|
||||
if source != "" {
|
||||
dir, _ = filepath.Abs(source)
|
||||
} else {
|
||||
dir, _ = os.Getwd()
|
||||
}
|
||||
|
||||
var sourceFs afero.Fs = hugofs.Os
|
||||
if c.DepsCfg.Fs != nil {
|
||||
sourceFs = c.DepsCfg.Fs.Source
|
||||
}
|
||||
|
||||
config, configFiles, err := hugolib.LoadConfig(hugolib.ConfigSourceDescriptor{Fs: sourceFs, Path: source, WorkingDir: dir, Filename: cfgFile})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Cfg = config
|
||||
c.configFiles = configFiles
|
||||
|
||||
for _, cmdV := range c.subCmdVs {
|
||||
c.initializeFlags(cmdV)
|
||||
}
|
||||
|
||||
if l, ok := c.Cfg.Get("languagesSorted").(helpers.Languages); ok {
|
||||
c.languages = l
|
||||
}
|
||||
|
||||
if baseURL != "" {
|
||||
config.Set("baseURL", baseURL)
|
||||
}
|
||||
|
||||
if c.doWithCommandeer != nil {
|
||||
err = c.doWithCommandeer(c)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(disableKinds) > 0 {
|
||||
c.Set("disableKinds", disableKinds)
|
||||
}
|
||||
|
||||
logger, err := createLogger(cfg.Cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.Logger = logger
|
||||
|
||||
config.Set("logI18nWarnings", logI18nWarnings)
|
||||
|
||||
if theme != "" {
|
||||
config.Set("theme", theme)
|
||||
}
|
||||
|
||||
if themesDir != "" {
|
||||
config.Set("themesDir", themesDir)
|
||||
}
|
||||
|
||||
if destination != "" {
|
||||
config.Set("publishDir", destination)
|
||||
}
|
||||
|
||||
config.Set("workingDir", dir)
|
||||
|
||||
if contentDir != "" {
|
||||
config.Set("contentDir", contentDir)
|
||||
}
|
||||
|
||||
if layoutDir != "" {
|
||||
config.Set("layoutDir", layoutDir)
|
||||
}
|
||||
|
||||
if cacheDir != "" {
|
||||
config.Set("cacheDir", cacheDir)
|
||||
}
|
||||
|
||||
createMemFs := config.GetBool("renderToMemory")
|
||||
|
||||
if createMemFs {
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
config.Set("publishDir", "/")
|
||||
}
|
||||
|
||||
c.fsCreate.Do(func() {
|
||||
fs := hugofs.NewFrom(sourceFs, config)
|
||||
|
||||
// Hugo writes the output to memory instead of the disk.
|
||||
if createMemFs {
|
||||
fs.Destination = new(afero.MemMapFs)
|
||||
}
|
||||
|
||||
err = c.initFs(fs)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cacheDir = config.GetString("cacheDir")
|
||||
if cacheDir != "" {
|
||||
if helpers.FilePathSeparator != cacheDir[len(cacheDir)-1:] {
|
||||
cacheDir = cacheDir + helpers.FilePathSeparator
|
||||
}
|
||||
isDir, err := helpers.DirExists(cacheDir, sourceFs)
|
||||
utils.CheckErr(cfg.Logger, err)
|
||||
if !isDir {
|
||||
mkdir(cacheDir)
|
||||
}
|
||||
config.Set("cacheDir", cacheDir)
|
||||
} else {
|
||||
config.Set("cacheDir", helpers.GetTempDir("hugo_cache", sourceFs))
|
||||
}
|
||||
|
||||
cfg.Logger.INFO.Println("Using config file:", config.ConfigFileUsed())
|
||||
|
||||
themeDir := c.PathSpec().GetThemeDir()
|
||||
if themeDir != "" {
|
||||
if _, err := sourceFs.Stat(themeDir); os.IsNotExist(err) {
|
||||
return newSystemError("Unable to find theme Directory:", themeDir)
|
||||
}
|
||||
}
|
||||
|
||||
themeVersionMismatch, minVersion := c.isThemeVsHugoVersionMismatch(sourceFs)
|
||||
|
||||
if themeVersionMismatch {
|
||||
cfg.Logger.ERROR.Printf("Current theme does not support Hugo version %s. Minimum version required is %s\n",
|
||||
helpers.CurrentHugoVersion.ReleaseVersion(), minVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
@@ -25,8 +25,6 @@ import (
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -44,7 +42,6 @@ import (
|
||||
"regexp"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/gohugoio/hugo/deps"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
"github.com/gohugoio/hugo/livereload"
|
||||
@@ -55,7 +52,6 @@ import (
|
||||
"github.com/spf13/fsync"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/nitro"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Hugo represents the Hugo sites to build. This variable is exported as it
|
||||
@@ -142,10 +138,6 @@ Complete documentation is available at http://gohugo.io/.`,
|
||||
return err
|
||||
}
|
||||
|
||||
if buildWatch {
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
return c.build()
|
||||
},
|
||||
}
|
||||
@@ -301,129 +293,11 @@ func init() {
|
||||
// InitializeConfig initializes a config file with sensible default configuration flags.
|
||||
func InitializeConfig(running bool, doWithCommandeer func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
|
||||
|
||||
var cfg *deps.DepsCfg = &deps.DepsCfg{}
|
||||
|
||||
// Init file systems. This may be changed at a later point.
|
||||
osFs := hugofs.Os
|
||||
|
||||
config, err := hugolib.LoadConfig(osFs, source, cfgFile)
|
||||
c, err := newCommandeer(running, doWithCommandeer, subCmdVs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Init file systems. This may be changed at a later point.
|
||||
cfg.Cfg = config
|
||||
|
||||
c, err := newCommandeer(cfg, running)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, cmdV := range append([]*cobra.Command{hugoCmdV}, subCmdVs...) {
|
||||
c.initializeFlags(cmdV)
|
||||
}
|
||||
|
||||
if baseURL != "" {
|
||||
config.Set("baseURL", baseURL)
|
||||
}
|
||||
|
||||
if doWithCommandeer != nil {
|
||||
if err := doWithCommandeer(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(disableKinds) > 0 {
|
||||
c.Set("disableKinds", disableKinds)
|
||||
}
|
||||
|
||||
logger, err := createLogger(cfg.Cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.Logger = logger
|
||||
|
||||
config.Set("logI18nWarnings", logI18nWarnings)
|
||||
|
||||
if theme != "" {
|
||||
config.Set("theme", theme)
|
||||
}
|
||||
|
||||
if themesDir != "" {
|
||||
config.Set("themesDir", themesDir)
|
||||
}
|
||||
|
||||
if destination != "" {
|
||||
config.Set("publishDir", destination)
|
||||
}
|
||||
|
||||
var dir string
|
||||
if source != "" {
|
||||
dir, _ = filepath.Abs(source)
|
||||
} else {
|
||||
dir, _ = os.Getwd()
|
||||
}
|
||||
config.Set("workingDir", dir)
|
||||
|
||||
if contentDir != "" {
|
||||
config.Set("contentDir", contentDir)
|
||||
}
|
||||
|
||||
if layoutDir != "" {
|
||||
config.Set("layoutDir", layoutDir)
|
||||
}
|
||||
|
||||
if cacheDir != "" {
|
||||
config.Set("cacheDir", cacheDir)
|
||||
}
|
||||
|
||||
fs := hugofs.NewFrom(osFs, config)
|
||||
|
||||
// Hugo writes the output to memory instead of the disk.
|
||||
// This is only used for benchmark testing. Cause the content is only visible
|
||||
// in memory.
|
||||
if config.GetBool("renderToMemory") {
|
||||
fs.Destination = new(afero.MemMapFs)
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
config.Set("publishDir", "/")
|
||||
}
|
||||
|
||||
cacheDir = config.GetString("cacheDir")
|
||||
if cacheDir != "" {
|
||||
if helpers.FilePathSeparator != cacheDir[len(cacheDir)-1:] {
|
||||
cacheDir = cacheDir + helpers.FilePathSeparator
|
||||
}
|
||||
isDir, err := helpers.DirExists(cacheDir, fs.Source)
|
||||
utils.CheckErr(cfg.Logger, err)
|
||||
if !isDir {
|
||||
mkdir(cacheDir)
|
||||
}
|
||||
config.Set("cacheDir", cacheDir)
|
||||
} else {
|
||||
config.Set("cacheDir", helpers.GetTempDir("hugo_cache", fs.Source))
|
||||
}
|
||||
|
||||
if err := c.initFs(fs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.Logger.INFO.Println("Using config file:", config.ConfigFileUsed())
|
||||
|
||||
themeDir := c.PathSpec().GetThemeDir()
|
||||
if themeDir != "" {
|
||||
if _, err := cfg.Fs.Source.Stat(themeDir); os.IsNotExist(err) {
|
||||
return nil, newSystemError("Unable to find theme Directory:", themeDir)
|
||||
}
|
||||
}
|
||||
|
||||
themeVersionMismatch, minVersion := c.isThemeVsHugoVersionMismatch()
|
||||
|
||||
if themeVersionMismatch {
|
||||
cfg.Logger.ERROR.Printf("Current theme does not support Hugo version %s. Minimum version required is %s\n",
|
||||
helpers.CurrentHugoVersion.ReleaseVersion(), minVersion)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
|
||||
}
|
||||
@@ -516,28 +390,14 @@ func (c *commandeer) setValueFromFlag(flags *flag.FlagSet, key string) {
|
||||
if _, deprecated := deprecatedFlags[strings.ToLower(key)]; deprecated {
|
||||
msg := fmt.Sprintf(`Set "%s = true" in your config.toml.
|
||||
If you need to set this configuration value from the command line, set it via an OS environment variable: "HUGO_%s=true hugo"`, key, strings.ToUpper(key))
|
||||
// Remove in Hugo 0.37
|
||||
helpers.Deprecated("hugo", "--"+key+" flag", msg, false)
|
||||
// Remove in Hugo 0.38
|
||||
helpers.Deprecated("hugo", "--"+key+" flag", msg, true)
|
||||
}
|
||||
f := flags.Lookup(key)
|
||||
c.Set(key, f.Value.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *commandeer) watchConfig() {
|
||||
v := c.Cfg.(*viper.Viper)
|
||||
v.WatchConfig()
|
||||
v.OnConfigChange(func(e fsnotify.Event) {
|
||||
c.Logger.FEEDBACK.Println("Config file changed:", e.Name)
|
||||
// Force a full rebuild
|
||||
utils.CheckErr(c.Logger, c.recreateAndBuildSites(true))
|
||||
if !c.Cfg.GetBool("disableLiveReload") {
|
||||
// Will block forever trying to write to a channel that nobody is reading if livereload isn't initialized
|
||||
livereload.ForceRefresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (c *commandeer) fullBuild() error {
|
||||
var (
|
||||
g errgroup.Group
|
||||
@@ -776,6 +636,9 @@ func (c *commandeer) copyStaticTo(dirs *src.Dirs, publishDir string) (uint64, er
|
||||
}
|
||||
|
||||
func (c *commandeer) timeTrack(start time.Time, name string) {
|
||||
if quiet {
|
||||
return
|
||||
}
|
||||
elapsed := time.Since(start)
|
||||
c.Logger.FEEDBACK.Printf("%s in %v ms", name, int(1000*elapsed.Seconds()))
|
||||
}
|
||||
@@ -842,7 +705,7 @@ func (c *commandeer) getDirList() ([]string, error) {
|
||||
c.Logger.ERROR.Printf("Cannot read symbolic link '%s', error was: %s", path, err)
|
||||
return nil
|
||||
}
|
||||
linkfi, err := helpers.LstatIfOs(c.Fs.Source, link)
|
||||
linkfi, err := helpers.LstatIfPossible(c.Fs.Source, link)
|
||||
if err != nil {
|
||||
c.Logger.ERROR.Printf("Cannot stat %q: %s", link, err)
|
||||
return nil
|
||||
@@ -880,9 +743,13 @@ func (c *commandeer) getDirList() ([]string, error) {
|
||||
|
||||
// SymbolicWalk will log anny ERRORs
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, dataDir, regularWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, c.PathSpec().AbsPathify(c.Cfg.GetString("contentDir")), symLinkWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, i18nDir, regularWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, layoutDir, regularWalker)
|
||||
|
||||
for _, contentDir := range c.PathSpec().ContentDirs() {
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, contentDir.Value, symLinkWalker)
|
||||
}
|
||||
|
||||
for _, staticDir := range staticDirs {
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, staticDir, regularWalker)
|
||||
}
|
||||
@@ -939,6 +806,8 @@ func (c *commandeer) resetAndBuildSites() (err error) {
|
||||
|
||||
func (c *commandeer) initSites() error {
|
||||
if Hugo != nil {
|
||||
Hugo.Cfg = c.Cfg
|
||||
Hugo.Log.ResetLogCounters()
|
||||
return nil
|
||||
}
|
||||
h, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
@@ -1005,6 +874,15 @@ func (c *commandeer) newWatcher(dirList ...string) (*watcher.Batcher, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Identifies changes to config (config.toml) files.
|
||||
configSet := make(map[string]bool)
|
||||
|
||||
for _, configFile := range c.configFiles {
|
||||
c.Logger.FEEDBACK.Println("Watching for config changes in", configFile)
|
||||
watcher.Add(configFile)
|
||||
configSet[configFile] = true
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
@@ -1017,6 +895,21 @@ func (c *commandeer) newWatcher(dirList ...string) (*watcher.Batcher, error) {
|
||||
// Special handling for symbolic links inside /content.
|
||||
filtered := []fsnotify.Event{}
|
||||
for _, ev := range evs {
|
||||
if configSet[ev.Name] {
|
||||
if ev.Op&fsnotify.Chmod == fsnotify.Chmod {
|
||||
continue
|
||||
}
|
||||
// Config file changed. Need full rebuild.
|
||||
if err := c.loadConfig(true); err != nil {
|
||||
jww.ERROR.Println("Failed to reload config:", err)
|
||||
} else if err := c.recreateAndBuildSites(true); err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
} else if !buildWatch && !c.Cfg.GetBool("disableLiveReload") {
|
||||
livereload.ForceRefresh()
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// Check the most specific first, i.e. files.
|
||||
contentMapped := Hugo.ContentChanges.GetSymbolicLinkMappings(ev.Name)
|
||||
if len(contentMapped) > 0 {
|
||||
@@ -1208,7 +1101,7 @@ func pickOneWriteOrCreatePath(events []fsnotify.Event) string {
|
||||
|
||||
// isThemeVsHugoVersionMismatch returns whether the current Hugo version is
|
||||
// less than the theme's min_version.
|
||||
func (c *commandeer) isThemeVsHugoVersionMismatch() (mismatch bool, requiredMinVersion string) {
|
||||
func (c *commandeer) isThemeVsHugoVersionMismatch(fs afero.Fs) (mismatch bool, requiredMinVersion string) {
|
||||
if !c.PathSpec().ThemeSet() {
|
||||
return
|
||||
}
|
||||
@@ -1217,13 +1110,13 @@ func (c *commandeer) isThemeVsHugoVersionMismatch() (mismatch bool, requiredMinV
|
||||
|
||||
path := filepath.Join(themeDir, "theme.toml")
|
||||
|
||||
exists, err := helpers.Exists(path, c.Fs.Source)
|
||||
exists, err := helpers.Exists(path, fs)
|
||||
|
||||
if err != nil || !exists {
|
||||
return
|
||||
}
|
||||
|
||||
b, err := afero.ReadFile(c.Fs.Source, path)
|
||||
b, err := afero.ReadFile(fs, path)
|
||||
|
||||
tomlMeta, err := parser.HandleTOMLMetaData(b)
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ description = ""
|
||||
homepage = "http://example.com/"
|
||||
tags = []
|
||||
features = []
|
||||
min_version = "0.37"
|
||||
min_version = "0.38"
|
||||
|
||||
[author]
|
||||
name = ""
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -111,12 +112,16 @@ func init() {
|
||||
|
||||
}
|
||||
|
||||
var serverPorts []int
|
||||
|
||||
func server(cmd *cobra.Command, args []string) error {
|
||||
// If a Destination is provided via flag write to disk
|
||||
if destination != "" {
|
||||
renderToDisk = true
|
||||
}
|
||||
|
||||
var serverCfgInit sync.Once
|
||||
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("renderToMemory", !renderToDisk)
|
||||
if cmd.Flags().Changed("navigateToChanged") {
|
||||
@@ -132,37 +137,42 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
c.Set("watch", true)
|
||||
}
|
||||
|
||||
serverPorts := make([]int, 1)
|
||||
var err error
|
||||
|
||||
if c.languages.IsMultihost() {
|
||||
if !serverAppend {
|
||||
return newSystemError("--appendPort=false not supported when in multihost mode")
|
||||
}
|
||||
serverPorts = make([]int, len(c.languages))
|
||||
}
|
||||
// We can only do this once.
|
||||
serverCfgInit.Do(func() {
|
||||
serverPorts = make([]int, 1)
|
||||
|
||||
currentServerPort := serverPort
|
||||
|
||||
for i := 0; i < len(serverPorts); i++ {
|
||||
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(currentServerPort)))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
serverPorts[i] = currentServerPort
|
||||
} else {
|
||||
if i == 0 && serverCmd.Flags().Changed("port") {
|
||||
// port set explicitly by user -- he/she probably meant it!
|
||||
return newSystemErrorF("Server startup failed: %s", err)
|
||||
if c.languages.IsMultihost() {
|
||||
if !serverAppend {
|
||||
err = newSystemError("--appendPort=false not supported when in multihost mode")
|
||||
}
|
||||
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
|
||||
sp, err := helpers.FindAvailablePort()
|
||||
if err != nil {
|
||||
return newSystemError("Unable to find alternative port to use:", err)
|
||||
}
|
||||
serverPorts[i] = sp.Port
|
||||
serverPorts = make([]int, len(c.languages))
|
||||
}
|
||||
|
||||
currentServerPort = serverPorts[i] + 1
|
||||
}
|
||||
currentServerPort := serverPort
|
||||
|
||||
for i := 0; i < len(serverPorts); i++ {
|
||||
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(currentServerPort)))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
serverPorts[i] = currentServerPort
|
||||
} else {
|
||||
if i == 0 && serverCmd.Flags().Changed("port") {
|
||||
// port set explicitly by user -- he/she probably meant it!
|
||||
err = newSystemErrorF("Server startup failed: %s", err)
|
||||
}
|
||||
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
|
||||
sp, err := helpers.FindAvailablePort()
|
||||
if err != nil {
|
||||
err = newSystemError("Unable to find alternative port to use:", err)
|
||||
}
|
||||
serverPorts[i] = sp.Port
|
||||
}
|
||||
|
||||
currentServerPort = serverPorts[i] + 1
|
||||
}
|
||||
})
|
||||
|
||||
c.serverPorts = serverPorts
|
||||
|
||||
@@ -184,7 +194,7 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
|
||||
baseURL, err := fixURL(language, baseURL, serverPort)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
if isMultiHost {
|
||||
language.Set("baseURL", baseURL)
|
||||
@@ -194,7 +204,7 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
@@ -215,10 +225,6 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
s.RegisterMediaTypes()
|
||||
}
|
||||
|
||||
if serverWatch {
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
// Watch runs its own server as part of the routine
|
||||
if serverWatch {
|
||||
|
||||
|
||||
@@ -20,6 +20,12 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
// KeyValueStr is a string tuple.
|
||||
type KeyValueStr struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
// KeyValues holds an key and a slice of values.
|
||||
type KeyValues struct {
|
||||
Key interface{}
|
||||
|
||||
@@ -63,7 +63,22 @@ func NewContent(
|
||||
return err
|
||||
}
|
||||
|
||||
contentPath := s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), targetPath))
|
||||
// The site may have multiple content dirs, and we currently do not know which contentDir the
|
||||
// user wants to create this content in. We should improve on this, but we start by testing if the
|
||||
// provided path points to an existing dir. If so, use it as is.
|
||||
var contentPath string
|
||||
var exists bool
|
||||
targetDir := filepath.Dir(targetPath)
|
||||
|
||||
if targetDir != "" && targetDir != "." {
|
||||
exists, _ = helpers.Exists(targetDir, ps.Fs.Source)
|
||||
}
|
||||
|
||||
if exists {
|
||||
contentPath = targetPath
|
||||
} else {
|
||||
contentPath = s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), targetPath))
|
||||
}
|
||||
|
||||
if err := helpers.SafeWriteToDisk(contentPath, bytes.NewReader(content), s.Fs.Source); err != nil {
|
||||
return err
|
||||
|
||||
@@ -88,10 +88,15 @@ func executeArcheTypeAsTemplate(s *hugolib.Site, kind, targetPath, archetypeFile
|
||||
err error
|
||||
)
|
||||
|
||||
sp := source.NewSourceSpec(s.Deps.Cfg, s.Deps.Fs)
|
||||
ps, err := helpers.NewPathSpec(s.Deps.Fs, s.Deps.Cfg)
|
||||
sp := source.NewSourceSpec(ps, ps.Fs.Source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f := sp.NewFileInfo("", targetPath, false, nil)
|
||||
|
||||
name := f.TranslationBaseName()
|
||||
|
||||
if name == "index" || name == "_index" {
|
||||
// Page bundles; the directory name will hopefully have a better name.
|
||||
dir := strings.TrimSuffix(f.Dir(), helpers.FilePathSeparator)
|
||||
@@ -137,15 +142,6 @@ func executeArcheTypeAsTemplate(s *hugolib.Site, kind, targetPath, archetypeFile
|
||||
|
||||
archetypeContent = []byte(archetypeShortcodeReplacementsPost.Replace(buff.String()))
|
||||
|
||||
if !bytes.Contains(archetypeContent, []byte("date")) || !bytes.Contains(archetypeContent, []byte("title")) {
|
||||
// TODO(bep) remove some time in the future.
|
||||
s.Log.FEEDBACK.Println(fmt.Sprintf(`WARNING: date and/or title missing from archetype file %q.
|
||||
From Hugo 0.24 this must be provided in the archetype file itself, if needed. Example:
|
||||
%s
|
||||
`, archetypeFilename, ArchetypeTemplateTemplate))
|
||||
|
||||
}
|
||||
|
||||
return archetypeContent, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func TestNewContent(t *testing.T) {
|
||||
for i, v := range c.expected {
|
||||
found := strings.Contains(content, v)
|
||||
if !found {
|
||||
t.Errorf("[%d] %q missing from output:\n%q", i, v, content)
|
||||
t.Fatalf("[%d] %q missing from output:\n%q", i, v, content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ func New(cfg DepsCfg) (*Deps, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sp := source.NewSourceSpec(cfg.Language, fs)
|
||||
sp := source.NewSourceSpec(ps, fs.Source)
|
||||
|
||||
d := &Deps{
|
||||
Fs: fs,
|
||||
|
||||
@@ -10,6 +10,12 @@ Note that this repository contains solely the documentation for Hugo. For contri
|
||||
|
||||
*Pull requests shall **only** contain changes to the actual documentation. However, changes on the code base of Hugo **and** the documentation shall be a single, atomic pull request in the [hugo](https://github.com/gohugoio/hugo) repository.*
|
||||
|
||||
Spelling fixes are most welcomed, and if you want to contribute longer sections to the documentation, it would be great if you had these in mind when writing:
|
||||
|
||||
* Short is good. People go to the library to read novels. If there is more than one way to _do a thing_ in Hugo, describe the current _best practice_ (avoid "… but you can also do …" and "… in older versions of Hugo you had to …".
|
||||
* For examples, try to find short snippets that teaches people about the concept. If the example is also useful as-is (copy and paste), then great, but don't list long and similar examples just so people can use them on their sites.
|
||||
* Hugo has users from all over the world, so an easy to understand and [simple English](https://simple.wikipedia.org/wiki/Basic_English) is good.
|
||||
|
||||
## Branches
|
||||
|
||||
* The `master` branch is where the site is automatically built from, and is the place to put changes relevant to the current Hugo version.
|
||||
|
||||
@@ -16,7 +16,6 @@ pluralizeListTitles = false
|
||||
# We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below).
|
||||
disableAliases = true
|
||||
|
||||
|
||||
# Highlighting config (Pygments)
|
||||
# It is (currently) not in use, but you can do ```go in a content file if you want to.
|
||||
pygmentsCodeFences = true
|
||||
@@ -27,7 +26,7 @@ pygmentsUseClasses = true
|
||||
pygmentsUseClassic = false
|
||||
|
||||
# See https://help.farbox.com/pygments.html
|
||||
pygmentsStyle = "friendly"
|
||||
pygmentsStyle = "trac"
|
||||
|
||||
[outputs]
|
||||
home = [ "HTML", "RSS", "REDIR", "HEADERS" ]
|
||||
@@ -71,7 +70,7 @@ twitter = "GoHugoIO"
|
||||
[params]
|
||||
description = "The world’s fastest framework for building websites"
|
||||
## Used for views in rendered HTML (i.e., rather than using the .Hugo variable)
|
||||
release = "0.37"
|
||||
release = "0.38"
|
||||
## Setting this to true will add a "noindex" to *EVERY* page on the site
|
||||
removefromexternalsearch = false
|
||||
## Gh repo for site footer (include trailing slash)
|
||||
|
||||
@@ -29,14 +29,14 @@ This has many benefits. The most noticeable is performance. HTTP servers are *ve
|
||||
|
||||
* ["An Introduction to Static Site Generators", David Walsh][]
|
||||
* ["Hugo vs. Wordpress page load speed comparison: Hugo leaves WordPress in its dust", GettingThingsTech][hugovwordpress]
|
||||
* ["Static Site Generators", O-Reilly][]
|
||||
* ["Static Site Generators", O'Reilly][]
|
||||
* [StaticGen: Top Open-Source Static Site Generators (GitHub Stars)][]
|
||||
* ["Top 10 Static Website Generators", Netlify blog][]
|
||||
* ["The Resurgence of Static", dotCMS][dotcms]
|
||||
|
||||
|
||||
["An Introduction to Static Site Generators", David Walsh]: https://davidwalsh.name/introduction-static-site-generators
|
||||
["Static Site Generators", O-Reilly]: /documents/oreilly-static-site-generators.pdf
|
||||
["Static Site Generators", O'Reilly]: http://www.oreilly.com/web-platform/free/files/static-site-generators.pdf
|
||||
["Top 10 Static Website Generators", Netlify blog]: https://www.netlify.com/blog/2016/05/02/top-ten-static-website-generators/
|
||||
[hugovwordpress]: https://gettingthingstech.com/hugo-vs.-wordpress-page-load-speed-comparison-hugo-leaves-wordpress-in-its-dust/
|
||||
[StaticGen: Top Open-Source Static Site Generators (GitHub Stars)]: https://www.staticgen.com/
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
---
|
||||
title: Archetypes
|
||||
linktitle: Archetypes
|
||||
description: Archetypes allow you to create new instances of content types and set default parameters from the command line.
|
||||
description: Archetypes are templates used when creating new content.
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
keywords: [archetypes,generators,metadata,front matter]
|
||||
categories: ["content management"]
|
||||
menu:
|
||||
@@ -18,175 +17,59 @@ aliases: [/content/archetypes/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
{{% note %}}
|
||||
This section is outdated, see https://github.com/gohugoio/hugoDocs/issues/11
|
||||
{{% /note %}}
|
||||
{{% todo %}}
|
||||
See above
|
||||
{{% /todo %}}
|
||||
|
||||
## What are Archetypes?
|
||||
|
||||
**Archetypes** are content files in the [archetypes directory][] of your project that contain preconfigured [front matter][] for your website's [content types][]. Archetypes facilitate consistent metadata across your website content and allow content authors to quickly generate instances of a content type via the `hugo new` command.
|
||||
**Archetypes** are content template files in the [archetypes directory][] of your project that contain preconfigured [front matter][] and possibly also a content disposition for your website's [content types][]. These will be used when you run `hugo new`.
|
||||
|
||||
{{< youtube bcme8AzVh6o >}}
|
||||
|
||||
The `hugo new` generator for archetypes assumes your working directory is the content folder at the root of your project. Hugo is able to infer the appropriate archetype by assuming the content type from the content section passed to the CLI command:
|
||||
|
||||
```
|
||||
hugo new <content-section>/<file-name.md>
|
||||
```
|
||||
|
||||
We can use this pattern to create a new `.md` file in the `posts` section:
|
||||
The `hugo new` uses the `content-section` to find the most suitable archetype template in your project. If your project does not contain any archetype files, it will also look in the theme.
|
||||
|
||||
{{< code file="archetype-example.sh" >}}
|
||||
hugo new posts/my-first-post.md
|
||||
{{< /code >}}
|
||||
|
||||
{{% note "Override Content Type in a New File" %}}
|
||||
To override the content type Hugo infers from `[content-section]`, add the `--kind` flag to the end of the `hugo new` command.
|
||||
{{% /note %}}
|
||||
|
||||
Running this command in a new site that does not have default or custom archetypes will create the following file:
|
||||
|
||||
{{< output file="content/posts/my-first-post.md" >}}
|
||||
+++
|
||||
date = "2017-02-01T19:20:04-07:00"
|
||||
title = "my first post"
|
||||
draft = true
|
||||
+++
|
||||
{{< /output >}}
|
||||
|
||||
{{% note %}}
|
||||
In this example, if you do not already have a `content/posts` directory, Hugo will create both `content/posts/` and `content/posts/my-first-post.md` for you.
|
||||
{{% /note %}}
|
||||
|
||||
The auto-populated fields are worth examining:
|
||||
|
||||
* `title` is generated from the new content's filename (i.e. in this case, `my-first-post` becomes `"my first post"`)
|
||||
* `date` and `title` are the variables that ship with Hugo and are therefore included in *all* content files created with the Hugo CLI. `date` is generated in [RFC 3339 format][] by way of Go's [`now()`][] function, which returns the current time.
|
||||
* The third variable, `draft = true`, is *not* inherited by your default or custom archetypes but is included in Hugo's automatically scaffolded `default.md` archetype for convenience.
|
||||
|
||||
Three variables per content file are often not enough for effective content management of larger websites. Luckily, Hugo provides a simple mechanism for extending the number of variables through custom archetypes, as well as default archetypes to keep content creation DRY.
|
||||
|
||||
## Lookup Order for Archetypes
|
||||
|
||||
Similar to the [lookup order for templates][lookup] in your `layouts` directory, Hugo looks for a section- or type-specific archetype, then a default archetype, and finally an internal archetype that ships with Hugo. For example, Hugo will look for an archetype for `content/posts/my-first-post.md` in the following order:
|
||||
The above will create a new content file in `content/posts/my-first-post.md` using the first archetype file found of these:
|
||||
|
||||
1. `archetypes/posts.md`
|
||||
2. `archetypes/default.md`
|
||||
3. `themes/<THEME>/archetypes/posts.md`
|
||||
4. `themes/<THEME>/archetypes/default.md` (Auto-generated with `hugo new site`)
|
||||
3. `themes/my-theme/posts.md`
|
||||
4. `themes/my-theme/default.md`
|
||||
|
||||
{{% note "Using a Theme Archetype" %}}
|
||||
If you wish to use archetypes that ship with a theme, the `theme` field must be specified in your [configuration file](/getting-started/configuration/).
|
||||
{{% /note %}}
|
||||
The last two list items is only applicable if you use a theme and it uses the `my-theme` theme name as an example.
|
||||
|
||||
## Choose Your Archetype's Front Matter Format
|
||||
## Create a New Archetype Template
|
||||
|
||||
By default, `hugo new` content files include front matter in the TOML format regardless of the format used in `archetypes/*.md`.
|
||||
A fictional example for the section `newsletter` and the archetype file `archetypes/newsletter.md`. Create a new file in `archetypes/newsletter.md` and open it in a text editor.
|
||||
|
||||
You can specify a different default format in your site [configuration file][] file using the `metaDataFormat` directive. Possible values are `toml`, `yaml`, and `json`.
|
||||
{{< code file="archetypes/newsletter.md" >}}
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
---
|
||||
|
||||
## Default Archetypes
|
||||
**Insert Lead paragraph here.**
|
||||
|
||||
Default archetypes are convenient if your content's front matter stays consistent across multiple [content sections][sections].
|
||||
## New Cool Posts
|
||||
|
||||
### Create the Default Archetype
|
||||
|
||||
When you create a new Hugo project using `hugo new site`, you'll notice that Hugo has already scaffolded a file at `archetypes/default.md`.
|
||||
|
||||
The following examples are from a site that's using `tags` and `categories` as [taxonomies][]. If we assume that all content files will require these two key-values, we can create a `default.md` archetype that *extends* Hugo's base archetype. In this example, we are including "golang" and "hugo" as tags and "web development" as a category.
|
||||
|
||||
{{< code file="archetypes/default.md" >}}
|
||||
+++
|
||||
tags = ["golang", "hugo"]
|
||||
categories = ["web development"]
|
||||
+++
|
||||
{{ range first 10 ( where .Site.RegularPages "Type" "cool" ) }}
|
||||
* {{ .Title }}
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
{{% warning "EOL Characters in Text Editors"%}}
|
||||
If you get an `EOF error` when using `hugo new`, add a carriage return after the closing `+++` or `---` for your TOML or YAML front matter, respectively. (See the [troubleshooting article on EOF errors](/troubleshooting/eof-error/) for more information.)
|
||||
{{% /warning %}}
|
||||
When you create a new newsletter with:
|
||||
|
||||
### Use the Default Archetype
|
||||
```bash
|
||||
hugo new newsletter/the-latest-cool.stuff.md
|
||||
```
|
||||
|
||||
With an `archetypes/default.md` in place, we can use the CLI to create a new post in the `posts` content section:
|
||||
It will create a new newsletter type of content file based on the archetype template.
|
||||
|
||||
{{< code file="new-post-from-default.sh" >}}
|
||||
$ hugo new posts/my-new-post.md
|
||||
{{< /code >}}
|
||||
**Note:** the site will only be built if the `.Site` is in use in the archetype file, and this can be time consuming for big sites.
|
||||
|
||||
Hugo then creates a new markdown file with the following front matter:
|
||||
The above _newsletter type archetype_ illustrates the possibilities: The full Hugo `.Site` and all of Hugo's template funcs can be used in the archetype file.
|
||||
|
||||
{{< output file="content/posts/my-new-post.md" >}}
|
||||
+++
|
||||
categories = ["web development"]
|
||||
date = "2017-02-01T19:20:04-07:00"
|
||||
tags = ["golang", "hugo"]
|
||||
title = "my new post"
|
||||
+++
|
||||
{{< /output >}}
|
||||
|
||||
We see that the `title` and `date` key-values have been added in addition to the `tags` and `categories` key-values from `archetypes/default.md`.
|
||||
|
||||
{{% note "Ordering of Front Matter" %}}
|
||||
You may notice that content files created with `hugo new` do not respect the order of the key-values specified in your archetype files. This is a [known issue](https://github.com/gohugoio/hugo/issues/452).
|
||||
{{% /note %}}
|
||||
|
||||
## Custom Archetypes
|
||||
|
||||
Suppose your site's `posts` section requires more sophisticated front matter than what has been specified in `archetypes/default.md`. You can create a custom archetype for your posts at `archetypes/posts.md` that includes the full set of front matter to be added to the two default archetypes fields.
|
||||
|
||||
### Create a Custom Archetype
|
||||
|
||||
{{< code file="archetypes/posts.md">}}
|
||||
+++
|
||||
description = ""
|
||||
tags = ""
|
||||
categories = ""
|
||||
+++
|
||||
{{< /code >}}
|
||||
|
||||
### Use a Custom Archetype
|
||||
|
||||
With an `archetypes/posts.md` in place, you can use the Hugo CLI to create a new post with your preconfigured front matter in the `posts` content section:
|
||||
|
||||
{{< code file="new-post-from-custom.sh" >}}
|
||||
$ hugo new posts/post-from-custom.md
|
||||
{{< /code >}}
|
||||
|
||||
This time, Hugo recognizes our custom `archetypes/posts.md` archetype and uses it instead of `archetypes/default.md`. The generated file will now include the full list of front matter parameters, as well as the base archetype's `title` and `date`:
|
||||
|
||||
{{< output file="content/posts/post-from-custom-archetype.md" >}}
|
||||
+++
|
||||
categories = ""
|
||||
date = 2017-02-13T17:24:43-08:00
|
||||
description = ""
|
||||
tags = ""
|
||||
title = "post from custom archetype"
|
||||
+++
|
||||
{{< /output >}}
|
||||
|
||||
### Hugo Docs Custom Archetype
|
||||
|
||||
As an example of archetypes in practice, the following is the `functions` archetype from the Hugo docs:
|
||||
|
||||
{{< code file="archetypes/functions.md" >}}
|
||||
{{< readfile file="/archetypes/functions.md" >}}
|
||||
{{< /code >}}
|
||||
|
||||
{{% note %}}
|
||||
The preceding archetype is kept up to date with every Hugo build by using Hugo's [`readFile` function](/functions/readfile/). For similar examples, see [Local File Templates](/templates/files/).
|
||||
{{% /note %}}
|
||||
|
||||
[archetypes directory]: /getting-started/directory-structure/
|
||||
[`now()`]: http://golang.org/pkg/time/#Now
|
||||
[configuration file]: /getting-started/configuration/
|
||||
[sections]: /content-management/sections/
|
||||
[content types]: /content-management/types/
|
||||
[front matter]: /content-management/front-matter/
|
||||
[RFC 3339 format]: https://www.ietf.org/rfc/rfc3339.txt
|
||||
[taxonomies]: /content-management/taxonomies/
|
||||
[lookup]: /templates/lookup/
|
||||
[templates]: /templates/
|
||||
|
||||
@@ -109,8 +109,22 @@ Ensuring heading uniqueness across the site is accomplished with a unique identi
|
||||
/content-management/cross-references/#hugo-heading-anchors:77cd9ea530577debf4ce0f28c8dca242
|
||||
```
|
||||
|
||||
### Manually Specifying Anchors
|
||||
|
||||
For Markdown content files, if the `headerIds` [Blackfriday extension][bfext] is
|
||||
enabled (which it is by default), user can manually specify the anchor for any
|
||||
heading.
|
||||
|
||||
Few examples:
|
||||
|
||||
```
|
||||
## Alpha 101 {#alpha}
|
||||
|
||||
## Version 1.0 {#version-1-dot-0}
|
||||
```
|
||||
|
||||
[built-in Hugo shortcodes]: /content-management/shortcodes/#using-the-built-in-shortcodes
|
||||
[lists]: /templates/lists/
|
||||
[output formats]: /templates/output-formats/
|
||||
[shortcode]: /content-management/shortcodes/
|
||||
[bfext]: /content-management/formats/#blackfriday-extensions
|
||||
|
||||
@@ -84,7 +84,7 @@ See [Shortcodes][sc] for usage, particularly for the built-in shortcodes that sh
|
||||
|
||||
### Code Blocks
|
||||
|
||||
Hugo supports GitHub-flavored markdown's use of triple back ticks, as well as provides a special [`highlight` nested shortcode][hlsc] to render syntax highlighting via [Pygments][]. For usage examples and a complete explanation, see the [syntax highlighting documentation][hl] in [developer tools][].
|
||||
Hugo supports GitHub-flavored markdown's use of triple back ticks, as well as provides a special [`highlight` shortcode][hlsc], and syntax highlights those code blocks natively using *Chroma*. Users also have an option to use *Pygments* instead. See the [Syntax Highlighting][hl] section for details.
|
||||
|
||||
## Mmark
|
||||
|
||||
@@ -231,7 +231,7 @@ Markdown syntax is simple enough to learn in a single sitting. The following are
|
||||
[fireball]: https://daringfireball.net/projects/markdown/
|
||||
[gfmtasks]: https://guides.github.com/features/mastering-markdown/#syntax
|
||||
[helperssource]: https://github.com/gohugoio/hugo/blob/77c60a3440806067109347d04eb5368b65ea0fe8/helpers/general.go#L65
|
||||
[hl]: /tools/syntax-highlighting/
|
||||
[hl]: /content-management/syntax-highlighting/
|
||||
[hlsc]: /content-management/shortcodes/#highlight
|
||||
[hugocss]: /css/style.css
|
||||
[ietf]: https://tools.ietf.org/html/
|
||||
|
||||
@@ -137,23 +137,21 @@ Here’s an example snippet pulled from a `config.toml`:
|
||||
Here's the equivalent snippet in a `config.yaml`:
|
||||
|
||||
{{< code file="config.yml" >}}
|
||||
---
|
||||
menu:
|
||||
docs:
|
||||
- Name: "about hugo"
|
||||
Pre: "<i class='fa fa-heart'></i>"
|
||||
Weight: -110
|
||||
Identifier: "about"
|
||||
URL: "/about/"
|
||||
- Name: "getting started"
|
||||
Pre: "<i class='fa fa-road'></i>"
|
||||
Weight: -100
|
||||
URL: "/getting-started/"
|
||||
---
|
||||
main:
|
||||
- name: "about hugo"
|
||||
pre: "<i class='fa fa-heart'></i>"
|
||||
weight: -110
|
||||
identifier: "about"
|
||||
url: "/about/"
|
||||
- name: "getting started"
|
||||
pre: "<i class='fa fa-road'></i>"
|
||||
weight: -100
|
||||
url: "/getting-started/"
|
||||
{{< /code >}}
|
||||
|
||||
{{% note %}}
|
||||
The URLs must be relative to the context root. If the `baseURL` is `https://example.com/mysite/`, then the URLs in the menu must not include the context root `mysite`. Using an absolute URL will overide the baseURL. If the value used for `URL` in the above example is `https://subdomain.example.com/`, the output will be `https://subdomain.example.com`.
|
||||
The URLs must be relative to the context root. If the `baseURL` is `https://example.com/mysite/`, then the URLs in the menu must not include the context root `mysite`. Using an absolute URL will override the baseURL. If the value used for `URL` in the above example is `https://subdomain.example.com/`, the output will be `https://subdomain.example.com`.
|
||||
{{% /note %}}
|
||||
|
||||
## Nesting
|
||||
|
||||
@@ -34,16 +34,16 @@ help = "Help"
|
||||
[languages.en]
|
||||
title = "My blog"
|
||||
weight = 1
|
||||
[languages.en.params]
|
||||
linkedin = "english-link"
|
||||
|
||||
[languages.fr]
|
||||
copyright = "Tout est à moi"
|
||||
title = "Mon blog"
|
||||
weight = 2
|
||||
[languages.fr.params]
|
||||
linkedin = "lien-francais"
|
||||
|
||||
# skip params key for front matter
|
||||
[languages.fr.navigation]
|
||||
[languages.fr.params.navigation]
|
||||
help = "Aide"
|
||||
{{< /code >}}
|
||||
|
||||
@@ -59,6 +59,28 @@ If you want all of the languages to be put below their respective language code,
|
||||
|
||||
Only the obvious non-global options can be overridden per language. Examples of global options are `baseURL`, `buildDrafts`, etc.
|
||||
|
||||
## Disable a Language
|
||||
|
||||
You can disable one or more languages. This can be useful when working on a new translation.
|
||||
|
||||
```toml
|
||||
disableLanguages = ["fr", "jp"]
|
||||
```
|
||||
|
||||
Note that you cannot disable the default content language.
|
||||
|
||||
We kept this as a standalone setting to make it easier to set via [OS environment](/getting-started/configuration/#configure-with-environment-variables):
|
||||
|
||||
```bash
|
||||
HUGO_DISABLELANGUAGES="fr jp" hugo
|
||||
```
|
||||
If you have already a list of disabled languages in `config.toml`, you can enable them in development like this:
|
||||
|
||||
```bash
|
||||
HUGO_DISABLELANGUAGES=" " hugo server
|
||||
```
|
||||
|
||||
|
||||
## Configure Multilingual Multihost
|
||||
|
||||
From **Hugo 0.31** we support multiple languages in a multihost configuration. See [this issue](https://github.com/gohugoio/hugo/issues/4027) for details.
|
||||
@@ -156,11 +178,6 @@ You can also set the key used to link the translations explicitly in front matte
|
||||
translationKey: "my-story"
|
||||
```
|
||||
|
||||
|
||||
{{% note %}}
|
||||
**Before Hugo 0.31**, the file's directory was not considered when looking for translations. This did not work when you named all of your content files, say, `index.md`. Now we use the full content path.
|
||||
{{% /note %}}
|
||||
|
||||
If you need distinct URLs per language, you can set the slug in the non-default language file. For example, you can define a custom slug for a French translation in the front matter of `content/about.fr.md` as follows:
|
||||
|
||||
```yaml
|
||||
@@ -170,6 +187,7 @@ slug: "a-propos"
|
||||
|
||||
At render, Hugo will build both `/about/` and `/a-propos/` as properly linked translated pages.
|
||||
|
||||
For merging of content from other languages (i.e. missing content translations), see [lang.Merge](/functions/lang.merge/).
|
||||
|
||||
## Link to Translated Content
|
||||
|
||||
@@ -332,7 +350,7 @@ The rendering of the main navigation works as usual. `.Site.Menus` will just con
|
||||
|
||||
```
|
||||
|
||||
## Missing translations
|
||||
## Missing Translations
|
||||
|
||||
If a string does not have a translation for the current language, Hugo will use the value from the default language. If no default value is set, an empty string will be shown.
|
||||
|
||||
@@ -342,6 +360,8 @@ While translating a Hugo website, it can be handy to have a visual indicator of
|
||||
Hugo will generate your website with these missing translation placeholders. It might not be suited for production environments.
|
||||
{{% /note %}}
|
||||
|
||||
For merging of content from other languages (i.e. missing content translations), see [lang.Merge](/functions/lang.merge/).
|
||||
|
||||
## Multilingual Themes support
|
||||
|
||||
To support Multilingual mode in your themes, some considerations must be taken for the URLs in the templates. If there is more than one language, URLs must meet the following criteria:
|
||||
|
||||
@@ -6,7 +6,6 @@ lastmod : 2018-01-28T22:26:40-05:00
|
||||
linktitle : "Page Bundles"
|
||||
keywords : ["page", "bundle", "leaf", "branch"]
|
||||
categories : ["content management"]
|
||||
draft : true
|
||||
toc : true
|
||||
menu :
|
||||
docs:
|
||||
@@ -15,19 +14,16 @@ menu :
|
||||
weight : 11
|
||||
---
|
||||
|
||||
Page Bundles are a way to organize the content files. It's useful for
|
||||
cases where a page or section's content needs to be split into
|
||||
multiple content pages for convenience or has associated attachments
|
||||
like documents or images.
|
||||
Page Bundles are a way to group [Page Resources](/content-management/page-resources/).
|
||||
|
||||
A Page Bundle can be one of two types:
|
||||
A Page Bundle can be one of:
|
||||
|
||||
- Leaf Bundle
|
||||
- Branch Bundle
|
||||
- Leaf Bundle (leaf means it has no children)
|
||||
- Branch Bundle (home page, section, taxonomy terms, taxonomy list)
|
||||
|
||||
| | Leaf Bundle | Branch Bundle |
|
||||
|-----------------|--------------------------------------------------------|---------------------------------------------------------|
|
||||
| Usage | Collection of content and attachments for single pages | Collection of content and attachments for section pages |
|
||||
| Usage | Collection of resources (pages, images etc.) for single pages | Collection of non-page resources (images etc.)for list pages |
|
||||
| Index file name | `index.md` [^fn:1] | `_index.md` [^fn:1] |
|
||||
| Layout type | `single` | `list` |
|
||||
| Nesting | Doesn't allow nesting of more bundles under it | Allows nesting of leaf/branch bundles under it |
|
||||
@@ -37,15 +33,7 @@ A Page Bundle can be one of two types:
|
||||
## Leaf Bundles {#leaf-bundles}
|
||||
|
||||
A _Leaf Bundle_ is a directory at any hierarchy within the `content/`
|
||||
directory, that contains at least an **`index.md`** file.
|
||||
|
||||
{{% note %}}
|
||||
Here `md` (markdown) is used just as an example. You can use any file
|
||||
type as a content resource as long as it is a MIME type recognized by
|
||||
Hugo (`json` files will, as one example, work fine). If you want to
|
||||
get exotic, you can define your own media type.
|
||||
{{% /note %}}
|
||||
|
||||
directory, that contains an **`index.md`** file.
|
||||
|
||||
### Examples of Leaf Bundle organization {#examples-of-leaf-bundle-organization}
|
||||
|
||||
@@ -115,6 +103,20 @@ But you can get it by `.Site.GetPage`. Here is an example:
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
_In this example, we are assuming the `some-headless-bundle` to be a headless
|
||||
bundle containing one or more **page** resources whose `.Name` matches
|
||||
`"author*"`._
|
||||
|
||||
Explanation of the above example:
|
||||
|
||||
1. Get the `some-headless-bundle` Page "object".
|
||||
2. Collect a *slice* of resources in this *Page Bundle* that matches
|
||||
`"author*"` using `.Resources.Match`.
|
||||
3. Loop through that *slice* of nested pages, and output their `.Title` and
|
||||
`.Content`.
|
||||
|
||||
---
|
||||
|
||||
A leaf bundle can be made headless by adding below in the Front Matter
|
||||
(in the `index.md`):
|
||||
|
||||
@@ -141,9 +143,7 @@ This `_index.md` can also be directly under the `content/` directory.
|
||||
|
||||
{{% note %}}
|
||||
Here `md` (markdown) is used just as an example. You can use any file
|
||||
type as a content resource as long as it is a MIME type recognized by
|
||||
Hugo (`json` files will, as one example, work fine). If you want to
|
||||
get exotic, you can define your own media type.
|
||||
type as a content resource as long as it is a content type recognized by Hugo.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
|
||||
@@ -17,36 +17,50 @@ aliases: [/content/sections/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
A **Section** is a collection of pages that gets defined based on the
|
||||
organization structure under the `content/` directory.
|
||||
|
||||
By default, all the **first-level** directories under `content/` form their own
|
||||
sections (**root sections**).
|
||||
|
||||
If a user needs to define a section `foo` at a deeper level, they need to create
|
||||
a directory named `foo` with an `_index.md` file (see [Branch Bundles][branch bundles]
|
||||
for more information).
|
||||
|
||||
|
||||
{{% note %}}
|
||||
A **section** cannot be defined or overridden by a front matter parameter -- it
|
||||
is strictly derived from the content organization structure.
|
||||
{{% /note %}}
|
||||
|
||||
## Nested Sections
|
||||
|
||||
The sections can be nested as deeply as you need.
|
||||
|
||||
```bash
|
||||
blog
|
||||
├── funny-cats
|
||||
│ └── kittens
|
||||
│ └── _index.md
|
||||
└── tech
|
||||
└── _index.md
|
||||
content
|
||||
└── blog <-- Section, because first-level dir under content/
|
||||
├── funny-cats
|
||||
│ ├── mypost.md
|
||||
│ └── kittens <-- Section, because contains _index.md
|
||||
│ └── _index.md
|
||||
└── tech <-- Section, because contains _index.md
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
|
||||
**The important part to understand is, that to make the section tree fully navigational, at least the lower-most section needs a content file. (e.g. `_index.md`).**
|
||||
|
||||
**The important part to understand is, that to make the section tree fully navigational, at least the lower-most section needs a content file. (e.g. `_index.md`).**
|
||||
|
||||
{{% note %}}
|
||||
When we talk about a **section** in correlation with template selection, it is currently always the root section only (`/blog/funny/mypost/ => blog`).
|
||||
When we talk about a **section** in correlation with template selection, it is
|
||||
currently always the *root section* only (`/blog/funny-cats/mypost/ => blog`).
|
||||
|
||||
If you need a specific template for a sub-section, you need to adjust either the `type` or `layout` in front matter.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
## Example: Breadcrumb Navigation
|
||||
|
||||
With the available [section variables and methods](#section-page-variables-and-methods) you can build powerful navigation. One common example would be a partial to show Breadcrumb navigation:
|
||||
|
||||
|
||||
{{< code file="layouts/partials/breadcrumb.html" download="breadcrumb.html" >}}
|
||||
<ol class="nav navbar-nav">
|
||||
{{ template "breadcrumbnav" (dict "p1" . "p2" .) }}
|
||||
@@ -71,15 +85,14 @@ Also see [Page Variables](/variables/page/).
|
||||
|
||||
## Content Section Lists
|
||||
|
||||
Hugo will automatically create pages for each section root that list all of the content in that section. See the documentation on [section templates][] for details on customizing the way these pages are rendered.
|
||||
Hugo will automatically create pages for each *root section* that list all of the content in that section. See the documentation on [section templates][] for details on customizing the way these pages are rendered.
|
||||
|
||||
## Content *Section* vs Content *Type*
|
||||
|
||||
By default, everything created within a section will use the [content type][] that matches the root section name. For example, Hugo will assume that `posts/post-1.md` has a `posts` content type. If you are using an [archetype][] for your posts section, Hugo will generate front matter according to what it finds in `archetypes/posts.md`.
|
||||
By default, everything created within a section will use the [content `type`][content type] that matches the *root section* name. For example, Hugo will assume that `posts/post-1.md` has a `posts` content `type`. If you are using an [archetype][] for your `posts` section, Hugo will generate front matter according to what it finds in `archetypes/posts.md`.
|
||||
|
||||
[archetype]: /content-management/archetypes/
|
||||
[content type]: /content-management/types/
|
||||
[directory structure]: /getting-started/directory-structure/
|
||||
[section templates]: /templates/section-templates/
|
||||
|
||||
|
||||
[branch bundles]: /content-management/page-bundles/#branch-bundles
|
||||
|
||||
@@ -62,7 +62,7 @@ func GetTitleFunc(style string) func(s string) string {
|
||||
{{< / highlight >}}
|
||||
|
||||
|
||||
## Configure Syntax Hightlighter
|
||||
## Configure Syntax Highlighter
|
||||
To make the transition from Pygments to Chroma seamless, they share a common set of configuration options:
|
||||
|
||||
pygmentsOptions
|
||||
|
||||
@@ -54,7 +54,7 @@ layout = "birthday"
|
||||
+++
|
||||
{{< /code >}}
|
||||
|
||||
By default, Hugo assumes `*.md` under `events` is of the `events` content type. However, we have specified that this particular file at `content/events/ my-first-event.md` is of type `event` and should render using the `birthday` layout.
|
||||
By default, Hugo assumes `*.md` under `events` is of the `events` content type. However, we have specified that this particular file at `content/events/my-first-event.md` is of type `event` and should render using the `birthday` layout.
|
||||
|
||||
### Create a Type Layout Directory
|
||||
|
||||
@@ -96,4 +96,4 @@ Read [Archetypes][archetypes] for more information on archetype usage with `hugo
|
||||
[sectiontemplates]: /templates/section-templates/
|
||||
[sections]: /content-management/sections/
|
||||
[template]: /templates/
|
||||
[Tumblr]: https://www.tumblr.com/
|
||||
[Tumblr]: https://www.tumblr.com/
|
||||
|
||||
@@ -25,7 +25,7 @@ A collection of all themes created by the Hugo community, including screenshots
|
||||
## tl;dr
|
||||
|
||||
1. Create your theme using `hugo new theme <THEMENAME>`;
|
||||
2. Test your theme against <https://github.com/spf13/HugoBasicExample> \*
|
||||
2. Test your theme against <https://github.com/gohugoio/hugoBasicExample> \*
|
||||
3. Add a `theme.toml` file to the root of the theme with all required metadata
|
||||
4. Add a descriptive `README.md` to the root of the theme source
|
||||
5. Add `/images/screenshot.png` and `/images/tn.png`
|
||||
|
||||
@@ -10,7 +10,7 @@ menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [sections,lists,indexes]
|
||||
signature: [".GetPage TYPE PATH"]
|
||||
signature: [".GetPage KIND PATH"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: []
|
||||
@@ -18,29 +18,33 @@ deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
Every `Page` has a `Kind` attribute that shows what kind of page it is. While this attribute can be used to list pages of a certain `kind` using `where`, often it can be useful to fetch a single page by its path.
|
||||
Every `Page` has a [`Kind` attribute][page_kinds] that shows what kind of page it is. While this attribute can be used to list pages of a certain `kind` using `where`, often it can be useful to fetch a single page by its path.
|
||||
|
||||
`.GetPage` looks up a page of a given `Kind` and `path`.
|
||||
`.GetPage` returns a page of a given `Kind` and `path`.
|
||||
|
||||
{{% note %}}
|
||||
If the `path` is `"foo/bar.md"`, it can be written as exactly that, or broken up
|
||||
into multiple strings as `"foo" "bar.md"`.
|
||||
{{% /note %}}
|
||||
|
||||
```
|
||||
{{ with .Site.GetPage "section" "blog" }}{{ .Title }}{{ end }}
|
||||
```
|
||||
|
||||
This method wil return `nil` when no page could be found, so the above will not print anything if the blog section isn't found.
|
||||
This method wil return `nil` when no page could be found, so the above will not print anything if the blog section is not found.
|
||||
|
||||
For a regular page:
|
||||
|
||||
```
|
||||
{{ with .Site.GetPage "page" "blog" "my-post.md" }}{{ .Title }}{{ end }}
|
||||
```
|
||||
|
||||
Note that the path can also be supplied like this:
|
||||
For a regular page (whose `Kind` is `page`):
|
||||
|
||||
```
|
||||
{{ with .Site.GetPage "page" "blog/my-post.md" }}{{ .Title }}{{ end }}
|
||||
```
|
||||
|
||||
The valid page kinds are: *page, home, section, taxonomy and taxonomyTerm.*
|
||||
Note that the `path` can also be supplied like this, where the slash-separated
|
||||
path elements are added as separate strings:
|
||||
|
||||
```
|
||||
{{ with .Site.GetPage "page" "blog" "my-post.md" }}{{ .Title }}{{ end }}
|
||||
```
|
||||
|
||||
## `.GetPage` Example
|
||||
|
||||
@@ -53,13 +57,26 @@ This code snippet---in the form of a [partial template][partials]---allows you t
|
||||
|
||||
{{< code file="grab-top-two-tags.html" >}}
|
||||
<ul class="most-popular-tags">
|
||||
{{ $t := $.Site.GetPage "taxonomyTerm" "tags" }}
|
||||
{{ $t := .Site.GetPage "taxonomyTerm" "tags" }}
|
||||
{{ range first 2 $t.Data.Terms.ByCount }}
|
||||
<li>{{.}}</li>
|
||||
<li>{{ . }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{< /code >}}
|
||||
|
||||
## `.GetPage` on Page Bundles
|
||||
|
||||
If the page retrieved by `.GetPage` is a [Leaf Bundle][leaf_bundle], and you
|
||||
need to get the nested _**page** resources_ in that, you will need to use the
|
||||
methods in `.Resources` as explained in the [Page Resources][page_resources]
|
||||
section.
|
||||
|
||||
See the [Headless Bundle][headless_bundle] documentation for an example.
|
||||
|
||||
|
||||
[partials]: /templates/partials/
|
||||
[taxonomy]: /content-management/taxonomies/
|
||||
[page_kinds]: /templates/section-templates/#page-kinds
|
||||
[leaf_bundle]: /content-management/page-bundles/#leaf-bundles
|
||||
[headless_bundle]: /content-management/page-bundles/#headless-bundle
|
||||
[page_resources]: /content-management/page-resources/
|
||||
|
||||
@@ -15,7 +15,7 @@ workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [countrunes]
|
||||
deprecated: false
|
||||
aliases: [/functions/countrunes/,/functions/countwords/]
|
||||
aliases: [/functions/countwords/]
|
||||
---
|
||||
|
||||
The template function works similar to the [.WordCount page variable][pagevars].
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: .Format
|
||||
description: Formats built-in Hugo dates---`.Date`, `.PublishDate`, and `.LastMod`---according to Go's layout string.
|
||||
description: Formats built-in Hugo dates---`.Date`, `.PublishDate`, and `.Lastmod`---according to Go's layout string.
|
||||
godocref: https://golang.org/pkg/time/#example_Time_Format
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
@@ -23,7 +23,7 @@ toc: true
|
||||
|
||||
* `.PublishDate`
|
||||
* `.Date`
|
||||
* `.LastMod`
|
||||
* `.Lastmod`
|
||||
|
||||
Assuming a key-value of `date: 2017-03-03` in a content file's front matter, your can run the date through `.Format` followed by a layout string for your desired output at build time:
|
||||
|
||||
@@ -69,9 +69,6 @@ date: 2017-03-03T14:15:59-06:00
|
||||
`"Mon Jan 2 2006"`
|
||||
: **Returns**: `Fri Mar 3 2017`
|
||||
|
||||
`"January 2nd"`
|
||||
: **Returns**: `March 3rd`
|
||||
|
||||
`"January 2006"`
|
||||
: **Returns**: `March 2017`
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ pop_city = 658390
|
||||
pop_metro = 1717900
|
||||
```
|
||||
|
||||
The example we will use will be an article on Oslo, which front matter should set to exactly the same name as the corresponding file name in `data/locations/`:
|
||||
The example we will use will be an article on Oslo, whose front matter should be set to exactly the same name as the corresponding file name in `data/locations/`:
|
||||
|
||||
```
|
||||
title = "My Norwegian Vacation"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: lang.Merge
|
||||
description: "Merge missing translations from other languages."
|
||||
godocref: ""
|
||||
workson: []
|
||||
date: 2018-03-16
|
||||
categories: [functions]
|
||||
keywords: [multilingual]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
toc: false
|
||||
signature: ["lang.Merge FROM TO"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: []
|
||||
deprecated: false
|
||||
draft: false
|
||||
aliases: []
|
||||
comments:
|
||||
---
|
||||
|
||||
As an example:
|
||||
|
||||
```bash
|
||||
{{ $pages := .Site.RegularPages | lang.Merge $frSite.RegularPages | lang.Merge $enSite.RegularPages }}
|
||||
```
|
||||
|
||||
Will "fill in the gaps" in the current site with, from left to right, content from the French site, and lastly the English.
|
||||
|
||||
|
||||
A more practical example is to fill in the missing translations for the "minority languages" with content from the main language:
|
||||
|
||||
|
||||
```bash
|
||||
{{ $pages := .Site.RegularPages }}
|
||||
{{ .Scratch.Set "pages" $pages }}
|
||||
{{ $mainSite := .Sites.First }}
|
||||
{{ if ne $mainSite .Site }}
|
||||
{{ .Scratch.Set "pages" ($pages | lang.Merge $mainSite.RegularPages) }}
|
||||
{{ end }}
|
||||
{{ $pages := .Scratch.Get "pages" }}
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
Note that the slightly ugly `.Scratch` construct will not be needed once this is fixed: https://github.com/golang/go/issues/10608
|
||||
{{% /note %}}
|
||||
@@ -6,7 +6,7 @@ godocref:
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
categories: [functions,fundamentals]
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
|
||||
@@ -32,6 +32,7 @@ See [this Go issue](https://github.com/golang/go/issues/10608) for the main moti
|
||||
* `Get` returns the `value` for the `key` given.
|
||||
* `SetInMap` takes a `key`, `mapKey` and `value`
|
||||
* `GetSortedMapValues` returns array of values from `key` sorted by `mapKey`
|
||||
* `Delete` takes a `key` to remove
|
||||
|
||||
`Set` and `SetInMap` can store values of any type.
|
||||
|
||||
@@ -69,6 +70,11 @@ The usage is best illustrated with some samples:
|
||||
{{ $.Scratch.SetInMap "a3" "c" "CC" }}
|
||||
{{ $.Scratch.SetInMap "a3" "b" "BB" }}
|
||||
{{ $.Scratch.GetSortedMapValues "a3" }} {{/* => []interface {}{"AA", "BB", "CC"} */}}
|
||||
|
||||
{{ $.Scratch.Add "a" 1 }}
|
||||
{{ $.Scratch.Delete "a" }}
|
||||
{{ $.Scratch.Add "a" 2 }}
|
||||
{{ $.Scratch.Get "a" }} {{/* => 2 */}}
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
|
||||
@@ -6,7 +6,7 @@ godocref:
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
categories: [functions,fundamentals]
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
@@ -24,7 +24,7 @@ aliases: []
|
||||
{{title "BatMan"}}` → "Batman"
|
||||
```
|
||||
|
||||
Can be combined in pipes. In the following snippet, the link text is cleaned up using `humanize` to remove dashes and `title` to convert the value of `$name` to Intial Caps.
|
||||
Can be combined in pipes. In the following snippet, the link text is cleaned up using `humanize` to remove dashes and `title` to convert the value of `$name` to Initial Caps.
|
||||
|
||||
```
|
||||
{{ range $name, $items := .Site.Taxonomies.categories }}
|
||||
|
||||
@@ -50,7 +50,7 @@ It can also be used with the logical operators `!=`, `>=`, `in`, etc. Without an
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
The following logical operators are vailable with `where`:
|
||||
The following logical operators are available with `where`:
|
||||
|
||||
`=`, `==`, `eq`
|
||||
: `true` if a given field value equals a matching value
|
||||
|
||||
@@ -6,7 +6,7 @@ godocref:
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-03-12
|
||||
categories: [functions,fundamentals]
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
title: Code Toggle
|
||||
description: Code Toggle tryout and showcase.
|
||||
date: 2018-03-16
|
||||
categories: [getting started,fundamentals]
|
||||
keywords: [configuration,toml,yaml,json]
|
||||
weight: 60
|
||||
sections_weight: 60
|
||||
draft: false
|
||||
toc: true
|
||||
---
|
||||
|
||||
## The Config Toggler!
|
||||
|
||||
This is an exemple for the Config Toggle shortcode.
|
||||
Its purpose is to let users choose a Config language by clicking on its corresponding tab. Upon doing so, every Code toggler on the page will be switched to the target language. Also, target language will be saved in user's `localStorage` so when they go to a different pages, Code Toggler display their last "toggled" config language.
|
||||
|
||||
## That Congig Toggler
|
||||
|
||||
{{< code-toggle file="config">}}
|
||||
|
||||
baseURL: "https://yoursite.example.com/"
|
||||
title: "My Hugo Site"
|
||||
footnoteReturnLinkContents: "↩"
|
||||
permalinks:
|
||||
post: /:year/:month/:title/
|
||||
params:
|
||||
Subtitle: "Hugo is Absurdly Fast!"
|
||||
AuthorName: "Jon Doe"
|
||||
GitHubUser: "spf13"
|
||||
ListOfFoo:
|
||||
- "foo1"
|
||||
- "foo2"
|
||||
SidebarRecentLimit: 5
|
||||
{{< /code-toggle >}}
|
||||
|
||||
## Another Config Toggler!
|
||||
|
||||
{{< code-toggle file="theme">}}
|
||||
|
||||
# theme.toml template for a Hugo theme
|
||||
|
||||
name = "Hugo Theme"
|
||||
license = "MIT"
|
||||
licenselink = "https://github.com/budparr/gohugo.io/blob/master/LICENSE.md"
|
||||
description = ""
|
||||
homepage = "https://github.com/budparr/gohugo.io"
|
||||
tags = ["website"]
|
||||
features = ["", ""]
|
||||
min_version = 0.18
|
||||
|
||||
[author]
|
||||
name = "Bud Parr"
|
||||
homepage = "https://github.com/budparr"
|
||||
|
||||
{{< /code-toggle >}}
|
||||
|
||||
## Two regular code blocks
|
||||
|
||||
{{< code file="bf-config.toml" >}}
|
||||
[blackfriday]
|
||||
angledQuotes = true
|
||||
fractions = false
|
||||
plainIDAnchors = true
|
||||
extensions = ["hardLineBreak"]
|
||||
{{< /code >}}
|
||||
|
||||
{{< code file="bf-config.yml" >}}
|
||||
blackfriday:
|
||||
angledQuotes: true
|
||||
fractions: false
|
||||
plainIDAnchors: true
|
||||
extensions:
|
||||
- hardLineBreak
|
||||
{{< /code >}}
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Configure Hugo
|
||||
linktitle: Configuration
|
||||
description: Often the default settings are good enough, but the config file can provide highly granular control over how your site is rendered.
|
||||
description: How to configure your Hugo site.
|
||||
date: 2013-07-01
|
||||
publishdate: 2017-01-02
|
||||
lastmod: 2017-03-05
|
||||
@@ -18,9 +18,226 @@ aliases: [/overview/source-directory/,/overview/configuration/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
The [directory structure][] of a Hugo website—or more precisely, the source organization of files containing the website's content and templates—provides most of the configuration information that Hugo needs in order to generate a finished website.
|
||||
Hugo uses the `config.toml`, `config.yaml`, or `config.json` (if found in the
|
||||
site root) as the default site config file.
|
||||
|
||||
Because of Hugo's sensible defaults, many websites may not need a configuration file. Hugo is designed to recognize certain typical usage patterns.
|
||||
The user can choose to override that default with one or more site config files
|
||||
using the command line `--config` switch.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
hugo --config debugconfig.toml
|
||||
hugo --config a.toml,b.toml,c.toml
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
Multiple site config files can be specified as a comma-separated string to the `--config` switch.
|
||||
{{% /note %}}
|
||||
|
||||
## All Configuration Settings
|
||||
|
||||
The following is the full list of Hugo-defined variables with their default
|
||||
value in parentheses. Users may choose to override those values in their site
|
||||
config file(s).
|
||||
|
||||
archetypeDir ("archetypes")
|
||||
: The directory where Hugo finds archetype files (content templates).
|
||||
|
||||
baseURL
|
||||
: Hostname (and path) to the root, e.g. http://bep.is/
|
||||
|
||||
blackfriday
|
||||
: See [Configure Blackfriday](/getting-started/configuration/#configure-blackfriday)
|
||||
|
||||
buildDrafts (false)
|
||||
: Include drafts when building.
|
||||
|
||||
buildExpired (false)
|
||||
: Include content already expired.
|
||||
|
||||
buildFuture (false)
|
||||
: Include content with publishdate in the future.
|
||||
|
||||
canonifyURLs (false)
|
||||
: Enable to turn relative URLs into absolute.
|
||||
|
||||
contentDir ("content")
|
||||
: The directory from where Hugo reads content files.
|
||||
|
||||
dataDir ("data")
|
||||
: The directory from where Hugo reads data files.
|
||||
|
||||
defaultContentLanguage ("en")
|
||||
: Content without language indicator will default to this language.
|
||||
|
||||
defaultContentLanguageInSubdir (false)
|
||||
: Render the default content language in subdir, e.g. `content/en/`. The site root `/` will then redirect to `/en/`.
|
||||
|
||||
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"`.
|
||||
|
||||
disableLiveReload (false)
|
||||
: Disable automatic live reloading of browser window.
|
||||
|
||||
disablePathToLower (false)
|
||||
: Do not convert the url/path to lowercase.
|
||||
|
||||
enableEmoji (false)
|
||||
: Enable Emoji emoticons support for page content; see the [Emoji Cheat Sheet](https://www.webpagefx.com/tools/emoji-cheat-sheet/).
|
||||
|
||||
enableGitInfo (false)
|
||||
: Enable `.GitInfo` object for each page (if the Hugo site is versioned by Git). This will then update the `Lastmod` parameter for each page using the last git commit date for that content file.
|
||||
|
||||
enableMissingTranslationPlaceholders (false)
|
||||
: Show a placeholder instead of the default value or an empty string if a translation is missing.
|
||||
|
||||
enableRobotsTXT (false)
|
||||
: Enable generation of `robots.txt` file.
|
||||
|
||||
frontmatter
|
||||
|
||||
: See [Front matter Configuration](#configure-front-matter).
|
||||
|
||||
footnoteAnchorPrefix ("")
|
||||
: Prefix for footnote anchors.
|
||||
|
||||
footnoteReturnLinkContents ("")
|
||||
: Text to display for footnote return links.
|
||||
|
||||
googleAnalytics ("")
|
||||
: Google Analytics tracking ID.
|
||||
|
||||
hasCJKLanguage (false)
|
||||
: If true, auto-detect Chinese/Japanese/Korean Languages in the content. This will make `.Summary` and `.WordCount` behave correctly for CJK languages.
|
||||
|
||||
imaging
|
||||
: See [Image Processing Config](/content-management/image-processing/#image-processing-config).
|
||||
|
||||
languages
|
||||
: See [Configure Languages](/content-management/multilingual/#configure-languages).
|
||||
|
||||
languageCode ("")
|
||||
: The site's language code.
|
||||
|
||||
disableLanguages
|
||||
: See [Disable a Language](/content-management/multilingual/#disable-a-language)
|
||||
|
||||
layoutDir ("layouts")
|
||||
: The directory from where Hugo reads layouts (templates).
|
||||
|
||||
log (false)
|
||||
: Enable logging.
|
||||
|
||||
logFile ("")
|
||||
: Log File path (if set, logging enabled automatically).
|
||||
|
||||
menu
|
||||
: See [Add Non-content Entries to a Menu](/content-management/menus/#add-non-content-entries-to-a-menu).
|
||||
|
||||
metaDataFormat ("toml")
|
||||
: Front matter meta-data format. Valid values: `"toml"`, `"yaml"`, or `"json"`.
|
||||
|
||||
newContentEditor ("")
|
||||
: The editor to use when creating new content.
|
||||
|
||||
noChmod (false)
|
||||
: Don't sync permission mode of files.
|
||||
|
||||
noTimes (false)
|
||||
: Don't sync modification time of files.
|
||||
|
||||
paginate (10)
|
||||
: Default number of pages per page in [pagination](/templates/pagination/).
|
||||
|
||||
paginatePath ("page")
|
||||
: The path element used during pagination (https://example.com/page/2).
|
||||
|
||||
permalinks
|
||||
: See [Content Management](/content-management/urls/#permalinks).
|
||||
|
||||
pluralizeListTitles (true)
|
||||
: Pluralize titles in lists.
|
||||
|
||||
preserveTaxonomyNames (false)
|
||||
: Preserve special characters in taxonomy names ("Gérard Depardieu" vs "Gerard Depardieu").
|
||||
|
||||
publishDir ("public")
|
||||
: The directory to where Hugo will write the final static site (the HTML files etc.).
|
||||
|
||||
pygmentsCodeFencesGuessSyntax (false)
|
||||
: Enable syntax guessing for code fences without specified language.
|
||||
|
||||
pygmentsStyle ("monokai")
|
||||
: Color-theme or style for syntax highlighting. See [Pygments Color Themes](https://help.farbox.com/pygments.html).
|
||||
|
||||
pygmentsUseClasses (false)
|
||||
: Enable using external CSS for syntax highlighting.
|
||||
|
||||
related
|
||||
: See [Related Content](/content-management/related/#configure-related-content).
|
||||
|
||||
relativeURLs (false)
|
||||
: Enable this to make all relative URLs relative to content root. Note that this does not affect absolute URLs.
|
||||
|
||||
rssLimit (unlimited)
|
||||
: Maximum number of items in the RSS feed.
|
||||
|
||||
sectionPagesMenu ("")
|
||||
: See ["Section Menu for Lazy Bloggers"](/templates/menu-templates/#section-menu-for-lazy-bloggers).
|
||||
|
||||
sitemap
|
||||
: Default [sitemap configuration](/templates/sitemap-template/#configure-sitemap-xml).
|
||||
|
||||
staticDir ("static")
|
||||
: Relative directory from where Hugo reads static files.
|
||||
|
||||
stepAnalysis (false)
|
||||
: Display memory and timing of different steps of the program.
|
||||
|
||||
summaryLength (70)
|
||||
: The length of text to show in a [`.Summary`](/content-management/summaries/#hugo-defined-automatic-summary-splitting).
|
||||
|
||||
taxonomies
|
||||
: See [Configure Taxonomies](/content-management/taxonomies#configure-taxonomies).
|
||||
|
||||
theme ("")
|
||||
: Theme to use (located by default in `/themes/THEMENAME/`).
|
||||
|
||||
themesDir ("themes")
|
||||
: The directory where Hugo reads the themes from.
|
||||
|
||||
title ("")
|
||||
: Site title.
|
||||
|
||||
uglyURLs (false)
|
||||
: When enabled, creates URL of the form `/filename.html` instead of `/filename/`.
|
||||
|
||||
verbose (false)
|
||||
: Enable verbose output.
|
||||
|
||||
verboseLog (false)
|
||||
: Enable verbose logging.
|
||||
|
||||
watch (false)
|
||||
: Watch filesystem for changes and recreate as needed.
|
||||
|
||||
{{% note %}}
|
||||
If you are developing your site on a \*nix machine, here is a handy shortcut for finding a configuration option from the command line:
|
||||
```
|
||||
cd ~/sites/yourhugosite
|
||||
hugo config | grep emoji
|
||||
```
|
||||
|
||||
which shows output like
|
||||
|
||||
```
|
||||
enableemoji: true
|
||||
```
|
||||
{{% /note %}}
|
||||
|
||||
## Configuration Lookup Order
|
||||
|
||||
@@ -32,9 +249,8 @@ Similar to the template [lookup order][], Hugo has a default set of rules for se
|
||||
|
||||
In your `config` file, you can direct Hugo as to how you want your website rendered, control your website's menus, and arbitrarily define site-wide parameters specific to your project.
|
||||
|
||||
## YAML Configuration
|
||||
|
||||
The following is a typical example of a YAML configuration file. The values nested under `params:` will populate the [`.Site.Params`][] variable for use in [templates][]:
|
||||
## YAML Configuration
|
||||
|
||||
{{< code file="config.yml">}}
|
||||
baseURL: "https://yoursite.example.com/"
|
||||
@@ -52,118 +268,22 @@ params:
|
||||
SidebarRecentLimit: 5
|
||||
{{< /code >}}
|
||||
|
||||
### All Variables, YAML
|
||||
The following is a typical example of a YAML configuration file. The values nested under `params:` will populate the [`.Site.Params`][] variable for use in [templates][]:
|
||||
|
||||
The following is the full list of Hugo-defined variables in an example YAML file. The values provided in this example represent the default values used by Hugo.
|
||||
|
||||
{{< code file="config.yml" download="config.yml" >}}
|
||||
archetypeDir: "archetypes"
|
||||
# hostname (and path) to the root, e.g. http://spf13.com/
|
||||
baseURL: ""
|
||||
# include content marked as draft
|
||||
buildDrafts: false
|
||||
# include content with publishdate in the future
|
||||
buildFuture: false
|
||||
# include content already expired
|
||||
buildExpired: false
|
||||
# enable this to make all relative URLs relative to content root. Note that this does not affect absolute URLs. See the "URL Management" page
|
||||
relativeURLs: false
|
||||
canonifyURLs: false
|
||||
# config file (default is path/config.yaml|json|toml)
|
||||
config: "config.toml"
|
||||
contentDir: "content"
|
||||
dataDir: "data"
|
||||
defaultLayout: "post"
|
||||
# Missing translations will default to this content language
|
||||
defaultContentLanguage: "en"
|
||||
# Renders the default content language in subdir, e.g. /en/. The root directory / will redirect to /en/
|
||||
defaultContentLanguageInSubdir: false
|
||||
disableLiveReload: false
|
||||
# Enable GitInfo feature
|
||||
enableGitInfo: false
|
||||
# Build robots.txt file
|
||||
enableRobotsTXT: false
|
||||
# Do not inject generator meta tag on homepage
|
||||
disableHugoGeneratorInject: false
|
||||
# Allows you to disable all page types and will render nothing related to 'kind';
|
||||
# values = "page", "home", "section", "taxonomy", "taxonomyTerm", "RSS", "sitemap", "robotsTXT", "404"
|
||||
disableKinds: []
|
||||
# Do not make the url/path to lowercase
|
||||
disablePathToLower: false ""
|
||||
# Enable Emoji emoticons support for page content; see emoji-cheat-sheet.com
|
||||
enableEmoji: false
|
||||
# Show a placeholder instead of the default value or an empty string if a translation is missing
|
||||
enableMissingTranslationPlaceholders: false
|
||||
footnoteAnchorPrefix: ""
|
||||
footnoteReturnLinkContents: ""
|
||||
# google analytics tracking id
|
||||
googleAnalytics: ""
|
||||
# if true, auto-detect Chinese/Japanese/Korean Languages in the content. (.Summary and .WordCount can work properly in CJKLanguage)
|
||||
hasCJKLanguage: false
|
||||
languageCode: ""
|
||||
# the length of text to show in a .Summary
|
||||
summaryLength: 70
|
||||
layoutDir: "layouts"
|
||||
# Enable Logging
|
||||
log: false
|
||||
# Log File path (if set, logging enabled automatically)
|
||||
logFile: ""
|
||||
# "toml","yaml", or "json"
|
||||
metaDataFormat: "toml"
|
||||
newContentEditor: ""
|
||||
# Don't sync permission mode of files
|
||||
noChmod: false
|
||||
# Don't sync modification time of files
|
||||
noTimes: false
|
||||
# Pagination
|
||||
paginate: 10
|
||||
paginatePath: "page"
|
||||
# See "content-management/permalinks"
|
||||
{{< code file="config.yml">}}
|
||||
baseURL: "https://yoursite.example.com/"
|
||||
title: "My Hugo Site"
|
||||
footnoteReturnLinkContents: "↩"
|
||||
permalinks:
|
||||
# Pluralize titles in lists using inflect
|
||||
pluralizeListTitles: true
|
||||
# Preserve special characters in taxonomy names ("Gérard Depardieu" vs "Gerard Depardieu")
|
||||
preserveTaxonomyNames: false
|
||||
# filesystem path to write files to
|
||||
publishDir: "public"
|
||||
# enables syntax guessing for code fences without specified language
|
||||
pygmentsCodeFencesGuessSyntax: false
|
||||
# color-codes for highlighting derived from this style
|
||||
pygmentsStyle: "monokai"
|
||||
# true use pygments-css or false will color code directly
|
||||
pygmentsUseClasses: false
|
||||
# maximum number of items in the RSS feed
|
||||
rssLimit: 15
|
||||
# see "Section Menu for Lazy Bloggers", /templates/menu-templates for more info
|
||||
SectionPagesMenu: ""
|
||||
# default sitemap configuration map
|
||||
sitemap:
|
||||
# filesystem path to read files relative from
|
||||
source: ""
|
||||
staticDir: "static"
|
||||
# display memory and timing of different steps of the program
|
||||
stepAnalysis: false
|
||||
# display metrics about template executions
|
||||
templateMetrics: false
|
||||
# theme to use (located by default in /themes/THEMENAME/)
|
||||
themesDir: "themes"
|
||||
theme: ""
|
||||
title: ""
|
||||
# Title Case style guide for the title func and other automatic title casing in Hugo.
|
||||
// Valid values are "AP" (default), "Chicago" and "Go" (which was what you had in Hugo <= 0.25.1).
|
||||
// See https://www.apstylebook.com/ and http://www.chicagomanualofstyle.org/home.html
|
||||
titleCaseStyle: "AP"
|
||||
# if true, use /filename.html instead of /filename/
|
||||
uglyURLs: false
|
||||
# verbose output
|
||||
verbose: false
|
||||
# verbose logging
|
||||
verboseLog: false
|
||||
# watch filesystem for changes and recreate as needed
|
||||
watch: true
|
||||
taxonomies:
|
||||
- category: "categories"
|
||||
- tag: "tags"
|
||||
post: /:year/:month/:title/
|
||||
params:
|
||||
Subtitle: "Hugo is Absurdly Fast!"
|
||||
AuthorName: "Jon Doe"
|
||||
GitHubUser: "spf13"
|
||||
ListOfFoo:
|
||||
- "foo1"
|
||||
- "foo2"
|
||||
SidebarRecentLimit: 5
|
||||
{{< /code >}}
|
||||
|
||||
## TOML Configuration
|
||||
@@ -188,128 +308,9 @@ title = "My Hugo Site"
|
||||
author = "John Doe"
|
||||
{{< /code >}}
|
||||
|
||||
### All Variables, TOML
|
||||
|
||||
The following is the full list of Hugo-defined variables in an example TOML file. The values provided in this example represent the default values used by Hugo.
|
||||
|
||||
{{< code file="config.toml" download="config.toml">}}
|
||||
archetypeDir = "archetypes"
|
||||
# hostname (and path) to the root, e.g. http://spf13.com/
|
||||
baseURL = ""
|
||||
# include content marked as draft
|
||||
buildDrafts = false
|
||||
# include content with publishdate in the future
|
||||
buildFuture = false
|
||||
# include content already expired
|
||||
buildExpired = false
|
||||
# enable this to make all relative URLs relative to content root. Note that this does not affect absolute URLs.
|
||||
relativeURLs = false
|
||||
canonifyURLs = false
|
||||
# config file (default is path/config.yaml|json|toml)
|
||||
config = "config.toml"
|
||||
contentDir = "content"
|
||||
dataDir = "data"
|
||||
defaultLayout = "post"
|
||||
# Missing translations will default to this content language
|
||||
defaultContentLanguage = "en"
|
||||
# Renders the default content language in subdir, e.g. /en/. The root directory / will redirect to /en/
|
||||
defaultContentLanguageInSubdir = false
|
||||
disableLiveReload = false
|
||||
# Enable GitInfo feature
|
||||
enableGitInfo = false
|
||||
# Build robots.txt file
|
||||
enableRobotsTXT = false
|
||||
# Do not inject generator meta tag on homepage
|
||||
disableHugoGeneratorInject = false
|
||||
# Allows you to disable all page types and will render nothing related to 'kind';
|
||||
# values = "page", "home", "section", "taxonomy", "taxonomyTerm", "RSS", "sitemap", "robotsTXT", "404"
|
||||
disableKinds = []
|
||||
# Do not make the url/path to lowercase
|
||||
disablePathToLower = false
|
||||
# Enable Emoji emoticons support for page content; see emoji-cheat-sheet.com
|
||||
enableEmoji = false
|
||||
# Show a placeholder instead of the default value or an empty string if a translation is missing
|
||||
enableMissingTranslationPlaceholders = false
|
||||
footnoteAnchorPrefix = ""
|
||||
footnoteReturnLinkContents = ""
|
||||
# google analytics tracking id
|
||||
googleAnalytics = ""
|
||||
# if true, auto-detect Chinese/Japanese/Korean Languages in the content. (.Summary and .WordCount can work properly in CJKLanguage)
|
||||
hasCJKLanguage = false
|
||||
languageCode = ""
|
||||
# the length of text to show in a .Summary
|
||||
summaryLength = 70
|
||||
layoutDir = "layouts"
|
||||
# Enable Logging
|
||||
log = false
|
||||
# Log File path (if set, logging enabled automatically)
|
||||
logFile =
|
||||
# maximum number of items in the RSS feed
|
||||
rssLimit = 15
|
||||
# "toml","yaml", or "json"
|
||||
metaDataFormat = "toml"
|
||||
newContentEditor = ""
|
||||
# Don't sync permission mode of files
|
||||
noChmod = false
|
||||
# Don't sync modification time of files
|
||||
noTimes = false
|
||||
# Pagination
|
||||
paginate = 10
|
||||
paginatePath = "page"
|
||||
# See "content-management/permalinks"
|
||||
permalinks =
|
||||
# Pluralize titles in lists using inflect
|
||||
pluralizeListTitles = true
|
||||
# Preserve special characters in taxonomy names ("Gérard Depardieu" vs "Gerard Depardieu")
|
||||
preserveTaxonomyNames = false
|
||||
# filesystem path to write files to
|
||||
publishDir = "public"
|
||||
# enables syntax guessing for code fences without specified language
|
||||
pygmentsCodeFencesGuessSyntax = false
|
||||
# color-codes for highlighting derived from this style
|
||||
pygmentsStyle = "monokai"
|
||||
# true: use pygments-css or false: color-codes directly
|
||||
pygmentsUseClasses = false
|
||||
# see "Section Menu for Lazy Bloggers", /templates/menu-templates for more info
|
||||
SectionPagesMenu =
|
||||
# default sitemap configuration map
|
||||
sitemap =
|
||||
# filesystem path to read static files relative from
|
||||
staticDir = "static"
|
||||
# display memory and timing of different steps of the program
|
||||
stepAnalysis = false
|
||||
# theme to use (located by default in /themes/THEMENAME/)
|
||||
themesDir = "themes"
|
||||
theme = ""
|
||||
title = ""
|
||||
# if true, use /filename.html instead of /filename/
|
||||
uglyURLs = false
|
||||
# verbose output
|
||||
verbose = false
|
||||
# verbose logging
|
||||
verboseLog = false
|
||||
# watch filesystem for changes and recreate as needed
|
||||
watch = true
|
||||
[taxonomies]
|
||||
category = "categories"
|
||||
tag = "tags"
|
||||
{{< /code >}}
|
||||
|
||||
{{% note %}}
|
||||
If you are developing your site on a \*nix machine, here is a handy shortcut for finding a configuration option from the command line:
|
||||
```
|
||||
cd ~/sites/yourhugosite
|
||||
hugo config | grep emoji
|
||||
```
|
||||
|
||||
which shows output like
|
||||
|
||||
```
|
||||
enableemoji: true
|
||||
```
|
||||
{{% /note %}}
|
||||
|
||||
## Environmental Variables
|
||||
## Configure with Environment Variables
|
||||
|
||||
In addition to the 3 config options already mentioned, configuration key-values can be defined through operating system environment variables.
|
||||
|
||||
@@ -319,10 +320,16 @@ For example, the following command will effectively set a website's title on Uni
|
||||
$ env HUGO_TITLE="Some Title" hugo
|
||||
```
|
||||
|
||||
This is really useful if you use a service such as Netlify to deploy your site. Look at the Hugo docs [Netlify configuration file](https://github.com/gohugoio/hugoDocs/blob/master/netlify.toml) for an example.
|
||||
|
||||
{{% note "Setting Environment Variables" %}}
|
||||
Names must be prefixed with `HUGO_` and the configuration key must be set in uppercase when setting operating system environment variables.
|
||||
{{% /note %}}
|
||||
|
||||
{{< todo >}}
|
||||
Test and document setting params via JSON env var.
|
||||
{{< /todo >}}
|
||||
|
||||
## Ignore Files When Rendering
|
||||
|
||||
The following statement inside `./config.toml` will cause Hugo to ignore files ending with `.foo` and `.boo` when rendering:
|
||||
@@ -333,6 +340,67 @@ ignoreFiles = [ "\\.foo$", "\\.boo$" ]
|
||||
|
||||
The above is a list of regular expressions. Note that the backslash (`\`) character is escaped in this example to keep TOML happy.
|
||||
|
||||
## Configure Front Matter
|
||||
|
||||
### Configure Dates
|
||||
|
||||
Dates are important in Hugo, and you can configure how Hugo assigns dates to your content pages. You do this by adding a `frontmatter` section to your `config.toml`.
|
||||
|
||||
|
||||
The default configuration is:
|
||||
|
||||
```toml
|
||||
[frontmatter]
|
||||
date = ["date","publishDate", "lastmod"]
|
||||
lastmod = [":git" "lastmod", "date","publishDate"]
|
||||
publishDate = ["publishDate", "date"]
|
||||
expiryDate = ["expiryDate"]
|
||||
```
|
||||
|
||||
If you, as an example, have a non-standard date parameter in some of your content, you can override the setting for `date`:
|
||||
|
||||
```toml
|
||||
[frontmatter]
|
||||
date = [ "myDate", ":default"]
|
||||
```
|
||||
|
||||
The `:default` is a shortcut to the default settings. The above will set `.Date` to the date value in `myDate` if present, if not we will look in `date`,`publishDate`, `lastmod` and pick the first valid date.
|
||||
|
||||
In the list to the right, values starting with ":" are date handlers with a special meaning (see below). The others are just names of date parameters (case insensitive) in your front matter configuration. Also note that Hugo have some built-in aliases to the above: `lastmod` => `modified`, `publishDate` => `pubdate`, `published` and `expiryDate` => `unpublishdate`. With that, as an example, using `pubDate` as a date in front matter, will, by default, be assigned to `.PublishDate`.
|
||||
|
||||
The special date handlers are:
|
||||
|
||||
|
||||
`:fileModTime`
|
||||
: Fetches the date from the content file's last modification timestamp.
|
||||
|
||||
An example:
|
||||
|
||||
```toml
|
||||
[frontmatter]
|
||||
lastmod = ["lastmod" ,":fileModTime", ":default"]
|
||||
```
|
||||
|
||||
|
||||
The above will try first to extract the value for `.Lastmod` starting with the `lastmod` front matter parameter, then the content file's modification timestamp. The last, `:default` should not be needed here, but Hugo will finally look for a valid date in `:git`, `date` and then `publishDate`.
|
||||
|
||||
|
||||
`:filename`
|
||||
: Fetches the date from the content file's filename. For example, `218-02-22-mypage.md` will extract the date `218-02-22`. Also, if `slug is not set, `mypage` will be used as the value for `.Slug`.
|
||||
|
||||
An example:
|
||||
|
||||
```toml
|
||||
[frontmatter]
|
||||
date = [":filename", ":default"]
|
||||
```
|
||||
|
||||
The above will try first to extract the value for `.Date` from the filename, then it will look in front matter parameters `date`, `publishDate` and lastly `lastmod`.
|
||||
|
||||
|
||||
`:git`
|
||||
: This is the Git author date for the last revision of this content file. This will only be set if `--enableGitInfo` is set or `enableGitInfo = true` is set in site config.
|
||||
|
||||
## Configure Blackfriday
|
||||
|
||||
[Blackfriday](https://github.com/russross/blackfriday) is Hugo's built-in Markdown rendering engine.
|
||||
|
||||
@@ -42,7 +42,7 @@ The following is a high-level overview of each of the directories with links to
|
||||
|
||||
[`archetypes`](/content-management/archetypes/)
|
||||
: You can create new content files in Hugo using the `hugo new` command.
|
||||
By default, hugo will create new content files with at least `date`, `title` (inferred from the file name), and `draft = true`. This saves time and promotes consistency for sites using multiple content types. You can create your own [archetypes][] with custom preconfigured front matter fields as well.
|
||||
By default, Hugo will create new content files with at least `date`, `title` (inferred from the file name), and `draft = true`. This saves time and promotes consistency for sites using multiple content types. You can create your own [archetypes][] with custom preconfigured front matter fields as well.
|
||||
|
||||
[`config.toml`](/getting-started/configuration/)
|
||||
: Every Hugo project should have a configuration file in TOML, YAML, or JSON format at the root. Many sites may need little to no configuration, but Hugo ships with a large number of [configuration directives][] for more granular directions on how you want Hugo to build your website.
|
||||
@@ -58,7 +58,7 @@ used by Hugo when generating your website. You can write these files in YAML, JS
|
||||
: Stores templates in the form of `.html` files that specify how views of your content will be rendered into a static website. Templates include [list pages][lists], your [homepage][], [taxonomy templates][], [partials][], [single page templates][singles], and more.
|
||||
|
||||
[`static`][]
|
||||
: stores all the static content for your future website: images, CSS, JavaScript, etc. When Hugo builds your site, all assets inside your static directory are copied over as-is. A good example of using the `static` folder is for [verifying site ownership on Google Search Console][searchconsole], where you want Hugo to copy over a complete HTML file without modifying its content.
|
||||
: Stores all the static content for your future website: images, CSS, JavaScript, etc. When Hugo builds your site, all assets inside your static directory are copied over as-is. A good example of using the `static` folder is for [verifying site ownership on Google Search Console][searchconsole], where you want Hugo to copy over a complete HTML file without modifying its content.
|
||||
|
||||
{{% note %}}
|
||||
From **Hugo 0.31** you can have multiple static directories.
|
||||
|
||||
@@ -23,7 +23,7 @@ GitHub provides free and fast static hosting over SSL for personal, organization
|
||||
|
||||
## Assumptions
|
||||
|
||||
1. You have Git 2.5 or greater [installed on your machine][installgit].
|
||||
1. You have Git 2.8 or greater [installed on your machine][installgit].
|
||||
2. You have a GitHub account. [Signing up][ghsignup] for GitHub is free.
|
||||
3. You have a ready-to-publish Hugo website or have at least completed the [Quick Start][].
|
||||
|
||||
|
||||
@@ -20,14 +20,6 @@ wip: false
|
||||
aliases: [/tutorials/hosting-on-gitlab/]
|
||||
---
|
||||
|
||||
{{% warning %}}
|
||||
GitLab has temporarily turned off custom domains support because of a security issue. The plan is to re-enable it after the 20th of February.
|
||||
For more information:
|
||||
https://about.gitlab.com/2018/02/05/gitlab-pages-custom-domain-validation/
|
||||
{{% /warning %}}
|
||||
|
||||
{{< todo >}}Remove the above when fixed.{{< /todo >}}
|
||||
|
||||
[GitLab](https://gitlab.com/) makes it incredibly easy to build, deploy, and host your Hugo website via their free GitLab Pages service, which provides [native support for Hugo, as well as numerous other static site generators](https://gitlab.com/pages/hugo).
|
||||
|
||||
## Assumptions
|
||||
|
||||
@@ -14,7 +14,7 @@ Hugo `0.30` is the **Race Car Edition**. Hugo is already very very fast, but muc
|
||||
|
||||
The second performance-related feature is a follow-up to the Template Metrics added in Hugo `0.29`. Now, if you add the flag `--templateMetricsHints`, we will calculate a score for how your partials can be cached (with the `partialCached` template func).
|
||||
|
||||
This release also more or less makes the really fast Chroma highlighter a complete alternative to Pygments. Most noteable is the new table `linenos` support ([7c30e2cb](https://github.com/gohugoio/hugo/commit/7c30e2cbb08fdf0e61f80c7f1aa29909aeca4211) [@bep](https://github.com/bep) [#3915](https://github.com/gohugoio/hugo/issues/3915)), which makes copy-and-paste code blocks much easier.
|
||||
This release also more or less makes the really fast Chroma highlighter a complete alternative to Pygments. Most notable is the new table `linenos` support ([7c30e2cb](https://github.com/gohugoio/hugo/commit/7c30e2cbb08fdf0e61f80c7f1aa29909aeca4211) [@bep](https://github.com/bep) [#3915](https://github.com/gohugoio/hugo/issues/3915)), which makes copy-and-paste code blocks much easier.
|
||||
|
||||
This release represents **31 contributions by 10 contributors** to the main Hugo code base.
|
||||
[@bep](https://github.com/bep) leads the Hugo development with a significant amount of contribution, but also a big shoutout to [@moorereason](https://github.com/moorereason), [@digitalcraftsman](https://github.com/digitalcraftsman), and [@bmon](https://github.com/bmon) for their ongoing contributions.
|
||||
|
||||
@@ -32,7 +32,7 @@ Hugo now has:
|
||||
* 197+ [themes](http://themes.gohugo.io/)
|
||||
|
||||
## Notes
|
||||
* `Resources.GetByPrefix` and `Resources.ByPrefix` are depracated. They still work, but will eventually be removed. Use `Resources.Match` (many) and `Resources.GetMatch` (one).
|
||||
* `Resources.GetByPrefix` and `Resources.ByPrefix` are deprecated. They still work, but will eventually be removed. Use `Resources.Match` (many) and `Resources.GetMatch` (one).
|
||||
* When filtering bundles pages in sub-folders, you need to include the sub-folder when matching. This was a bug introduced in `0.33` and gets it in line with images and other resources.
|
||||
|
||||
## Enhancements
|
||||
|
||||
|
After Width: | Height: | Size: 182 KiB |
@@ -1,13 +1,12 @@
|
||||
|
||||
---
|
||||
date: 2018-02-27
|
||||
title: "0.37"
|
||||
description: "0.37"
|
||||
slug: "0.37"
|
||||
title: "Hugo 0.37: Preserve PNG Colour Palette"
|
||||
description: "Reduces processed PNG file sizes. And 0.37 is built with Go 1.10!"
|
||||
categories: ["Releases"]
|
||||
---
|
||||
|
||||
The main item in Hugo `0.37` is that we now properly preserve the colour palette when processing `PNG` images. We got reports from users experiencing their `PNG` images getting bigger in file size when scaled down. Now, if you, as an example, start out with a carefully chosen 8 bit colour palette (i.e. `PNG-8`), this is now what you will end up with. A special thanks to [@aitva](https://github.com/aitva) for doing the investigative work finding a proper fix for this issue.
|
||||
The main item in Hugo `0.37` is that we now properly preserve the colour palette when processing `PNG` images. We got reports from users experiencing their `PNG` images getting bigger in file size when scaled down. Now, if you, as an example, start out with a carefully chosen 8 bit colour palette (i.e. `PNG-8`), this is now what you will end up with. A special thanks to [@aitva](https://github.com/aitva) for doing the investigative work finding a proper fix for this issue.
|
||||
|
||||
This release represents **40 contributions by 5 contributors** to the main Hugo code base.
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
---
|
||||
date: 2018-03-07
|
||||
title: "Hugo 0.37.1: One Bugfix"
|
||||
description: "Fixes SVG (and similar) handling as page resources."
|
||||
categories: ["Releases"]
|
||||
images:
|
||||
- images/blog/hugo-bug-poster.png
|
||||
|
||||
---
|
||||
|
||||
This is a bug-fix release with a one important fix:
|
||||
|
||||
Image content such as `SVG` cannot be scaled with the built-in image processing methods, but it should still be possible to use them as page resources. This was a regression in Hugo `0.37` and is now fixed. [ba94abbf](https://github.com/gohugoio/hugo/commit/ba94abbf5dd90f989242af8a7027d67a572a6128) [@bep](https://github.com/bep) [#4455](https://github.com/gohugoio/hugo/issues/4455)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
---
|
||||
date: 2018-04-02
|
||||
title: "0.38"
|
||||
description: "0.38"
|
||||
categories: ["Releases"]
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
Hugo `0.38` is an **Easter egg** filled with good stuff. We now support fetching **date and slug from the content filename**, making the move from Jekyll even easier. And you can now set `contentDir` per language with intelligent merging, and themes can now provide configuration ... Also worth mentioning is several improvements in the [Chroma](https://github.com/alecthomas/chroma) highlighter, most notable support for Go templates.
|
||||
|
||||
This release represents **39 contributions by 4 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), [@felicianotech](https://github.com/felicianotech), and [@paulcmal](https://github.com/paulcmal) for their ongoing contributions.
|
||||
|
||||
And a big thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) for his relentless work on keeping the themes site in pristine condition and to [@kaushalmodi](https://github.com/kaushalmodi) for his great work on the documentation site.
|
||||
|
||||
Also, a shoutout to [@regisphilibert](https://github.com/regisphilibert) for his work on the new [Code Toggle Shortcode](https://gohugo.io/getting-started/code-toggle/) on the Hugo docs site, which we will put to good use to improve all the configuration samples.
|
||||
|
||||
Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
|
||||
which has received **55 contributions by 18 contributors**. A special thanks to [@kaushalmodi](https://github.com/kaushalmodi), [@bep](https://github.com/bep), [@xa0082249956](https://github.com/xa0082249956), and [@paulcmal](https://github.com/paulcmal) for their work on the documentation site.
|
||||
|
||||
|
||||
Hugo now has:
|
||||
|
||||
* 24547+ [stars](https://github.com/gohugoio/hugo/stargazers)
|
||||
* 447+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
|
||||
* 213+ [themes](http://themes.gohugo.io/)
|
||||
|
||||
## Notes
|
||||
|
||||
* Hugo now allows partial redefinition `outputs` in your site configuration. This is what most people would expect, but it is still a change in behaviour. For details, see [#4487](https://github.com/gohugoio/hugo/issues/4487)
|
||||
* Before this release, Hugo flattened URLs of processed images in sub-folders. This worked fine but was not intentional. See [#4502](https://github.com/gohugoio/hugo/issues/4502).
|
||||
|
||||
## Enhancements
|
||||
|
||||
* Allow themes to define output formats, media types and params [e9c7b620](https://github.com/gohugoio/hugo/commit/e9c7b6205f94a7edac0e0df2cd18d1456cb26a06) [@bep](https://github.com/bep) [#4490](https://github.com/gohugoio/hugo/issues/4490)
|
||||
* Allow partial redefinition of the `ouputs` config [f8dc47ee](https://github.com/gohugoio/hugo/commit/f8dc47eeffa847fd0b51e376da355e3d957848a6) [@bep](https://github.com/bep) [#4487](https://github.com/gohugoio/hugo/issues/4487)
|
||||
* Add a way to merge pages by language [ffaec4ca](https://github.com/gohugoio/hugo/commit/ffaec4ca8c4c6fd05b195879ccd65acf2fd5a6ac) [@bep](https://github.com/bep) [#4463](https://github.com/gohugoio/hugo/issues/4463)
|
||||
* Extract `date` and `slug` from filename [68bf1511](https://github.com/gohugoio/hugo/commit/68bf1511f2be39b6576d882d071196e477c72c9f) [@bep](https://github.com/bep) [#285](https://github.com/gohugoio/hugo/issues/285)[#3310](https://github.com/gohugoio/hugo/issues/3310)[#3762](https://github.com/gohugoio/hugo/issues/3762)[#4340](https://github.com/gohugoio/hugo/issues/4340)
|
||||
* Add `Delete` method to delete key from `Scratch` [e46ab29b](https://github.com/gohugoio/hugo/commit/e46ab29bd24caa9e2cfa51f24ba15037750850d6) [@paulcmal](https://github.com/paulcmal)
|
||||
* Simplify Prev/Next [79dd7cb3](https://github.com/gohugoio/hugo/commit/79dd7cb31a941d7545df33b938ca3ed46593ddfd) [@bep](https://github.com/bep)
|
||||
* List Chroma lexers [2c54f1ad](https://github.com/gohugoio/hugo/commit/2c54f1ad48fe2a2f7504117d351d45abc89dcb1f) [@bep](https://github.com/bep) [#4554](https://github.com/gohugoio/hugo/issues/4554)
|
||||
* Add support for a `contentDir` set per language [eb42774e](https://github.com/gohugoio/hugo/commit/eb42774e587816b1fbcafbcea59ed65df703882a) [@bep](https://github.com/bep) [#4523](https://github.com/gohugoio/hugo/issues/4523)[#4552](https://github.com/gohugoio/hugo/issues/4552)[#4553](https://github.com/gohugoio/hugo/issues/4553)
|
||||
* Update Chroma [7a634898](https://github.com/gohugoio/hugo/commit/7a634898c359a6af0da52be17df07cae97c7937c) [@bep](https://github.com/bep) [#4549](https://github.com/gohugoio/hugo/issues/4549)
|
||||
* Add `.Site.IsServer` [1823c053](https://github.com/gohugoio/hugo/commit/1823c053c8900cb6ee53b8e5c02939c7398e34dd) [@felicianotech](https://github.com/felicianotech) [#4478](https://github.com/gohugoio/hugo/issues/4478)
|
||||
* Move to Ubuntu Trusty image [511d5d3b](https://github.com/gohugoio/hugo/commit/511d5d3b7681cb76822098f430ed6862232ca529) [@anthonyfok](https://github.com/anthonyfok)
|
||||
* Bump some deprecations [b6798ee8](https://github.com/gohugoio/hugo/commit/b6798ee8676c48f86b0bd8581ea244f4be4ef3fa) [@bep](https://github.com/bep)
|
||||
* Update Chroma to get `Go template support` [904a3d9d](https://github.com/gohugoio/hugo/commit/904a3d9ddf523d452d04d0b5814503e0ff17bd2e) [@bep](https://github.com/bep) [#4515](https://github.com/gohugoio/hugo/issues/4515)
|
||||
* Recover from error in server [f0052b6d](https://github.com/gohugoio/hugo/commit/f0052b6d0f8e113a50aeb6cd7bd34555dbf34a00) [@bep](https://github.com/bep) [#4516](https://github.com/gohugoio/hugo/issues/4516)
|
||||
* Spring test cleaning, take 2 [da880157](https://github.com/gohugoio/hugo/commit/da88015776645cc68b96e8b94030c95905df53ae) [@bep](https://github.com/bep)
|
||||
* Add docs for `lang.Merge` [70005364](https://github.com/gohugoio/hugo/commit/70005364a245ea3bc59c74192e1f4c56cb6879cf) [@bep](https://github.com/bep)
|
||||
* Remove archetype title/date warning [ac12d51e](https://github.com/gohugoio/hugo/commit/ac12d51e7ea3a0ffb7d8053a10b6bf6acf1235ae) [@bep](https://github.com/bep) [#4504](https://github.com/gohugoio/hugo/issues/4504)
|
||||
* Add docs on the new front matter configuration [0dbf79c2](https://github.com/gohugoio/hugo/commit/0dbf79c2f8cd5b1a5c91c04a8d677f956b0b8fe8) [@bep](https://github.com/bep) [#4495](https://github.com/gohugoio/hugo/issues/4495)
|
||||
* Refactor the GitInfo into the date handlers [ce6e4310](https://github.com/gohugoio/hugo/commit/ce6e4310febf5659392a41b543594382441f3681) [@bep](https://github.com/bep) [#4495](https://github.com/gohugoio/hugo/issues/4495)
|
||||
* Do not print build total when `--quiet` is set [50a03a5a](https://github.com/gohugoio/hugo/commit/50a03a5acc7c200c795590c3f4b964fdc56085f2) [@bep](https://github.com/bep) [#4456](https://github.com/gohugoio/hugo/issues/4456)
|
||||
|
||||
## Fixes
|
||||
|
||||
* Fix freeze in invalid front matter error case [93e24a03](https://github.com/gohugoio/hugo/commit/93e24a03ce98d3212a2d49ad04739141229d0809) [@bep](https://github.com/bep) [#4526](https://github.com/gohugoio/hugo/issues/4526)
|
||||
* Fix path duplication/flattening in processed images [3fbc7553](https://github.com/gohugoio/hugo/commit/3fbc75534d1acda2be1c597aa77c919d3a02659d) [@bep](https://github.com/bep) [#4502](https://github.com/gohugoio/hugo/issues/4502)[#4501](https://github.com/gohugoio/hugo/issues/4501)
|
||||
* Fix SVG and similar resource handling [ba94abbf](https://github.com/gohugoio/hugo/commit/ba94abbf5dd90f989242af8a7027d67a572a6128) [@bep](https://github.com/bep) [#4455](https://github.com/gohugoio/hugo/issues/4455)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
Forestry.io is a Git-backed CMS (content management system) for websites and web products built using static site generators such as Hugo.
|
||||
|
||||
Forestry bridges the gap between developers and their teams, by making development fun and easy, while providing powerful content management for their teams.
|
||||
|
||||
|
After Width: | Height: | Size: 222 KiB |
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Forestry.io
|
||||
date: 2018-03-16
|
||||
description: "Showcase: \"Seeing Hugo in action is a whole different world of awesome.\""
|
||||
siteURL: https://forestry.io/
|
||||
siteSource: https://github.com/forestryio/forestry.io
|
||||
---
|
||||
|
||||
It was clear from the get-go that we had to go with a static site generator. Static sites are secure, performant, and give you 100% flexibility. At [Forestry.io](https://forestry.io/) we provide Content Management Solutions for websites built with static site generators, so we might be a little biased. The only question: Which static site generator was the right choice for us?
|
||||
|
||||
### Why Hugo?
|
||||
|
||||
In our early research we looked at Ionic’s [site](https://github.com/ionic-team/ionic) to get some inspiration. They used Jekyll to build their website. While Jekyll is a great generator, the build times for larger sites can be painfully slow. With more than 150 pages plus many custom configurations and add-ons, our website doesn’t fall into the low-volume category anymore. Our developers want a smooth experience when working on the website and our content editors need the ability to preview content quickly. In short, we need our builds to be lightning fast.
|
||||
|
||||
We knew Hugo was fast but we did [some additional benchmarking](https://forestry.io/blog/hugo-vs-jekyll-benchmark/) before making our decision. Seeing Hugo in action is a whole different world of awesome. Hugo takes less than one second to build our 150-page site! Take a look:
|
||||
|
||||
```bash
|
||||
| EN
|
||||
+------------------+-----+
|
||||
Pages | 141
|
||||
Paginator pages | 4
|
||||
Non-page files | 0
|
||||
Static files | 537
|
||||
Processed images | 0
|
||||
Aliases | 60
|
||||
Sitemaps | 1
|
||||
Cleaned | 0
|
||||
|
||||
Total in 739 ms
|
||||
```
|
||||
|
||||
In fact, we liked Hugo so much that our wizard Chris made his workflow public and we started the open-source project [Create-Static-Site](https://github.com/forestryio/create-static-site). It's [a simple way to spin up sites](https://forestry.io/blog/up-and-running-with-hugo/) and set up a modern web development workflow with one line of code. Essentially it adds build configurations as a dependency for JS, CSS and Image Processing.
|
||||
|
||||
Lastly, we want to take the opportunity to give some love to other amazing tools we used building our website.
|
||||
|
||||
### What tools did we use?
|
||||
|
||||
* Our Norwegian designer Nichlas is in love with [**Sketch**](https://www.sketchapp.com/). From what we hear it’s a designer’s dream come true.
|
||||
* Some say our main graphic is [mesmerizing](https://twitter.com/hmncllctv/status/968907474664284160). Nichlas created it using [**3DS Max**](https://www.autodesk.com/products/3ds-max/overview).
|
||||
* [**Hugo**](https://gohugo.io/) -- of course.
|
||||
* Chris can’t think of modern web development without [**Gulp**](https://gulpjs.com/) & [**Webpack**](https://webpack.js.org/). We used them to add additional build steps such as Browsersync, CSS, JS and SVG optimization.
|
||||
* Speaking about adding steps to our build, our lives would be much harder without [**CircleCI**](https://circleci.com/) for continuous deployment and automated testing purposes.
|
||||
* We can’t stop raving about [**Algolia**](https://www.algolia.com/). Chris loves it and even wrote a tutorial on [how to implement Algolia](https://forestry.io/blog/search-with-algolia-in-hugo/) into static sites using Hugo’s [Custom Outputs](https://gohugo.io/templates/output-formats/).
|
||||
* [**Cloudinary**](https://cloudinary.com/) is probably one of the easiest ways to get responsive images into your website.
|
||||
* We might be a little biased on this one - We think [**Forestry.io**](https://forestry.io/) is a great way to add a content management system with a clean UI on top of your site without interrupting your experience as a developer.
|
||||
* For hosting purposes we use the almighty [**AWS**](https://aws.amazon.com/).
|
||||
* [**Formspree.io**](https://formspree.io/) is managing our support and enterprise requests.
|
||||
* We also use browser cookies and JS to customize our user’s experience and give it a more dynamic feel.
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
Let's Encrypt is a free, automated, and open certificate authority (CA), run for the public's benefit. It is a service provided by the [Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/).
|
||||
|
After Width: | Height: | Size: 144 KiB |
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: "Let’s Encrypt"
|
||||
date: 2018-03-13
|
||||
description: "Showcase: Lessons learned from taking letsencrypt.org to Hugo."
|
||||
siteURL: https://letsencrypt.org/
|
||||
siteSource: https://github.com/letsencrypt/website
|
||||
byline: "[bep](https://github.com/bep), Hugo Lead"
|
||||
---
|
||||
|
||||
The **Let’s Encrypt website** has a common set of elements: A landing page and some other static info-pages, a document section, a blog, and a documentation section. Having it moved to Hugo was mostly motivated by a _simpler administration and Hugo's [multilingual support](/content-management/multilingual/)_. They already serve HTTPS to more than 60 million domains, and having the documentation available in more languages will increase that reach.[^1]
|
||||
|
||||
{{< tweet 971755920639307777 >}}
|
||||
|
||||
I helped them port the site from Jekyll to Hugo. There are usually very few surprises doing this. I know Hugo very well, but working on sites with a history usually comes up with something new.
|
||||
|
||||
That site is bookmarked in many browsers, so preserving the URLs was a must. Hugo's URL handling is very flexible, but there was one challenge. The website has a mix of standard and what we in Hugo call _ugly URLs_ (`https://letsencrypt.org/2017/12/07/looking-forward-to-2018.html`). In Hugo this is handled automatically, and you can turn it on globally or per language. But before Hugo `0.33` you could not configure it for parts of your site. You could set it manually for the relevant pages in front matter -- which is how it was done in Jekyll -- but that would be hard to manage, especially when you start to introduce translations. So, in [Hugo 0.33](https://gohugo.io/news/0.33-relnotes/) I added support for _ugly URLs_ per section and also `url` set in front matter for list pages (`https://letsencrypt.org/blog/`).
|
||||
|
||||
The lessons learned from this also lead to [disableLanguages](/content-management/multilingual/#disable-a-language) in Hugo `0.34` (a way to turn off languages during translation). And I also registered [this issue](https://github.com/gohugoio/hugo/issues/4463). Once fixed it will make it easier to handle partially translated sites.
|
||||
|
||||
|
||||
[^1]: The work on getting the content translated is in progress.
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
Small Multiples is a multidisciplinary team of data specialists, designers and developers that help people make the best use of their data, a journey that starts from strategy, to concepts, mock-ups, prototypes, design, and development.
|
||||
|
||||
|
After Width: | Height: | Size: 366 KiB |
@@ -0,0 +1,47 @@
|
||||
---
|
||||
|
||||
title: Small Multiples
|
||||
date: 2018-02-28
|
||||
description: "\"Hugo has excellent support and integration with Netlify and we were immediately blown away by how fast it was.\""
|
||||
siteURL: https://smallmultiples.com.au/
|
||||
byline: "[Small Multiples](https://smallmultiples.com.au/)"
|
||||
draft: true
|
||||
---
|
||||
|
||||
Previously we had built and hosted our website with SquareSpace. Although SquareSpace was adequate for quickly showcasing our work, we felt it didn’t reflect our technical capabilities and the types of products we build for our clients.
|
||||
|
||||
For many client applications, static front-end sites provide fast, scalable solutions that can easily connect with any back-end service, API or static data. We wanted to use the same processes and infrastructure that we use to host and deploy many of our products, so we felt that building a static site was the right solution for our website.
|
||||
|
||||
Netlify is a hosting and deployment service that we use for many products. Our developers really like it because it has strong integration with GitHub and it works with the build tools we use such as Yarn and Webpack. It creates a production build every time we commit to our GitHub repository. This means we can share and preview every change internally or with clients.
|
||||
|
||||
Application development has become increasingly complex and there is a strong motivation to simplify this process by avoiding complicated backends in favour of applications that consume static data and APIs (a JAMstack).
|
||||
|
||||
Libraries like React make this easy, but we also wanted something that was server rendered. This led us to look at React based tools for static site generation such as GatsbyJS. We liked GatsbyJS, but in the end, we didn’t choose it due to the lack of availability of a simple CMS driven data source.
|
||||
|
||||
For this, we considered Contentful. Contentful is a beautifully designed application. It’s basically a headless CMS, but it’s not specifically designed for websites and it becomes quite expensive at a commercial level. Their free tier is possibly a good option for personal sites especially with Gatsby. We also evaluated prose.io. This is a free service for editing markdown files in a GitHub repository. It works well, but it’s quite basic and didn’t provide the editing experience we were looking for.
|
||||
|
||||
At the same time, we started exploring Hugo. Hugo is a static site generator similar to Jekyll, but it’s written in Go. It has excellent support and integration with Netlify and we were immediately blown away by how fast it was.
|
||||
|
||||
We had been closely following the redevelopment of the Smashing Magazine website. We knew this was being powered by Hugo and Netlify and this showed us that Hugo could work for a large scale sites.
|
||||
|
||||
The deciding factor, however, was the availability of CMS options that integrate well with Hugo. Netlify has an open source project called NetlifyCMS and there are also hosted services like Forestry.io. These both provide a CMS with an editing interface for markdown files and images. There is no database, instead, changes are committed directly back into the GitHub repository.
|
||||
|
||||
In the end, we chose Hugo on Netlify, with Forestry as our CMS. The site is built and redeployed immediately with Netlify watching for changes to the GitHub repository.
|
||||
|
||||
Was this the right choice? For us, yes, but we learnt a few things along the way.
|
||||
|
||||
The Hugo templating language was very powerful, although also frustrating at times. The queries used to filter list pages are concise but difficult to read. Although it’s easy to get started, Hugo can have a significant learning curve as you try to do more complicated things.
|
||||
|
||||
Hugo has particular expectations when it comes to CMS concepts like tags, categories, RSS, related content and menus. Some parts of our initial design did not match perfectly with how these work in Hugo. It took some time to figure out how to make things work the way we wanted without losing all the benefits of structured content.
|
||||
|
||||
There were a few teething issues. We picked some relatively new technologies and as a result, we encountered some bugs. We were forced to find some workarounds and logged some issues with Hugo during the course of development. Most of these were fixed and features were added with releases happening frequently over the time we were working on the project. This can be exciting but also frustrating. We can see Hugo is developing in the right direction.
|
||||
|
||||
NetlifyCMS was also very new when we first looked at it and this is partly why we opted for Forestry. Forestry is an excellent choice for an out-of-the-box CMS and it needs very little code configuration. It provided a better editing experience for non-technical users. I would still say this is true, but it also provides fewer options for customisation when compared with NetlifyCMS.
|
||||
|
||||
Fortunately, the site is more portable now than it was, or would have been with a dynamic CMS like WordPress, or a fully hosted service like SquareSpace. It should be comparatively easy to swap the publishing functions from Forestry to NetlifyCMS or to change the templates. No part of the pipe-line is tightly coupled, the hosting, the CMS and the templates and the build process can all be updated independently, without changing anything else.
|
||||
|
||||
We have complete control over the design and mark-up produced. This means we can implement a better responsive design and have a stronger focus on accessibility and performance.
|
||||
|
||||
These technology choices gave us a good performance baseline. It was important to implement a site that took advantage of this. As a data visualisation agency, it can be difficult to optimise for performance with a small bundle size, while also aiming for high-quality visuals and working with large datasets. This meant we spent a lot of time optimising assets making sure there was little blocking the critical path for faster rendering and lazy-load images and videos.
|
||||
|
||||
The end result is a high performance site. We think this could have been achieved with GatsbyJS, Hugo or any another static site generator. However, what was important was the decision to use static infrastructure for speed, security, flexibility and hopefully a better ongoing development experience. If you are looking at choosing a static site generator or wondering whether a static is the right choice for you, we hope this has helped.
|
||||
@@ -52,4 +52,10 @@ Your 404.html file can be set to load automatically when a visitor enters a mist
|
||||
* Amazon AWS S3. When setting a bucket up for static web serving, you can specify the error file from within the S3 GUI.
|
||||
* Caddy Server. Using `errors { 404 /404.html }`. [Details here](https://caddyserver.com/docs/errors)
|
||||
|
||||
[pagevars]: /variables/page/
|
||||
{{% note %}}
|
||||
`hugo server` will not automatically load your custom `404.html` file, but you
|
||||
can test the appearance of your custom "not found" page by navigating your
|
||||
browser to `/404.html`.
|
||||
{{% /note %}}
|
||||
|
||||
[pagevars]: /variables/page/
|
||||
|
||||
@@ -81,7 +81,7 @@ You can now render the list of recordings for all the bass players in a template
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
And then in the `partial/artist.html`:
|
||||
And then in the `partials/artist.html`:
|
||||
|
||||
```
|
||||
<ul>
|
||||
@@ -118,7 +118,7 @@ Note the use of the [`markdownify` template function][markdownify]. This will se
|
||||
|
||||
## Data-Driven Content
|
||||
|
||||
In addition to the [data files](/extras/datafiles/) feature, Hugo also a "data-driven content" feature, which lets you load any [JSON](http://www.json.org/) or [CSV](http://en.wikipedia.org/wiki/Comma-separated_values) file from nearly any resource.
|
||||
In addition to the [data files](/extras/datafiles/) feature, Hugo also has a "data-driven content" feature, which lets you load any [JSON](http://www.json.org/) or [CSV](http://en.wikipedia.org/wiki/Comma-separated_values) file from nearly any resource.
|
||||
|
||||
Data-driven content currently consists of two functions, `getJSON` and `getCSV`, which are available in all template files.
|
||||
|
||||
|
||||
@@ -109,24 +109,37 @@ There are more boolean operators than those listed in the Hugo docs in the [Gola
|
||||
|
||||
## Includes
|
||||
|
||||
When including another template, you will pass to it the data it will be
|
||||
able to access. To pass along the current context, please remember to
|
||||
include a trailing dot. The templates location will always be starting at
|
||||
the `/layouts/` directory within Hugo.
|
||||
When including another template, you will need to pass it the data that it would
|
||||
need to access.
|
||||
|
||||
### Template and Partial Examples
|
||||
{{% note %}}
|
||||
To pass along the current context, please remember to include a trailing **dot**.
|
||||
{{% /note %}}
|
||||
|
||||
```
|
||||
{{ template "partials/header.html" . }}
|
||||
```
|
||||
The templates location will always be starting at the `layouts/` directory
|
||||
within Hugo.
|
||||
|
||||
Starting with Hugo v0.12, you may also use the `partial` call
|
||||
for [partial templates][partials]:
|
||||
### Partial
|
||||
|
||||
The [`partial`][partials] function is used to include *partial* templates using
|
||||
the syntax `{{ partial "<PATH>/<PARTIAL>.<EXTENSION>" . }}`.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
{{ partial "header.html" . }}
|
||||
```
|
||||
|
||||
### Template
|
||||
|
||||
The `template` function was used to include *partial* templates in much older
|
||||
Hugo versions. Now it is still useful for calling [*internal*
|
||||
templates][internal_templates]:
|
||||
|
||||
```
|
||||
{{ template "_internal/opengraph.html" . }}
|
||||
```
|
||||
|
||||
## Logic
|
||||
|
||||
Go templates provide the most basic iteration and conditional logic.
|
||||
@@ -261,7 +274,7 @@ Stuff Here
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
### Example 4: Internet Explorer Conditional Comments
|
||||
### Example 4: Internet Explorer Conditional Comments {#ie-conditional-comments}
|
||||
|
||||
By default, Go Templates remove HTML comments from output. This has the unfortunate side effect of removing Internet Explorer conditional comments. As a workaround, use something like this:
|
||||
|
||||
@@ -361,6 +374,45 @@ Go considers the following characters whitespace:
|
||||
* carriage <kbd>return</kbd>
|
||||
* newline
|
||||
|
||||
## Comments
|
||||
|
||||
In order to keep your templates organized and share information throughout your team, you may want to add comments to your templates. There are two ways to do that with Hugo.
|
||||
|
||||
### Go templates comments
|
||||
|
||||
Go templates support `{{/*` and `*/}}` to open and close a comment block. Nothing within that block will be rendered.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
Bonsoir, {{/* {{ add 0 + 2 }} */}}Eliott.
|
||||
```
|
||||
|
||||
Will render `Bonsoir, Eliott.`, and not care about the syntax error (`add 0 + 2`) in the comment block.
|
||||
|
||||
### HTML comments
|
||||
|
||||
If you need to produce HTML comments from your templates, take a look at the [Internet Explorer conditional comments](#ie-conditional-comments) example. If you need variables to construct such HTML comments, just pipe `printf` to `safeHTML`. For example:
|
||||
|
||||
```
|
||||
{{ printf "<!-- Our website is named: %s -->" .Site.Title | safeHTML }}
|
||||
```
|
||||
|
||||
#### HTML comments containing Go templates
|
||||
|
||||
HTML comments are by default stripped, but their content is still evaluated. That means that although the HTML comment will never render any content to the final HTML pages, code contained within the comment may fail the build process.
|
||||
|
||||
{{% note %}}
|
||||
Do **not** try to comment out Go template code using HTML comments.
|
||||
{{% /note %}}
|
||||
|
||||
```
|
||||
<!-- {{ $author := "Emma Goldman" }} was a great woman. -->
|
||||
{{ $author }}
|
||||
```
|
||||
|
||||
The templating engine will strip the content within the HTML comment, but will first evaluate any Go template code if present within. So the above example will render `Emma Goldman`, as the `$author` variable got evaluated in the HTML comment. But the build would have failed if that code in the HTML comment had an error.
|
||||
|
||||
## Hugo Parameters
|
||||
|
||||
Hugo provides the option of passing values to your template layer through your [site configuration][config] (i.e. for site-wide values) or through the metadata of each specific piece of content (i.e. the [front matter][]). You can define any values of any type and use them however you want in your templates, as long as the values are supported by the front matter format specified via `metaDataFormat` in your configuration file.
|
||||
@@ -479,6 +531,7 @@ Go allows you to do more than what's shown here. Using Hugo's [`where` function]
|
||||
[index]: /functions/index/
|
||||
[math functions]: /functions/math/
|
||||
[partials]: /templates/partials/ "Link to the partial templates page inside of the templating section of the Hugo docs"
|
||||
[internal_templates]: /templates/internal/
|
||||
[relpermalink]: /variables/page/
|
||||
[safehtml]: /functions/safehtml/
|
||||
[sitevars]: /variables/site/
|
||||
|
||||
@@ -43,15 +43,7 @@ The idea of a list page comes from the [hierarchical mental model of the web][me
|
||||
|
||||
Since section lists and taxonomy lists (N.B., *not* [taxonomy terms lists][taxterms]) are both *lists* with regards to their templates, both have the same terminating default of `_default/list.html` or `themes/<THEME>/layouts/_default/list.html` in their lookup order. In addition, both [section lists][sectiontemps] and [taxonomy lists][taxlists] have their own default list templates in `_default`:
|
||||
|
||||
#### Default Section Templates
|
||||
|
||||
1. `layouts/_default/section.html`
|
||||
2. `layouts/_default/list.html`
|
||||
|
||||
#### Default Taxonomy List Templates
|
||||
|
||||
1. `layouts/_default/taxonomy.html`
|
||||
2. `themes/<THEME>/layouts/_default/taxonomy.html`
|
||||
See [Template Lookup Order](/templates/lookup-order/) for the complete reference.
|
||||
|
||||
## Add Content and Front Matter to List Pages
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ Layout
|
||||
: Can be set in page front matter.
|
||||
|
||||
Type
|
||||
: Is value of `type` if set in front matter, else it is the name of the root section (e.g. "blog"). If will always have a value, so if not set, the value is "page".
|
||||
: Is value of `type` if set in front matter, else it is the name of the root section (e.g. "blog"). It will always have a value, so if not set, the value is "page".
|
||||
|
||||
Section
|
||||
: Is relevant for `section`, `taxonomy` and `taxonomyTerm` types.
|
||||
|
||||
@@ -96,11 +96,11 @@ If you want to build custom navigation, you can do so using the `.Paginator` obj
|
||||
`PageNumber`
|
||||
: The current page's number in the pager sequence
|
||||
|
||||
`URL`:
|
||||
The relative URL to the current pager
|
||||
`URL`
|
||||
: The relative URL to the current pager
|
||||
|
||||
`Pages`:
|
||||
The pages in the current pager
|
||||
`Pages`
|
||||
: The pages in the current pager
|
||||
|
||||
`NumberOfElements`
|
||||
: The number of elements on this page
|
||||
@@ -152,4 +152,4 @@ The pages are built on the following form (`BLANK` means no value):
|
||||
[`after`]: /functions/after/
|
||||
[configuration]: /getting-started/configuration/
|
||||
[lists]: /templates/lists/
|
||||
[where]: /functions/where/
|
||||
[where]: /functions/where/
|
||||
|
||||
@@ -67,10 +67,6 @@ As shown in the above example directory structure, you can nest your directories
|
||||
{{ partial "footer/scripts.html" . }}
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
Before v0.12, Hugo used the `template` call to include partial templates. When using Hugo v0.12 and newer, be sure to use the `{{ partial "<PATH>/<PARTIAL>.html" . }}` syntax. The old approach will still work but has fewer benefits.
|
||||
{{% /note %}}
|
||||
|
||||
### Variable Scoping
|
||||
|
||||
The second argument in a partial call is the variable being passed down. The above examples are passing the `.`, which tells the template receiving the partial to apply the current [context][context].
|
||||
@@ -166,4 +162,4 @@ The following `footer.html` partial template is used for [spf13.com](http://spf1
|
||||
[lookup order]: /templates/lookup-order/ "To keep your templating dry, read the documentation on Hugo's lookup order."
|
||||
[partialcached]: /functions/partialcached/ "Use the partial cached function to improve build times in cases where Hugo can cache partials that don't need to be rendered with every page."
|
||||
[singletemps]: /templates/single-page-templates/ "The most common form of template in Hugo is the single content template. Read the docs on how to create templates for individual pages."
|
||||
[themes]: /themes/
|
||||
[themes]: /themes/
|
||||
|
||||
@@ -20,7 +20,7 @@ toc: true
|
||||
|
||||
## RSS Template Lookup Order
|
||||
|
||||
See [Template Lookup](/templates/lookup-order/).
|
||||
See [Template Lookup Order](/templates/lookup-order/) for the complete reference.
|
||||
|
||||
{{% note "Hugo Ships with an RSS Template" %}}
|
||||
Hugo ships with its own [RSS 2.0 template](#the-embedded-rss-xml). The embedded template will be sufficient for most use cases.
|
||||
@@ -36,27 +36,9 @@ Hugo provides the ability for you to define any RSS type you wish and can have d
|
||||
|
||||
## Lookup Order for RSS Templates
|
||||
|
||||
### Main RSS
|
||||
The table below shows the RSS template lookup order for the different page kinds. The first listing shows the lookup order when running with a theme (`demoTheme`).
|
||||
|
||||
1. `/layouts/rss.xml`
|
||||
2. `/layouts/_default/rss.xml`
|
||||
3. Embedded rss.xml
|
||||
|
||||
### Section RSS
|
||||
|
||||
1. `/layouts/section/<SECTION>.rss.xml`
|
||||
2. `/layouts/_default/rss.xml`
|
||||
3. `/themes/<THEME>/layouts/section/<SECTION>.rss.xml`
|
||||
4. `/themes/<THEME>/layouts/_default/rss.xml`
|
||||
5. Embedded rss.xml
|
||||
|
||||
### Taxonomy RSS
|
||||
|
||||
1. `/layouts/taxonomy/<SINGULAR>.rss.xml`
|
||||
2. `/layouts/_default/rss.xml`
|
||||
3. `/themes/<THEME>/layouts/taxonomy/<SINGULAR>.rss.xml`
|
||||
4. `/themes/<THEME>/layouts/_default/rss.xml`
|
||||
5. Embedded rss.xml
|
||||
{{< datatable-filtered "output" "layouts" "OutputFormat == RSS" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}}
|
||||
|
||||
## Configure RSS
|
||||
|
||||
@@ -64,7 +46,7 @@ By default, Hugo will create an unlimited number of RSS entries. You can limit t
|
||||
|
||||
The following values will also be included in the RSS output if specified in your site’s configuration:
|
||||
|
||||
```
|
||||
```toml
|
||||
languageCode = "en-us"
|
||||
copyright = "This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License."
|
||||
|
||||
@@ -76,7 +58,7 @@ copyright = "This work is licensed under a Creative Commons Attribution-ShareAli
|
||||
|
||||
This is the default RSS template that ships with Hugo. It adheres to the [RSS 2.0 Specification][RSS 2.0].
|
||||
|
||||
```
|
||||
```xml
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
|
||||
@@ -114,26 +96,24 @@ Hugo will automatically add the following header line to this file on render. Pl
|
||||
|
||||
## Reference your RSS Feed in `<head>`
|
||||
|
||||
In your `header.html` template, you can specify your RSS feed in your `<head></head>` tag like this:
|
||||
In your `header.html` template, you can specify your RSS feed in your `<head></head>` tag using Hugo's [Output Formats][Output Formats] like this:
|
||||
|
||||
```
|
||||
{{ if .RSSLink }}
|
||||
<link href="{{ .RSSLink }}" rel="alternate" type="application/rss+xml" title="{{ .Site.Title }}" />
|
||||
<link href="{{ .RSSLink }}" rel="feed" type="application/rss+xml" title="{{ .Site.Title }}" />
|
||||
{{ end }}
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}" title="{{ $.Site.Title }}">
|
||||
{{ end -}}
|
||||
```
|
||||
|
||||
...with the auto-discovery link specified by the line with `rel="alternate"`.
|
||||
|
||||
The `.RSSLink` will render the appropriate RSS feed URL for the section, whether it's everything, posts in a section, or a taxonomy.
|
||||
|
||||
If you reference your RSS link, be sure to specify the MIME type with `type="application/rss+xml"`.
|
||||
If you only want the RSS link, you can query the formats:
|
||||
|
||||
```
|
||||
<a href="{{ .URL }}" type="application/rss+xml" target="_blank">{{ .SomeText }}</a>
|
||||
{{ with .OutputFormats.Get "rss" -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}" title="{{ $.Site.Title }}">
|
||||
{{ end -}
|
||||
```
|
||||
|
||||
|
||||
[config]: /getting-started/configuration/
|
||||
[embedded]: #the-embedded-rss-xml
|
||||
[RSS 2.0]: http://cyber.law.harvard.edu/rss/rss.html "RSS 2.0 Specification"
|
||||
[section]: /content-management/sections/
|
||||
[Output Formats]: /templates/output-formats/#link-to-output-formats
|
||||
@@ -26,25 +26,31 @@ To effectively leverage section page templates, you should first understand Hugo
|
||||
|
||||
See [Template Lookup](/templates/lookup-order/).
|
||||
|
||||
## Page Kinds
|
||||
|
||||
Every `Page` in Hugo has a `.Kind` attribute.
|
||||
|
||||
| Kind | Description | Example |
|
||||
|----------------|--------------------------------------------------------------------|-------------------------------------------------------------------------------|
|
||||
| `home` | The home page | `/index.html` |
|
||||
| `page` | A page showing a _regular page_ | `my-post` page (`/posts/my-post/index.html`) |
|
||||
| `section` | A page listing _regular pages_ from a given [_section_][sections] | `posts` section (`/posts/index.html`) |
|
||||
| `taxonomy` | A page listing _regular pages_ from a given _taxonomy term_ | page for the term `awesome` from `tags` taxonomy (`/tags/awesome/index.html`) |
|
||||
| `taxonomyTerm` | A page listing terms from a given _taxonomy_ | page for the `tags` taxonomy (`/tags/index.html`) |
|
||||
|
||||
## `.Site.GetPage` with Sections
|
||||
|
||||
Every `Page` in Hugo has a `.Kind` attribute. `Kind` can easily be combined with the [`where` function][where] in your templates to create kind-specific lists of content. This method is ideal for creating lists, but there are times where you may want to fetch just the index page of a single section via the section's path.
|
||||
`Kind` can easily be combined with the [`where` function][where] in your templates to create kind-specific lists of content. This method is ideal for creating lists, but there are times where you may want to fetch just the index page of a single section via the section's path.
|
||||
|
||||
The [`.GetPage` function][getpage] looks up an index page of a given `Kind` and `path`.
|
||||
|
||||
{{% note %}}
|
||||
`.GetPage` is not currently supported to grab single content files but *may* be supported in the future.
|
||||
{{% /note %}}
|
||||
You can call `.Site.GetPage` with two arguments: `kind` (one of the valid values
|
||||
of `Kind` from above) and `kind value`.
|
||||
|
||||
You can call `.Site.GetPage` with two arguments: `kind` and `kind value`.
|
||||
|
||||
These are the valid values for 'kind':
|
||||
|
||||
1. `home`
|
||||
2. `section`
|
||||
3. `taxonomy`
|
||||
4. `taxonomyTerm`
|
||||
Examples:
|
||||
|
||||
- `{{ .Site.GetPage "section" "posts" }}`
|
||||
- `{{ .Site.GetPage "page" "search" }}`
|
||||
|
||||
## Example: Creating a Default Section Template
|
||||
|
||||
@@ -113,3 +119,4 @@ Which then returns the following:
|
||||
[lists]: /templates/lists/
|
||||
[lookup]: /templates/lookup-order/
|
||||
[where]: /functions/where/
|
||||
[sections]: /content-management/sections/
|
||||
|
||||
@@ -301,9 +301,9 @@ The following example is contrived but demonstrates the concept. Assume you have
|
||||
</div>
|
||||
{{< /code >}}
|
||||
|
||||
You also have an `image` shortcode with a single named `src` parameter that you want to call inside of `gallery` and other shortcodes so that the parent defines the context of each `image`:
|
||||
You also have an `img` shortcode with a single named `src` parameter that you want to call inside of `gallery` and other shortcodes, so that the parent defines the context of each `img`:
|
||||
|
||||
{{< code file="layouts/shortcodes/image.html" >}}
|
||||
{{< code file="layouts/shortcodes/img.html" >}}
|
||||
{{- $src := .Get "src" -}}
|
||||
{{- with .Parent -}}
|
||||
<img src="{{$src}}" class="{{.Get "class"}}-image">
|
||||
@@ -322,7 +322,7 @@ You can then call your shortcode in your content as follows:
|
||||
{{</* img src="/images/three.jpg" */>}}
|
||||
```
|
||||
|
||||
This will output the following HTML. Note how the first two `image` shortcodes inherit the `class` value of `content-gallery` set with the call to the parent `gallery`, whereas the third `image` only uses `src`:
|
||||
This will output the following HTML. Note how the first two `img` shortcodes inherit the `class` value of `content-gallery` set with the call to the parent `gallery`, whereas the third `img` only uses `src`:
|
||||
|
||||
```
|
||||
<div class="content-gallery">
|
||||
|
||||
@@ -20,10 +20,10 @@ toc: true
|
||||
|
||||
A static website with a dynamic search function? Yes. As alternatives to embeddable scripts from Google or other search engines, you can provide your visitors a custom search by indexing your content files directly.
|
||||
|
||||
* [Hugoidx](https://github.com/blevesearch/hugoidx) is an experimental application to create a search index. It's built on top of [Bleve](http://www.blevesearch.com/).
|
||||
* [GitHub Gist for Hugo Workflow](https://gist.github.com/sebz/efddfc8fdcb6b480f567). This gist contains a simple workflow to create a search index for your static website. It uses a simple Grunt script to index all your content files and [lunr.js](http://lunrjs.com/) to serve the search results.
|
||||
* [hugo-lunr](https://www.npmjs.com/package/hugo-lunr). A simple way to add site search to your static Hugo site using [lunr.js](http://lunrjs.com/). Hugo-lunr will create an index file of any html and markdown documents in your Hugo project.
|
||||
* [hugo-lunr-zh](https://www.npmjs.com/package/hugo-lunr-zh). A bit like Hugo-lunr, but Hugo-lunr-zh can help you seperate the Chinese keywords.
|
||||
* [hugo-lunr-zh](https://www.npmjs.com/package/hugo-lunr-zh). A bit like Hugo-lunr, but Hugo-lunr-zh can help you separate the Chinese keywords.
|
||||
* [Github Gist for Fuse.js integration](https://gist.github.com/eddiewebb/735feb48f50f0ddd65ae5606a1cb41ae). This gist demonstrates how to leverage Hugo's existing build time processing to generate a searchable JSON index used by [Fuse.js](http://fusejs.io/) on the client side. Although this gist uses Fuse.js for fuzzy matching, any client side search tool capable of reading JSON indexes will work. Does not require npm, grunt or other build-time tools except Hugo!
|
||||
|
||||
## Commercial Search Services
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ toc: true
|
||||
---
|
||||
|
||||
{{% note %}}
|
||||
The example site used below is from https://github.com/gohugoio/hugo/examples/blog
|
||||
The example site used below is from https://github.com/gohugoio/hugo/tree/master/examples/blog
|
||||
{{% /note %}}
|
||||
|
||||
## Template Metrics
|
||||
|
||||
@@ -17,6 +17,10 @@ aliases: [/faq/]
|
||||
**Note:** The answers/solutions presented below are short, and may not be note be enough to solve your problem. Visit [Hugo Discourse](https://discourse.gohugo.io/) and use the search. It that does not help, start a new topic and ask your questions.
|
||||
{{% /note %}}
|
||||
|
||||
## Can I set configuration variables via OS environment?
|
||||
|
||||
Yes you can! See [Configure with Environment Variables](/getting-started/configuration/#configure-with-environment-variables).
|
||||
|
||||
## How do I schedule posts?
|
||||
|
||||
1. Set `publishDate` in the page [Front Matter](/content-management/front-matter/) to a date in the future.
|
||||
@@ -34,4 +38,3 @@ Also see this Twitter thread:
|
||||
## Can I use the latest Hugo version on Netlify?
|
||||
|
||||
Yes you can! Read [this](/hosting-and-deployment/hosting-on-netlify/#configure-hugo-version-in-netlify).
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@ The following is a list of site-level (aka "global") variables. Many of these va
|
||||
.Site.IsMultiLingual
|
||||
: whether there are more than one language in this site. See [Multilingual](/content-management/multilingual/) for more information.
|
||||
|
||||
.Site.IsServer
|
||||
: a boolean to indicate if the site is being served with Hugo's built-in server. See [`hugo server`](/commands/hugo_server/) for more information.
|
||||
|
||||
.Site.Language.Lang
|
||||
: the language code of the current locale (e.g., `en`).
|
||||
|
||||
@@ -122,4 +125,4 @@ You can use `.Site.Params` in a [partial template](/templates/partials/) to call
|
||||
<meta name="description" content="{{if .IsHome}}{{ $.Site.Params.description }}{{else}}{{.Description}}{{end}}" />
|
||||
{{< /code >}}
|
||||
|
||||
[config]: /getting-started/configuration/
|
||||
[config]: /getting-started/configuration/
|
||||
|
||||
@@ -25,7 +25,7 @@ toc: true
|
||||
For example, the following fields would be available in `layouts/_defaults/terms.html`, depending on how you organize your [taxonomy templates][taxonomytemplates]:
|
||||
|
||||
.Data.Singular
|
||||
: The singular name of the taxonomy (e.g., `tags => `tag`)
|
||||
: The singular name of the taxonomy (e.g., `tags => tag`)
|
||||
|
||||
.Data.Plural
|
||||
: The plural name of the taxonomy (e.g., `tags => tags`)
|
||||
@@ -49,7 +49,7 @@ Note that `.Data.Terms.Alphabetical` and `.Data.Terms.ByCount` can also be rever
|
||||
|
||||
## Use `.Site.Taxonomies` Outside of Taxonomy Templates
|
||||
|
||||
The `.Site.Taxonomies` variable holds all the taxonomies defined site-wide. `.Site.Taxonomies` is a map of the taxonomy name to a list of its values (e.g., `"tags" -> ["tag1", "tag2", "tag3"]``). Each value, though, is not a string but rather a *Taxonomy variable*.
|
||||
The `.Site.Taxonomies` variable holds all the taxonomies defined site-wide. `.Site.Taxonomies` is a map of the taxonomy name to a list of its values (e.g., `"tags" -> ["tag1", "tag2", "tag3"]`). Each value, though, is not a string but rather a *Taxonomy variable*.
|
||||
|
||||
## The `.Taxonomy` Variable
|
||||
|
||||
@@ -81,4 +81,4 @@ The following [partial template][partials] will list all your site's taxonomies,
|
||||
{{< /code >}}
|
||||
|
||||
[partials]: /templates/partials/
|
||||
[taxonomytemplates]: /templates/taxonomy-templates/
|
||||
[taxonomytemplates]: /templates/taxonomy-templates/
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
{{ $file := .Get "file" }}
|
||||
{{ $isHTML := strings.HasSuffix $file "html" }}
|
||||
{{ $.Scratch.Set "codeLang" "" }}
|
||||
{{ $suffix := findRE "(\\.[^.]+)$" $file 1 }}
|
||||
{{ with $suffix }}
|
||||
{{ $.Scratch.Set "codeLang" (index . 0 | strings.TrimPrefix ".") }}
|
||||
{{ end }}
|
||||
{{ with .Get "codeLang" }}{{ $.Scratch.Set "codeLang" . }}{{ end }}
|
||||
<div class="code relative" id="{{ $file | urlize}}">
|
||||
{{- with $file -}}
|
||||
<div class="filename san-serif f6 dib lh-solid pl2 pv2">{{.}}</div>
|
||||
@@ -11,7 +16,7 @@
|
||||
{{/* Functionality located within filesaver.js The copy here is located in the css with .copy class so it can be replaced with JS on success */}}
|
||||
{{end}}
|
||||
<div class="code-copy-content nt3" {{with .Get "download"}}id="{{.}}"{{end}}>
|
||||
{{ if .Get "nocode" }}{{ .Inner }}{{ else }}{{ if $isHTML }}{{- highlight .Inner "html" "" | -}}{{ else }}<pre><code>{{- .Inner | string -}}</code></pre>{{ end }}{{ end }}
|
||||
{{ if .Get "nocode" }}{{ $.Inner }}{{ else }}{{ with $.Scratch.Get "codeLang" }}{{- highlight $.Inner . "" | -}}{{ else }}<pre><code>{{- .Inner | string -}}</code></pre>{{ end }}{{ end }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
{{ if eq (substr . 0 1) "@" }}
|
||||
<a href="//github.com/{{ substr . 1 }}">{{ . }}</a>
|
||||
{{ else if eq (substr . 0 2) "0x" }}
|
||||
<a href="//github.com/spf13/hugo/commit/{{ substr . 2 }}">{{ substr . 2 6 }}</a>
|
||||
<a href="//github.com/gohugoio/hugo/commit/{{ substr . 2 }}">{{ substr . 2 6 }}</a>
|
||||
{{ else }}
|
||||
<a href="//github.com/spf13/hugo/issues/{{ . }}">#{{ . }}</a>
|
||||
<a href="//github.com/gohugoio/hugo/issues/{{ . }}">#{{ . }}</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -3,7 +3,7 @@ publish = "public"
|
||||
command = "hugo"
|
||||
|
||||
[context.production.environment]
|
||||
HUGO_VERSION = "0.36.1"
|
||||
HUGO_VERSION = "0.37.1"
|
||||
HUGO_ENV = "production"
|
||||
HUGO_ENABLEGITINFO = "true"
|
||||
|
||||
@@ -11,20 +11,20 @@ HUGO_ENABLEGITINFO = "true"
|
||||
command = "hugo --enableGitInfo"
|
||||
|
||||
[context.split1.environment]
|
||||
HUGO_VERSION = "0.36.1"
|
||||
HUGO_VERSION = "0.37.1"
|
||||
HUGO_ENV = "production"
|
||||
|
||||
[context.deploy-preview]
|
||||
command = "hugo -b $DEPLOY_PRIME_URL"
|
||||
|
||||
[context.deploy-preview.environment]
|
||||
HUGO_VERSION = "0.36.1"
|
||||
HUGO_VERSION = "0.37.1"
|
||||
|
||||
[context.branch-deploy]
|
||||
command = "hugo -b $DEPLOY_PRIME_URL"
|
||||
|
||||
[context.branch-deploy.environment]
|
||||
HUGO_VERSION = "0.36.1"
|
||||
HUGO_VERSION = "0.37.1"
|
||||
|
||||
[context.next.environment]
|
||||
HUGO_ENABLEGITINFO = "true"
|
||||
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 176 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 283 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 36 KiB |