commandName = subCommandName
}
cmd.Use = fmt.Sprintf("%s [flags]", commandName)
- cmd.Short = "Build your site"
- cmd.Long = `COMMAND_NAME is the main command, used to build your Hugo site.
+ cmd.Short = "Build your project"
+ cmd.Long = `COMMAND_NAME is the main command, used to build your Hugo project.
Hugo is a Fast and Flexible Static Site Generator
built with love by spf13 and friends in Go.
}
type simpleCommand struct {
- use string
- name string
- short string
- long string
- run func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *rootCommand, args []string) error
- withc func(cmd *cobra.Command, r *rootCommand)
- initc func(cd *simplecobra.Commandeer) error
+ use string
+ name string
+ short string
+ long string
+ aliases []string
+ run func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *rootCommand, args []string) error
+ withc func(cmd *cobra.Command, r *rootCommand)
+ initc func(cd *simplecobra.Commandeer) error
commands []simplecobra.Commander
cmd := cd.CobraCommand
cmd.Short = c.short
cmd.Long = c.long
+ cmd.Aliases = c.aliases
if c.use != "" {
cmd.Use = c.use
}
}
func mapLegacyArgs(args []string) []string {
- if len(args) > 1 && args[0] == "new" && !hstrings.EqualAny(args[1], "site", "theme", "content") {
+ if len(args) > 1 && args[0] == "new" && !hstrings.EqualAny(args[1], "project", "site", "theme", "content") {
// Insert "content" as the second argument
args = append(args[:1], append([]string{"content"}, args[1:]...)...)
}
func (c *configCommand) Init(cd *simplecobra.Commandeer) error {
c.r = cd.Root.Command.(*rootCommand)
cmd := cd.CobraCommand
- cmd.Short = "Display site configuration"
- cmd.Long = `Display site configuration, both default and custom settings.`
+ cmd.Short = "Display project configuration"
+ cmd.Long = `Display project configuration, both default and custom settings.`
cmd.Flags().StringVar(&c.format, "format", "toml", "preferred file format (toml, yaml or json)")
_ = cmd.RegisterFlagCompletionFunc("format", cobra.FixedCompletions([]string{"toml", "yaml", "json"}, cobra.ShellCompDirectiveNoFileComp))
cmd.Flags().StringVar(&c.lang, "lang", "", "the language to display config for. Defaults to the first language defined.")
func newDeployCommand() simplecobra.Commander {
return &simpleCommand{
name: "deploy",
- short: "Deploy your site to a cloud provider",
- long: `Deploy your site to a cloud provider
+ short: "Deploy your project to a cloud provider",
+ long: `Deploy your project to a cloud provider
See https://gohugo.io/hosting-and-deployment/hugo-deploy/ for detailed
documentation.
"editor": "newContentEditor",
}
- // Flags that we for some reason don't want to expose in the site config.
+ // Flags that we for some reason don't want to expose in the project config.
internalKeySet := map[string]bool{
"quiet": true,
"verbose": true,
if len(conf.configs.LoadingInfo.ConfigFiles) == 0 {
//lint:ignore ST1005 end user message.
- return errors.New("Unable to locate config file or config directory. Perhaps you need to create a new site.\nRun `hugo help new` for details.")
+ return errors.New("Unable to locate config file or config directory. Perhaps you need to create a new project.\nRun `hugo help new` for details.")
}
c.conf = conf
name: "jekyll",
short: "hugo import from Jekyll",
long: `hugo import from Jekyll.
-
+
Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.",
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
if len(args) < 2 {
func (c *importCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
- cmd.Short = "Import a site from another system"
- cmd.Long = `Import a site from another system.
+ cmd.Short = "Import a project from another system"
+ cmd.Long = `Import a project from another system.
Import requires a subcommand, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`."
}
func (i *importCommand) createConfigFromJekyll(fs afero.Fs, inpath string, kind metadecoders.Format, jekyllConfig map[string]any) (err error) {
- title := "My New Hugo Site"
+ title := "My New Hugo Project"
baseURL := "http://example.org/"
for key, value := range jekyllConfig {
return postDirs, hasAnyPost
}
-func (c *importCommand) createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[string]bool) error {
+func (c *importCommand) createProjectFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[string]bool) error {
fs := &afero.OsFs{}
if exists, _ := helpers.Exists(targetDir, fs); exists {
if isDir, _ := helpers.IsDir(targetDir, fs); !isDir {
return errors.New("abort: jekyll root contains neither posts nor drafts")
}
- err = c.createSiteFromJekyll(jekyllRoot, targetDir, jekyllPostDirs)
+ err = c.createProjectFromJekyll(jekyllRoot, targetDir, jekyllPostDirs)
if err != nil {
return newUserError(err)
}
)
const commonUsageMod = `
-Note that Hugo will always start out by resolving the components defined in the site
+Note that Hugo will always start out by resolving the components defined in the project
configuration, provided by a _vendor directory (if no --ignoreVendorPaths flag provided),
Go Modules, or a folder inside the themes directory, in that order.
You can also specify the kind with ` + "`-k KIND`" + `.
-If archetypes are provided in your theme or site, they will be used.
+If archetypes are provided in your theme or project, they will be used.
-Ensure you run this within the root directory of your site.`,
+Ensure you run this within the root directory of your project.`,
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
if len(args) < 1 {
return newUserError("path needs to be provided")
},
},
&simpleCommand{
- name: "site",
- use: "site [path]",
- short: "Create a new site",
- long: `Create a new site at the specified path.`,
+ name: "project",
+ use: "project [path]",
+ short: "Create a new project",
+ long: `Create a new project at the specified path.`,
+ aliases: []string{"site"},
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
if len(args) < 1 {
return newUserError("path needs to be provided")
}
sourceFs := conf.fs.Source
- err = skeletons.CreateSite(createpath, sourceFs, force, format)
+ err = skeletons.CreateProject(createpath, sourceFs, force, format)
if err != nil {
return err
}
- r.Printf("Congratulations! Your new Hugo site was created in %s.\n\n", createpath)
- r.Println(c.newSiteNextStepsText(createpath, format))
+ r.Printf("Congratulations! Your new Hugo project was created in %s.\n\n", createpath)
+ r.Println(c.newProjectNextStepsText(createpath, format))
return nil
},
You can also specify the kind with ` + "`-k KIND`" + `.
-If archetypes are provided in your theme or site, they will be used.
+If archetypes are provided in your theme or project, they will be used.
-Ensure you run this within the root directory of your site.`
+Ensure you run this within the root directory of your project.`
cmd.RunE = nil
return nil
return nil
}
-func (c *newCommand) newSiteNextStepsText(path string, format string) string {
+func (c *newCommand) newProjectNextStepsText(path string, format string) string {
format = strings.ToLower(format)
var nextStepsText bytes.Buffer
func (c *serverCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "Start the embedded web server"
- cmd.Long = `Hugo provides its own webserver which builds and serves the site.
+ cmd.Long = `Hugo provides its own webserver which builds and serves the project.
While hugo server is high performance, it is a webserver with limited options.
The ` + "`" + `hugo server` + "`" + ` command will by default write and serve files from disk, but
faster in some cases, but it will consume more memory.
By default hugo will also watch your files for any changes you make and
-automatically rebuild the site. It will then live reload any open browser pages
-and push the latest content to them. As most Hugo sites are built in a fraction
+automatically rebuild the project. It will then live reload any open browser pages
+and push the latest content to them. As most Hugo projects are built in a fraction
of a second, you will be able to save and see your changes nearly instantly.`
cmd.Aliases = []string{"serve"}
cmd.Flags().BoolVarP(&c.serverAppend, "appendPort", "", true, "append port to baseURL")
cmd.Flags().BoolVar(&c.disableLiveReload, "disableLiveReload", false, "watch without enabling live browser reload on rebuild")
cmd.Flags().BoolVarP(&c.navigateToChanged, "navigateToChanged", "N", false, "navigate to changed content file on live browser reload")
- cmd.Flags().BoolVarP(&c.openBrowser, "openBrowser", "O", false, "open the site in a browser after server startup")
+ cmd.Flags().BoolVarP(&c.openBrowser, "openBrowser", "O", false, "open the project in a browser after server startup")
cmd.Flags().BoolVar(&c.renderStaticToDisk, "renderStaticToDisk", false, "serve static files from disk and dynamic files from memory")
cmd.Flags().BoolVar(&c.disableFastRender, "disableFastRender", false, "enables full re-renders on changes")
cmd.Flags().BoolVar(&c.disableBrowserError, "disableBrowserError", false, "do not show build errors in the browser")
}
func (l *logAdapter) idfInfoStatement(what, id, format string) string {
- return fmt.Sprintf("\nYou can suppress this %s by adding the following to your site configuration:\nignoreLogs = ['%s']", what, id)
+ return fmt.Sprintf("\nYou can suppress this %s by adding the following to your project configuration:\nignoreLogs = ['%s']", what, id)
}
func (l *logAdapter) Trace(s logg.StringFunc) {
// Legacy privacy values.
if c.Privacy.Twitter.Disable {
- hugo.DeprecateWithLogger("site config key privacy.twitter.disable", "Use privacy.x.disable instead.", "v0.141.0", logger.Logger())
+ hugo.DeprecateWithLogger("project config key privacy.twitter.disable", "Use privacy.x.disable instead.", "v0.141.0", logger.Logger())
c.Privacy.X.Disable = c.Privacy.Twitter.Disable
}
if c.Privacy.Twitter.EnableDNT {
- hugo.DeprecateWithLogger("site config key privacy.twitter.enableDNT", "Use privacy.x.enableDNT instead.", "v0.141.0", logger.Logger())
+ hugo.DeprecateWithLogger("project config key privacy.twitter.enableDNT", "Use privacy.x.enableDNT instead.", "v0.141.0", logger.Logger())
c.Privacy.X.EnableDNT = c.Privacy.Twitter.EnableDNT
}
if c.Privacy.Twitter.Simple {
- hugo.DeprecateWithLogger("site config key privacy.twitter.simple", "Use privacy.x.simple instead.", "v0.141.0", logger.Logger())
+ hugo.DeprecateWithLogger("project config key privacy.twitter.simple", "Use privacy.x.simple instead.", "v0.141.0", logger.Logger())
c.Privacy.X.Simple = c.Privacy.Twitter.Simple
}
// Legacy services values.
if c.Services.Twitter.DisableInlineCSS {
- hugo.DeprecateWithLogger("site config key services.twitter.disableInlineCSS", "Use services.x.disableInlineCSS instead.", "v0.141.0", logger.Logger())
+ hugo.DeprecateWithLogger("project config key services.twitter.disableInlineCSS", "Use services.x.disableInlineCSS instead.", "v0.141.0", logger.Logger())
c.Services.X.DisableInlineCSS = c.Services.Twitter.DisableInlineCSS
}
)
if c.Markup.Goldmark.RenderHooks.Image.EnableDefault != nil {
alternative := "Use markup.goldmark.renderHooks.image.useEmbedded instead." + " " + alternativeDetails
- hugo.DeprecateWithLogger("site config key markup.goldmark.renderHooks.image.enableDefault", alternative, "0.148.0", logger.Logger())
+ hugo.DeprecateWithLogger("project config key markup.goldmark.renderHooks.image.enableDefault", alternative, "0.148.0", logger.Logger())
if *c.Markup.Goldmark.RenderHooks.Image.EnableDefault {
c.Markup.Goldmark.RenderHooks.Image.UseEmbedded = gc.RenderHookUseEmbeddedFallback
} else {
}
if c.Markup.Goldmark.RenderHooks.Link.EnableDefault != nil {
alternative := "Use markup.goldmark.renderHooks.link.useEmbedded instead." + " " + alternativeDetails
- hugo.DeprecateWithLogger("site config key markup.goldmark.renderHooks.link.enableDefault", alternative, "0.148.0", logger.Logger())
+ hugo.DeprecateWithLogger("project config key markup.goldmark.renderHooks.link.enableDefault", alternative, "0.148.0", logger.Logger())
if *c.Markup.Goldmark.RenderHooks.Link.EnableDefault {
c.Markup.Goldmark.RenderHooks.Link.UseEmbedded = gc.RenderHookUseEmbeddedFallback
} else {
gc.RenderHookUseEmbeddedNever,
}
if !slices.Contains(renderHookUseEmbeddedModes, c.Markup.Goldmark.RenderHooks.Image.UseEmbedded) {
- return fmt.Errorf("site config markup.goldmark.renderHooks.image.useEmbedded must be one of %s", helpers.StringSliceToList(renderHookUseEmbeddedModes, "or"))
+ return fmt.Errorf("project config markup.goldmark.renderHooks.image.useEmbedded must be one of %s", helpers.StringSliceToList(renderHookUseEmbeddedModes, "or"))
}
if !slices.Contains(renderHookUseEmbeddedModes, c.Markup.Goldmark.RenderHooks.Link.UseEmbedded) {
- return fmt.Errorf("site config markup.goldmark.renderHooks.link.useEmbedded must be one of %s", helpers.StringSliceToList(renderHookUseEmbeddedModes, "or"))
+ return fmt.Errorf("project config markup.goldmark.renderHooks.link.useEmbedded must be one of %s", helpers.StringSliceToList(renderHookUseEmbeddedModes, "or"))
}
c.C = &ConfigCompiled{
)
//lint:ignore ST1005 end user message.
-var ErrNoConfigFile = errors.New("Unable to locate config file or config directory. Perhaps you need to create a new site.\n Run `hugo help new` for details.\n")
+var ErrNoConfigFile = errors.New("Unable to locate config file or config directory. Perhaps you need to create a new project.\n Run `hugo help new` for details.\n")
func LoadConfig(d ConfigSourceDescriptor) (configs *Configs, err error) {
defer func() {
func (l configLoader) normalizeCfg(cfg config.Provider) error {
if b, ok := cfg.Get("minifyOutput").(bool); ok {
- hugo.Deprecate("site config minifyOutput", "Use minify.minifyOutput instead.", "v0.150.0")
+ hugo.Deprecate("project config minifyOutput", "Use minify.minifyOutput instead.", "v0.150.0")
if b {
cfg.Set("minify.minifyOutput", true)
}
} else if b, ok := cfg.Get("minify").(bool); ok {
- hugo.Deprecate("site config minify", "Use minify.minifyOutput instead.", "v0.150.0")
+ hugo.Deprecate("project config minify", "Use minify.minifyOutput instead.", "v0.150.0")
if b {
cfg.Set("minify", hmaps.Params{"minifyOutput": true})
}
)
const (
- // DefaultArchetypeTemplateTemplate is the template used in 'hugo new site'
+ // DefaultArchetypeTemplateTemplate is the template used in 'hugo new project'
// and the template we use as a fall back.
DefaultArchetypeTemplateTemplate = `---
title: "{{ replace .File.ContentBaseName "-" " " | title }}"
"github.com/spf13/afero"
)
-//go:embed all:site/*
-var siteFs embed.FS
+//go:embed all:project/*
+var projectFs embed.FS
//go:embed all:theme/*
var themeFs embed.FS
format = strings.ToLower(format)
- siteConfig := map[string]any{
+ projectConfig := map[string]any{
"baseURL": "https://example.org/",
"languageCode": "en-US",
- "title": "My New Hugo Site",
+ "title": "My New Hugo Project",
"menus": map[string]any{
"main": []any{
map[string]any{
},
}
- err := createSiteConfig(sourceFs, createpath, siteConfig, format)
+ err := createProjectConfig(sourceFs, createpath, projectConfig, format)
if err != nil {
return err
}
return copyFiles(createpath, sourceFs, themeFs)
}
-// CreateSite creates a site skeleton.
-func CreateSite(createpath string, sourceFs afero.Fs, force bool, format string) error {
+// CreateProject creates a project skeleton.
+func CreateProject(createpath string, sourceFs afero.Fs, force bool, format string) error {
format = strings.ToLower(format)
if exists, _ := helpers.Exists(createpath, sourceFs); exists {
if isDir, _ := helpers.IsDir(createpath, sourceFs); !isDir {
return errors.New(createpath + " already exists and is not empty. See --force.")
case !isEmpty && force:
var all []string
- fs.WalkDir(siteFs, ".", func(path string, d fs.DirEntry, err error) error {
+ fs.WalkDir(projectFs, ".", func(path string, d fs.DirEntry, err error) error {
if d.IsDir() && path != "." {
all = append(all, path)
}
}
}
- siteConfig := map[string]any{
+ projectConfig := map[string]any{
"baseURL": "https://example.org/",
- "title": "My New Hugo Site",
+ "title": "My New Hugo Project",
"languageCode": "en-us",
}
- err := createSiteConfig(sourceFs, createpath, siteConfig, format)
+ err := createProjectConfig(sourceFs, createpath, projectConfig, format)
if err != nil {
return err
}
return err
}
- return copyFiles(createpath, sourceFs, siteFs)
+ return copyFiles(createpath, sourceFs, projectFs)
}
func copyFiles(createpath string, sourceFs afero.Fs, skeleton embed.FS) error {
})
}
-func createSiteConfig(fs afero.Fs, createpath string, in map[string]any, format string) (err error) {
+func createProjectConfig(fs afero.Fs, createpath string, in map[string]any, format string) (err error) {
var buf bytes.Buffer
err = parser.InterfaceToConfig(in, metadecoders.FormatFromString(format), &buf)
if err != nil {
"Parent: |",
)
b.AssertFileContent("public/nn/index.html",
- "Site title nn|", // from site config.
+ "Site title nn|", // from project config.
"Lastmod: 2024-10-01",
"RenderString with shortcode: myshortcode.html",
)
files := `
-- hugo.toml --
baseURL = 'http://example.org/'
-title = 'My New Hugo Site'
+title = 'My New Hugo Project'
timeout = 600000 # ten minutes in case we want to pause and debug
Author page: {{ $withParam.Param "author.name" }}
Author name page string: {{ $withStringParam.Param "author.name" }}|
Author page string: {{ $withStringParam.Param "author" }}|
-Author site config: {{ $noParam.Param "author.name" }}
+Author project config: {{ $noParam.Param "author.name" }}
-- content/withparam.md --
+++
"Author page: Ernest Miller Hemingway",
"Author name page string: Kurt Vonnegut|",
"Author page string: Jo Nesbø|",
- "Author site config: Kurt Vonnegut")
+ "Author project config: Kurt Vonnegut")
}
func TestGoldmark(t *testing.T) {
func TestGetPageIndexIndex(t *testing.T) {
files := `
-- hugo.toml --
-disableKinds = ["taxonomy", "term"]
+disableKinds = ["taxonomy", "term"]
-- content/mysect/index/index.md --
---
title: "Mysect Index"
`)
b.AssertFileContent("public/s1/p2/index.html", `
-../p2: p2_root|
+../p2: p2_root|
../p2.md: p2_root|
p1/index.md: p1|
../s2/p3/index.md: p3|
baseURL = "http://example.org/"
languageCode = "en-us"
defaultContentLanguage = "ru"
-title = "My New Hugo Site"
+title = "My New Hugo Project"
uglyurls = true
[languages]
files := `
-- hugo.toml --
baseURL = "http://example.org/"
-title = "My New Hugo Site"
+title = "My New Hugo Project"
-- content/docs/1.md --
---
title: docs1
func TestRebuildBaseof(t *testing.T) {
files := `
-- hugo.toml --
-title = "Hugo Site"
+title = "Hugo Project"
baseURL = "https://example.com"
disableKinds = ["term", "taxonomy"]
disableLiveReload = true
{{ end }}
`
testRebuildBothWatchingAndRunning(t, files, func(b *IntegrationTestBuilder) {
- b.AssertFileContent("public/index.html", "Baseof: Hugo Site|", "Home: Hugo Site||")
+ b.AssertFileContent("public/index.html", "Baseof: Hugo Project|", "Home: Hugo Project||")
b.EditFileReplaceFunc("layouts/baseof.html", func(s string) string {
return strings.Replace(s, "Baseof", "Baseof Edited", 1)
}).Build()
- b.AssertFileContent("public/index.html", "Baseof Edited: Hugo Site|", "Home: Hugo Site||")
+ b.AssertFileContent("public/index.html", "Baseof Edited: Hugo Project|", "Home: Hugo Project||")
})
}
files := `
-- hugo.toml --
-title = "Hugo Site"
+title = "Hugo Project"
baseURL = "https://example.com"
disableKinds = ["term", "taxonomy", "sitemap", "robotstxt", "404"]
disableLiveReload = true
files := `
-- hugo.toml --
-title = "Hugo Site"
+title = "Hugo Project"
baseURL = "https://example.com"
disableKinds = ["term", "taxonomy"]
disableLiveReload = true
files := `
-- hugo.toml --
-title = "Hugo Site"
+title = "Hugo Project"
baseURL = "https://example.com"
disableKinds = ["term", "taxonomy"]
disableLiveReload = true
files := `
-- hugo.toml --
-title = "Hugo Site"
+title = "Hugo Project"
baseURL = "https://example.com"
disableKinds = ["term", "taxonomy"]
disableLiveReload = true
Site.Lastmod: {{ .Site.Lastmod.Format "2006-01-02" }}|
Paginate: {{ range (.Paginate .Site.RegularPages).Pages }}{{ .RelPermalink }}|{{ .Title }}|{{ end }}$
-- layouts/single.html --
-Single: .Site: {{ .Site }}
+Single: .Site: {{ .Site }}
Single: {{ .Title }}|{{ .Content }}|
Single Partial Cached: {{ partialCached "pcached" . }}|
Page.Lastmod: {{ .Lastmod.Format "2006-01-02" }}|
b := TestRunning(t, files, TestOptWarn())
b.AssertNoRenderShortcodesArtifacts()
- b.AssertLogContains(filepath.ToSlash("WARN .RenderShortcodes detected inside HTML block in \"/content/p1.md\"; this may not be what you intended, see https://gohugo.io/methods/page/rendershortcodes/#limitations\nYou can suppress this warning by adding the following to your site configuration:\nignoreLogs = ['warning-rendershortcodes-in-html']"))
+ b.AssertLogContains(filepath.ToSlash("WARN .RenderShortcodes detected inside HTML block in \"/content/p1.md\"; this may not be what you intended, see https://gohugo.io/methods/page/rendershortcodes/#limitations\nYou can suppress this warning by adding the following to your project configuration:\nignoreLogs = ['warning-rendershortcodes-in-html']"))
b.AssertFileContent("public/p1/index.html", "<div>Hello <b>world</b>. Some **bold** text. Some Unicode: 神真美好.\n</div>")
b.EditFileReplaceAll("content/p2.md", "Hello", "Hello Edited").Build()
b.AssertNoRenderShortcodesArtifacts()
if attributeKey == asciiDocDiagramCacheImagesOptionKey {
a.Cfg.Logger.Warnf(
- "The %q Asciidoctor attribute is fixed and cannot be modified. To disable caching of both image and metadata files, set markup.asciidocext.attributes.diagram-nocache-option to true in your site configuration.",
+ "The %q Asciidoctor attribute is fixed and cannot be modified. To disable caching of both image and metadata files, set markup.asciidocext.attributes.diagram-nocache-option to true in your project configuration.",
attributeKey,
)
continue
if attributeKey == asciiDocDiagramCacheDirKey {
a.Cfg.Logger.Warnf(
- "The %q Asciidoctor attribute is fixed and cannot be modified. To change the cache location, modify caches.misc.dir in your site configuration.",
+ "The %q Asciidoctor attribute is fixed and cannot be modified. To change the cache location, modify caches.misc.dir in your project configuration.",
attributeKey,
)
continue
// ProviderConfig configures a new Provider.
type ProviderConfig struct {
- Conf config.AllProvider // Site config
+ Conf config.AllProvider // Project config
ContentFs afero.Fs
Logger loggers.Logger
Exec *hexec.Exec
b := hugolib.Test(t, files, hugolib.TestOptWarn())
b.AssertFileContent("public/p1/index.html", "<!-- raw HTML omitted -->")
- b.AssertLogContains("WARN Raw HTML omitted while rendering \"/content/p1.md\"; see https://gohugo.io/getting-started/configuration-markup/#rendererunsafe\nYou can suppress this warning by adding the following to your site configuration:\nignoreLogs = ['warning-goldmark-raw-html']")
+ b.AssertLogContains("WARN Raw HTML omitted while rendering \"/content/p1.md\"; see https://gohugo.io/getting-started/configuration-markup/#rendererunsafe\nYou can suppress this warning by adding the following to your project configuration:\nignoreLogs = ['warning-goldmark-raw-html']")
b = hugolib.Test(t, strings.ReplaceAll(files, "markup.goldmark.renderer.unsafe = false", "markup.goldmark.renderer.unsafe = true"), hugolib.TestOptWarn())
b.AssertFileContent("public/p1/index.html", "! <!-- raw HTML omitted -->")
b := hugolib.Test(t, files, hugolib.TestOptWarn())
b.AssertFileContent("public/p1/index.html", "<!-- raw HTML omitted -->")
- b.AssertLogContains("WARN Raw HTML omitted while rendering \"/content/p1.md\"; see https://gohugo.io/getting-started/configuration-markup/#rendererunsafe\nYou can suppress this warning by adding the following to your site configuration:\nignoreLogs = ['warning-goldmark-raw-html']")
+ b.AssertLogContains("WARN Raw HTML omitted while rendering \"/content/p1.md\"; see https://gohugo.io/getting-started/configuration-markup/#rendererunsafe\nYou can suppress this warning by adding the following to your project configuration:\nignoreLogs = ['warning-goldmark-raw-html']")
b = hugolib.Test(t, strings.ReplaceAll(files, "markup.goldmark.renderer.unsafe = false", "markup.goldmark.renderer.unsafe = true"), hugolib.TestOptWarn())
b.AssertFileContent("public/p1/index.html", "! <!-- raw HTML omitted -->")
kn := "precision"
if vv, found := vm[ko]; found {
hugo.Deprecate(
- fmt.Sprintf("site config key minify.tdewolff.%s.%s", key, ko),
+ fmt.Sprintf("project config key minify.tdewolff.%s.%s", key, ko),
fmt.Sprintf("Use config key minify.tdewolff.%s.%s instead.", key, kn),
"v0.150.0",
)
kn := "keepspecialcomments"
if vv, found := vm[ko]; found {
hugo.Deprecate(
- fmt.Sprintf("site config key minify.tdewolff.html.%s", ko),
+ fmt.Sprintf("project config key minify.tdewolff.html.%s", ko),
fmt.Sprintf("Use config key minify.tdewolff.html.%s instead.", kn),
"v0.150.0",
)
kn := "version"
if vv, found := vm[ko]; found {
hugo.Deprecate(
- fmt.Sprintf("site config key minify.tdewolff.css.%s", ko),
+ fmt.Sprintf("project config key minify.tdewolff.css.%s", ko),
fmt.Sprintf("Use config key minify.tdewolff.css.%s instead.", kn),
"v0.150.0",
)
} else {
// Create one.
name := "project"
- // Use the Hugo site's folder name as the default name.
+ // Use the Hugo project's folder name as the default name.
// The owner can change it later.
rfi, err := sourceFs.Stat("")
if err == nil {
var smc = newMenuCache()
// MenuEntry represents a menu item defined in either Page front matter
-// or in the site config.
+// or in the project config.
type MenuEntry struct {
// The menu entry configuration.
MenuConfig
func (m *MenuEntry) URL() string {
// Check page first.
// In Hugo 0.86.0 we added `pageRef`,
- // a way to connect menu items in site config to pages.
+ // a way to connect menu items in project config to pages.
// This means that you now can have both a Page
// and a configured URL.
// Having the configured URL as a fallback if the Page isn't found
Rotate int
// Used to fill any transparency.
- // When set in site config, it's used when converting to a format that does
+ // When set in project config, it's used when converting to a format that does
// not support transparency.
// When set per image operation, it's used even for formats that does support
// transparency.
// Returns a map of all the data inside /data.
Data() map[string]any
- // Returns the site config.
+ // Returns the project config.
Config() SiteConfig
// BuildDrafts is deprecated and will be removed in a future release.
# Test the config command.
hugo config -h
-stdout 'Display site configuration'
+stdout 'Display project configuration'
hugo config
# Test files
-- hugo.toml --
baseURL="https://example.com/"
-title="My New Hugo Site"
+title="My New Hugo Project"
-- hugo.toml --
baseURL="https://example.com/"
-title="My New Hugo Site"
+title="My New Hugo Project"
# Test the import + import jekyll command.
-hugo import -h
-stdout 'Import a site from another system'
+hugo import -h
+stdout 'Import a project from another system'
hugo import jekyll -h
stdout 'hugo import from Jekyll\.'
-hugo import jekyll myjekyllsite myhugosite
-checkfilecount 1 myhugosite/content/post
-grep 'example\.org' myhugosite/hugo.yaml
+hugo import jekyll my-jekyll-project my-hugo-project
+checkfilecount 1 my-hugo-project/content/post
+grep 'example\.org' my-hugo-project/hugo.yaml
-# A simple Jekyll site.
--- myjekyllsite/_posts/2012-01-18-hello-world.markdown --
+# A simple Jekyll project.
+-- my-jekyll-project/_posts/2012-01-18-hello-world.markdown --
---
layout: post
title: "Hello World"
# Test the new command.
-hugo new site -h
-stdout 'Create a new site at the specified path.'
-hugo new site my-yaml-site --format yml
-checkfile my-yaml-site/hugo.yml
-hugo new site mysite -f
-stdout 'Congratulations! Your new Hugo site was created in'
-cd mysite
+hugo new project -h
+stdout 'Create a new project at the specified path.'
+hugo new project my-yaml-project --format yml
+checkfile my-yaml-project/hugo.yml
+hugo new project my-project -f
+stdout 'Congratulations! Your new Hugo project was created in'
+cd my-project
checkfile archetypes/default.md
checkfile hugo.toml
exists assets
hugo new theme -h
stdout 'Create a new theme with the specified name in the ./themes directory.'
-hugo new theme mytheme --format yml
+hugo new theme my-theme --format yml
stdout 'Creating new theme'
! exists resources
cd themes
-cd mytheme
+cd my-theme
checkfile archetypes/default.md
checkfile assets/css/main.css
checkfile assets/js/main.js
exists data
exists i18n
-cd $WORK/mysite
+cd $WORK/my-project
hugo new -h
stdout 'Create a new content file.'
checkfile content/posts/my-first-post.md
cd ..
-cd myexistingsite
-hugo new post/foo.md -t mytheme
+cd my-existing-project
+hugo new post/foo.md -t my-theme
grep 'Dummy content' content/post/foo.md
cd $WORK
# In the three archetype format tests below, skip Windows testing to avoid
# newline differences when comparing to golden.
-hugo new site json-site --format json
-[!windows] cmp json-site/archetypes/default.md archetype-golden-json.md
+hugo new project json-project --format json
+[!windows] cmp json-project/archetypes/default.md archetype-golden-json.md
-hugo new site toml-site --format toml
-[!windows] cmp toml-site/archetypes/default.md archetype-golden-toml.md
+hugo new project toml-project --format toml
+[!windows] cmp toml-project/archetypes/default.md archetype-golden-toml.md
-hugo new site yaml-site --format yaml
-[!windows] cmp yaml-site/archetypes/default.md archetype-golden-yaml.md
+hugo new project yaml-project --format yaml
+[!windows] cmp yaml-project/archetypes/default.md archetype-golden-yaml.md
--- myexistingsite/hugo.toml --
-theme = "mytheme"
--- myexistingsite/content/p1.md --
+-- my-existing-project/hugo.toml --
+theme = "my-theme"
+-- my-existing-project/content/p1.md --
---
title: "P1"
---
--- myexistingsite/themes/mytheme/hugo.toml --
--- myexistingsite/themes/mytheme/archetypes/post.md --
+-- my-existing-project/themes/my-theme/hugo.toml --
+-- my-existing-project/themes/my-theme/archetypes/post.md --
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
-hugo new site myblog
-cd myblog
+hugo new project my-project
+cd my-project
hugo new content --kind post post/first-post.md
! exists resources
grep 'draft = true' content/post/first-post.md
# Issue 12599
cd $WORK
-hugo new site --format toml --force issue-12599
+hugo new project --format toml --force issue-12599
cp hugo.toml issue-12599/hugo.toml
cd issue-12599
hugo new content content/s1/2099-12-31-p1.md
# Test the hugo version command.
hugo -h
-stdout 'hugo is the main command, used to build your Hugo site'
+stdout 'hugo is the main command, used to build your Hugo project'
hugo version
stdout 'hugo v.* BuildDate=unknown'
# Test the deploy command.
hugo deploy -h
-stdout 'Deploy your site to a cloud provider'
+stdout 'Deploy your project to a cloud provider'
mkdir mybucket
hugo deploy --target mydeployment --invalidateCDN=false
grep 'hello' mybucket/index.html
switch v := params[0].(type) {
case map[string]any: // created with collections.Dictionary
return mapToQueryString(v)
- case hmaps.Params: // site configuration or page parameters
+ case hmaps.Params: // project configuration or page parameters
return mapToQueryString(v)
case []string:
return stringSliceToQueryString(v)
b, err := hugolib.TestE(t, files)
b.Assert(err, qt.IsNotNil)
- b.AssertLogMatches(`ERROR a\nYou can suppress this error by adding the following to your site configuration:\nignoreLogs = \['error-a'\]`)
+ b.AssertLogMatches(`ERROR a\nYou can suppress this error by adding the following to your project configuration:\nignoreLogs = \['error-a'\]`)
b.AssertLogMatches(`ERROR D`)
b.AssertLogMatches(`! ERROR C`)
b.AssertLogMatches(`! ERROR c`)
{{ if not site.Config.Privacy.GoogleAnalytics.Disable }}
{{- with site.Config.Services.GoogleAnalytics.ID }}
{{- if strings.HasPrefix (lower .) "ua-" }}
- {{- warnf "Google Analytics 4 (GA4) replaced Google Universal Analytics (UA) effective 1 July 2023. See https://support.google.com/analytics/answer/11583528. Create a GA4 property and data stream, then replace the Google Analytics ID in your site configuration with the new value." }}
+ {{- warnf "Google Analytics 4 (GA4) replaced Google Universal Analytics (UA) effective 1 July 2023. See https://support.google.com/analytics/answer/11583528. Create a GA4 property and data stream, then replace the Google Analytics ID in your project configuration with the new value." }}
{{- else }}
<script async src="https://www.googletagmanager.com/gtag/js?id={{ . }}"></script>
<script>
{{ .Title }}
`
- // Test A: Exclude all pages via site config.
+ // Test A: Exclude all pages via project config.
b := hugolib.Test(t, files)
b.AssertFileContentExact("public/sitemap.xml",
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">\n \n</urlset>\n",
)
- // Test B: Include all pages via site config.
+ // Test B: Include all pages via project config.
files_b := strings.ReplaceAll(files, "disable = true", "disable = false")
b = hugolib.Test(t, files_b)
b.AssertFileContentExact("public/sitemap.xml",
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">\n <url>\n <loc>/p1/</loc>\n </url><url>\n <loc>/p2/</loc>\n </url>\n</urlset>\n",
)
- // Test C: Exclude all pages via site config, but include p1 via front matter.
+ // Test C: Exclude all pages via project config, but include p1 via front matter.
files_c := strings.ReplaceAll(files, "p1_disable: foo", "disable: false")
b = hugolib.Test(t, files_c)
b.AssertFileContentExact("public/sitemap.xml",
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">\n <url>\n <loc>/p1/</loc>\n </url>\n</urlset>\n",
)
- // Test D: Include all pages via site config, but exclude p1 via front matter.
+ // Test D: Include all pages via project config, but exclude p1 via front matter.
files_d := strings.ReplaceAll(files_b, "p1_disable: foo", "disable: true")
b = hugolib.Test(t, files_d)
b.AssertFileContentExact("public/sitemap.xml",