Compare commits

...

91 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen 2a663b1938 Fix TailwindCSS related server rebuild issue
Fixes #13316
2025-01-29 15:48:19 +01:00
Joe Mooring e08d9af21e markup/goldmark: Trim space from blockquote render hook text
Closes #13302
2025-01-24 19:58:45 +01:00
Bjørn Erik Pedersen cd7dc7a372 Fix some server rebuild issues for non-HTML custom output formats
The failing test case here is

* A custom search output format defined on the home page, marked as `noAlternative` and not `permalinkable`
* In fast render mode, when making a change to a data source for that search output format, the JSON file was not refreshed.

There are variants of the above, but the gist of it is:

* The change set was correctly determined, but since the search JSON file was not in the recently visited browser stack, we skipped rendering it.

Running with `hugo server --disableFastRender` would be a workaround for the above.

This commit fixes this by:

* Adding a check for the HTTP request header `Sec-Fetch-Mode = navigation` to the condition for if we should track server request as a user navigation (and not e.g. a HTTP request for a linked CSS stylesheet).
* Making sure that we compare against the real relative URL for non-permalinkable output formats.

Fixes #13014
2025-01-24 17:27:02 +01:00
Guilherme Soares c939c33fd3 parser/pageparser: Don't allow parameters after closing tag in shortcodes
Problem:
Previously, the following self-closing shortcode syntax was incorrectly allowed:
{{% sc / param %}}

Solution:
Only allow parameters before the self-closing tag
2025-01-24 15:31:44 +01:00
Bjørn Erik Pedersen bb7b3d3cdb Fix cascade with overlapping sections
Fixes #12465
2025-01-24 15:25:54 +01:00
Joe Mooring 873a5cda1a tpl/tplimpl: Improve shortcode test coverage 2025-01-24 09:10:45 +01:00
Joe Mooring f42a4b6af5 tpl/tplimpl: Deprecate gist shortcode
Closes #13211
2025-01-23 20:12:36 +01:00
Bjørn Erik Pedersen a5637831cd resources: Remove conditional used for debugging 2025-01-23 17:53:38 +01:00
Bjørn Erik Pedersen 68586c891c resources: Add responseHeaders option to resources.GetRemote
* These response headers will be included in `.Data.Headers` if found.
* The header name matching is case insensitive.
* `Data.Headers` is of type `map[string][]string`
* In most cases there will be only one value per header key, but e.g. `Set-Cookie` commonly has multiple values.

Fixes #12521
2025-01-23 15:20:03 +01:00
Bjørn Erik Pedersen 51bb2fedab tpl/tplimpl: Skip TestTemplateFuncsExamples on s390x
Closes #13204
2025-01-23 10:18:43 +01:00
Bjørn Erik Pedersen 43307b07f8 Merge commit '346b60358dd8ec2ca228e6635bff9d7914b398b7' 2025-01-23 09:47:46 +01:00
Bjørn Erik Pedersen 346b60358d Squashed 'docs/' changes from 4429eeeea..73a01565c
73a01565c Remove comment shortcode documentation
0ca7ccd30 Replace usage of comment shortcode with HTML comments
fe10d9899 Remove expired new-in labels
11e89dfcb [editorial] Link to proper render-hook page in relref.md
11a581c2f netlify: Hugo 0.142.0
1a4fcf7f7 Miscellaneous edits
2c7a3165f Markdown linting and cleanup
69d7a781b Replace links to glossary terms with custom render hook syntax
441752d2d Refactor glossary lookup portion of link render hook
80109a14f Fix glossary term linking for plural form
cd95f0f34 Update link render hook to support glossary links
53eadb430 Remove the glossary template
1d40a7f3b Improve transform.ToMath examples
586970df2 Misc edits
6a06a8de7 Add glossary link shortcode
4171c0eb7 Improve description of masking with non-transparent images
41c8feb64 Fix example of image.Mask filter
704a81656 Add alignx option to images.Text usage example
7c03eb0cc Clarify context in example of using the try statement
56d9c9b71 Refactor glossary of terms
042a6846b Add expiry dates to deprecated methods pages
365ab345f Remove services key from instagram shortcode page
b7fe31e07 Reorder options list for images.Text filter
8051ff818 Format directory names, file names, and file paths as code
d09a14623 Update version refs for Hugo and Dart Sass
3bb006974 Add NODE_VERSION to Netlify config examples
3a0f2531e Fix typo
7e3198eaf Fix typo
cf56452a3 Fix typo
a9f51d13e Fix typo
82bfdd8c3 Fix typo
a5c41a053 Fix typo
abcfed7a5 Fix typo
8c1debf3a Remove outdated new-in badges
809ddf9ef Update theme
63867d56f Use warnf instead of errorf in try-catch example
dee3e5f09 Update theme
9791f7057 Remove TODO from comment shortcode examples
a346ca1fd Elevate embedded shortcode documentation to its own section
8fa19b50f hugoreleaser.toml =>  hugoreleaser.yaml
575d60345 Update docs for v0.141.0
a0a442d62 netlify: Hugo 0.141.0
6667cbcd8 Merge commit '81a7b6390036138356773c87a886679c81c524e1'
f36fc013e docs: Regen CLI docs
365a47ded tpl/images: Change signature of images.QR to images.QR TEXT OPTIONS
ae8f8af0a images.Text: Add "alignx" option for horizontal alignment
8f45ccca6 docs: Regen CLI docs
f0e6304f4 Merge commit 'e9fbadacc3f09191e2e19f112a49777eeb8df06c'
cb9bec2b2 tpl/images: Add images.QR function

git-subtree-dir: docs
git-subtree-split: 73a01565c5
2025-01-23 09:46:02 +01:00
Bjørn Erik Pedersen 7f0f50b133 Make cascade front matter order deterministic
Fixes #12594
2025-01-23 09:45:47 +01:00
Joe Mooring 77a8e347bc tpl/tplimpl: Deprecate comment shortcode 2025-01-22 19:38:02 +01:00
Patrice Chalin f704d75699 markup/goldmark: Fix typo in func comment 2025-01-22 14:57:24 +01:00
hugoreleaser 9d765e1b99 releaser: Prepare repository for 0.143.0-DEV
[ci skip]
2025-01-22 12:35:08 +00:00
hugoreleaser 1f746a8724 releaser: Bump versions for release of 0.142.0
[ci skip]
2025-01-22 12:20:52 +00:00
Bjørn Erik Pedersen 6aa72acaf9 Fix render hook's PlainText with typographer extension enabled
Fixes #13286
Fixes #13292
2025-01-22 12:49:25 +01:00
Bjørn Erik Pedersen 9885e7020d Improve assert 2025-01-22 09:44:26 +01:00
Bjørn Erik Pedersen 91101d24f2 Improve assertions 2025-01-22 09:44:26 +01:00
Bjørn Erik Pedersen 637995ba8f Also handle inline HTML comments 2025-01-22 09:44:26 +01:00
Bjørn Erik Pedersen f1de5d2a04 Do not warn on potentially unsafe HTML comments when unsafe=false
We will still not render these comments, so from a safety perspective this is the same, but HTML comments are very common also inside Markdown and too useful to throw away.

Updates #13278
2025-01-22 09:44:26 +01:00
W. Michael Petullo 4b0c194fb3 Fix build with Go 1.24
Go 1.24 provides stricter checking that forbids passing a variable as
a format string to Printf-family functions with no other arguments. Remove
instances of this. See also:

https://tip.golang.org/doc/go1.24#vet

Signed-off-by: W. Michael Petullo <mike@flyn.org>
2025-01-21 11:10:03 +01:00
Joe Mooring 8de4ffb294 tpl/tplimpl: Fix context in shortcode error messages
Fixes #13279
2025-01-20 16:17:55 +01:00
Bjørn Erik Pedersen 1f5a15aba0 resources: Fix 2 image file cache key issues
* Always include the content hash in the cache key for unprocessed images.
* Always include the image config hash in the cache key.

This is also a major cleanup/simplification of the implementation in this area.

Note that this, unfortunately, forces new hashes/filenames for generated images.

Fixes #13273
Fixes #13272
2025-01-18 12:23:18 +01:00
Nicolas Friedli 8897113666 tpl: Add loading attribute to qr shortcode 2025-01-17 19:06:54 +01:00
hugoreleaser e91d3cff98 releaser: Prepare repository for 0.142.0-DEV
[ci skip]
2025-01-16 13:26:52 +00:00
hugoreleaser e7bd51698e releaser: Bump versions for release of 0.141.0
[ci skip]
2025-01-16 13:11:18 +00:00
Bjørn Erik Pedersen 1fad3832a9 tpl/tplimpl: Simplify some test assertions 2025-01-16 11:29:24 +01:00
Jack Baldry 8b52626915 common/paths: Fix docstring 2025-01-16 10:58:18 +01:00
Bjørn Erik Pedersen 81a7b63900 Squashed 'docs/' changes from f0f4bcb24..4429eeeea
4429eeeea Update image render hooks examples to conform with Commonmark
5391dddea Add class attribute to heading render hook examples

git-subtree-dir: docs
git-subtree-split: 4429eeeea8
2025-01-16 10:35:07 +01:00
Bjørn Erik Pedersen 5c5508817f Merge commit '81a7b6390036138356773c87a886679c81c524e1' 2025-01-16 10:35:07 +01:00
Bjørn Erik Pedersen 88ecc3b753 docs: Regen CLI docs 2025-01-16 10:34:52 +01:00
Joe Mooring 1191467c05 tpl/tplimpl: Deprecate twitter shortcode in favor of x shortcode
Closes #13214
2025-01-16 10:33:34 +01:00
Bjørn Erik Pedersen 60c24fc5ee commands: Fix spelling in comment 2025-01-15 22:31:52 +01:00
Bjørn Erik Pedersen 41137077bc commands: Set up the glboal logger early
Fixes #13265
2025-01-15 22:31:08 +01:00
Bjørn Erik Pedersen 5bb1564575 commands: Add --printZero to the config command
Will include zero config values (e.g. "", 0, false) in the output and will be more verbose, but useful if you cant to discover all available config options.
2025-01-15 22:48:14 +02:00
Bjørn Erik Pedersen 76993369a0 For render hooks, only fallback to HTML (or the defaultOutputFormat) template
Closes #13242
2025-01-15 19:59:58 +02:00
Bjørn Erik Pedersen de7137cc35 tpl/collections: Use MapRange/SetIterKey/SetIterValue for Where, Sort and Merge
Some relevant benchmarks:

Where with maps:

```
cpu: Apple M1 Pro
            │ master.bench │         fix-mapkeys.bench          │
            │    sec/op    │   sec/op     vs base               │
WhereMap-10    79.26µ ± 1%   26.58µ ± 1%  -66.46% (p=0.002 n=6)

            │ master.bench │         fix-mapkeys.bench         │
            │     B/op     │    B/op     vs base               │
WhereMap-10   56685.0 ± 0%   111.0 ± 1%  -99.80% (p=0.002 n=6)

            │ master.bench  │         fix-mapkeys.bench         │
            │   allocs/op   │ allocs/op   vs base               │
WhereMap-10   2003.000 ± 0%   4.000 ± 0%  -99.80% (p=0.002 n=6)
```

Merge:

```
         │ master.bench │         fix-mapkeys.bench          │
         │    sec/op    │   sec/op     vs base               │
Merge-10    3.285µ ± 0%   2.268µ ± 1%  -30.96% (p=0.002 n=6)

         │ master.bench │          fix-mapkeys.bench          │
         │     B/op     │     B/op      vs base               │
Merge-10   3.079Ki ± 0%   1.891Ki ± 0%  -38.58% (p=0.002 n=6)

         │ master.bench │         fix-mapkeys.bench         │
         │  allocs/op   │ allocs/op   vs base               │
Merge-10     64.00 ± 0%   26.00 ± 0%  -59.38% (p=0.002 n=6)
```
Sort:

```
cpu: Apple M1 Pro
           │ master.bench │         fix-mapkeys.bench         │
           │    sec/op    │   sec/op     vs base              │
SortMap-10   1008.0n ± 1%   915.5n ± 0%  -9.18% (p=0.002 n=6)

           │ master.bench │         fix-mapkeys.bench         │
           │     B/op     │    B/op     vs base               │
SortMap-10     640.0 ± 0%   512.0 ± 0%  -20.00% (p=0.002 n=6)

           │ master.bench │        fix-mapkeys.bench         │
           │  allocs/op   │ allocs/op   vs base              │
SortMap-10     16.00 ± 0%   15.00 ± 0%  -6.25% (p=0.002 n=6)
```
2025-01-13 16:24:48 +02:00
Bjørn Erik Pedersen a2edf04c27 deps: Upgrade github.com/gohugoio/hashstructure from 0.1.0 to 0.3.0
Faster hashing of maps:

```
           │ stash.bench  │      deps-hashstructv030.bench      │
           │    sec/op    │    sec/op     vs base               │
HashMap-10   198.9µ ± ∞ ¹   142.6µ ± ∞ ¹  -28.31% (p=0.029 n=4)
¹ need >= 6 samples for confidence interval at level 0.95

           │  stash.bench  │      deps-hashstructv030.bench       │
           │     B/op      │     B/op       vs base               │
HashMap-10   92.38Ki ± ∞ ¹   37.14Ki ± ∞ ¹  -59.80% (p=0.029 n=4)
¹ need >= 6 samples for confidence interval at level 0.95

           │ stash.bench  │      deps-hashstructv030.bench      │
           │  allocs/op   │  allocs/op    vs base               │
HashMap-10   6.747k ± ∞ ¹   4.748k ± ∞ ¹  -29.63% (p=0.029 n=4)
```
2025-01-13 16:22:24 +02:00
Bjørn Erik Pedersen 956f915f77 tpl/collections: Add BenchmarkWhereMap 2025-01-13 12:57:48 +02:00
Bjørn Erik Pedersen a2a4166f6d tpl/collections: Add BenchmarkSortMap 2025-01-13 10:38:12 +02:00
Bjørn Erik Pedersen 39f582f9f4 tpl/collections: Add Merge benchmark 2025-01-13 10:32:41 +02:00
Bjørn Erik Pedersen 2501de7aab resources/images: Refactor golden image tests to locate them closer to the implementation 2025-01-11 18:27:53 +02:00
Bjørn Erik Pedersen 06cc8673fa resources/images: Add some mask tests
Closes #13244
2025-01-11 12:20:11 +02:00
Markus Kienast 71fae99189 resources/images: Add images.Mask
See #13244
2025-01-11 12:20:11 +02:00
Joe Mooring 8af04745fb tpl/tplimpl: Use plain text for image render hook alt attribute
Co-authored-by: Heracles <email@heracl.es>
2025-01-10 19:44:39 +02:00
Bjørn Erik Pedersen dde9d9d544 Adjust error handling in ToMath vs try (note)
Closes #13239
2025-01-09 11:47:19 +01:00
Bjørn Erik Pedersen 892b49110e resources/images: Add some golden tests for images.QR 2025-01-09 08:02:43 +01:00
Bjørn Erik Pedersen c5a63a3b4f Fix branch resource overlapping bundle path
Fixes #13228
2025-01-09 08:00:30 +01:00
Bjørn Erik Pedersen 61d3d20129 templates: Fix handling of multiple defers in the same template
Fixes #13236
2025-01-09 07:59:25 +01:00
Joe Mooring b13d0a68e6 tpl/images: Change signature of images.QR to images.QR TEXT OPTIONS
Closes #13230
2025-01-08 19:59:39 +01:00
Bjørn Erik Pedersen d9594a96fc resources/images: Add some golden tests for images.Text 2025-01-08 18:56:26 +01:00
Julius Künzel 4a5cc2dd26 images.Text: Add "alignx" option for horizontal alignment
Add an "alignx" option to the images.Text to control whether the value of the "x" option is the left border of the text (current behaviour), the center of each line or the right border.

Fixes #10849
2025-01-08 17:23:46 +01:00
Bjørn Erik Pedersen 9cad8d38ca images: Rework the golden tests 2025-01-08 17:11:27 +01:00
Bjørn Erik Pedersen cfa0801815 Fix NPX issue with TailwindCSS v4
This allows the `tailwindcss` CLI binary to live in the `PATH` for NPM-less projects.

Fixes #13221
2025-01-07 13:12:08 +01:00
dependabot[bot] f024a5050e build(deps): bump golang.org/x/tools from 0.28.0 to 0.29.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.28.0 to 0.29.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-07 10:46:27 +01:00
dependabot[bot] 80704bc9a1 build(deps): bump golang.org/x/net from 0.33.0 to 0.34.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.33.0 to 0.34.0.
- [Commits](https://github.com/golang/net/compare/v0.33.0...v0.34.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-07 10:46:04 +01:00
Joe Mooring 3682027a51 snap: Always package latest stable version of Go 2025-01-06 12:50:40 -08:00
Bjørn Erik Pedersen 44628616af docs: Regen CLI docs 2025-01-06 18:12:20 +01:00
Bjørn Erik Pedersen 0fc86783ee Merge commit 'e9fbadacc3f09191e2e19f112a49777eeb8df06c' 2025-01-06 18:11:07 +01:00
Bjørn Erik Pedersen e9fbadacc3 Squashed 'docs/' changes from 8390a4a3a..f0f4bcb24
f0f4bcb24 Update Batch.md
15a8b1de6 Update Batch.md
eb841ce66 Update theme
751097f24 Use CI_PAGES_URL in GitLab Pages workflow
8584a0581 Fix typos
b030a7149 Update configuration.md
f7ec2ee9c Revert "Update shortcode.md"
f8188f1c8 Update shortcode.md
083fc39c6 Update shortcode.md
d4bdfb96b Update Filter.md
ef00649db Document wrapperClass highlighting option
e227dc422 Hugo 0.140.2
b95d28444 Fix description of the the hugo server command
41ca381b0 Fix documentation of Fragments
73a6cd966 Update theme
2573fd120 netlify: Hugo 0.140.1
90b19ec0d Merge branch 'tempv0.140.1'
ad2e9aeec Update gocloud and docs for S3-Compatible Endpoints
34b30bad2 Remove indentation from include shortcode examples
97b4ef544 Update related.md
7234e0189 Update related.md
32cc191f6 Clarify Name and Title menu entry methods
bce733c63 Update theme
2f1843d10 Use .Page.GetPage in examples of an include shortcode
9e1c85bbd Revert "Document PAGE.String"
bb30e7c08 Document PAGE.String
2d151d77f Fix link
fbe2d442f Miscellaneous updates for v0.140.0
4d3195223 Update JS docs vs Hugo v0.140
8c190aabc netlify: Hugo 0.140.0
826005ffe Merge branch 'tempv0.140.0'
107289a2c Update theme (again)
9884425f9 Update theme
ff0a358d3 Update Go tool version in hugo.work
c9b23cf6d tpl/tplimpl: Update details shortcode
f29f19aff tpl/tplimpl: Add details shortcode

git-subtree-dir: docs
git-subtree-split: f0f4bcb243
2025-01-06 18:09:20 +01:00
Bjørn Erik Pedersen 2a7bb1c7c9 create: Respect --noBuildLock in hugo new 2025-01-06 17:59:24 +01:00
dependabot[bot] b7b49fb0f8 build(deps): bump github.com/evanw/esbuild from 0.24.0 to 0.24.2
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.24.0 to 0.24.2.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.24.0...v0.24.2)

---
updated-dependencies:
- dependency-name: github.com/evanw/esbuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-06 15:07:05 +01:00
Bjørn Erik Pedersen 5f2adad2c7 tpl/images: Format the QR hashes as hex
Slightly shorter, and it looks more like a ... hash.
2025-01-06 15:05:03 +01:00
dependabot[bot] a837976731 build(deps): bump github.com/alecthomas/chroma/v2 from 2.14.0 to 2.15.0
Bumps [github.com/alecthomas/chroma/v2](https://github.com/alecthomas/chroma) from 2.14.0 to 2.15.0.
- [Release notes](https://github.com/alecthomas/chroma/releases)
- [Changelog](https://github.com/alecthomas/chroma/blob/master/.goreleaser.yml)
- [Commits](https://github.com/alecthomas/chroma/compare/v2.14.0...v2.15.0)

---
updated-dependencies:
- dependency-name: github.com/alecthomas/chroma/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-06 13:38:55 +01:00
Bjørn Erik Pedersen 0918e087ec resources: Replace error handling in GetRemote with try (note)
Closes #13216
2025-01-06 12:22:17 +01:00
Joe Mooring 4ea94c451d tpl/images: Add images.QR function
Closes #13205
2025-01-06 12:05:59 +01:00
Bjørn Erik Pedersen 5d2cbee989 Add try
Updates #9737
2025-01-05 15:32:21 +01:00
Bjørn Erik Pedersen 723e3f4342 resources: Add FromOpts for more effective resource creation
E.g. when the targetPath already contains a hash or if the resource content is expensive to create.
2025-01-05 12:43:37 +01:00
Bjørn Erik Pedersen d913f46a8b Fix server refresh on 404 template changes
Fixes #13209
2025-01-02 11:21:25 +01:00
Joe Mooring 2db43f841c markup/highlight: Remove noHl option
Closes #9885
2024-12-31 15:46:46 +01:00
hugoreleaser 46ce1f191b releaser: Prepare repository for 0.141.0-DEV
[ci skip]
2024-12-30 15:16:00 +00:00
hugoreleaser aae02ca612 releaser: Bump versions for release of 0.140.2
[ci skip]
2024-12-30 15:01:53 +00:00
Diwas Rimal 83cec785cf Print cli usage of hugo gen chromastyles alongside css 2024-12-30 15:06:35 +01:00
dependabot[bot] 4e52be8b90 build(deps): bump golang.org/x/net from 0.32.0 to 0.33.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.32.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.32.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-30 10:57:04 +01:00
Joe Mooring 7888ac585c config/allconfig: Fix slice of language configs
Fixes #13201
2024-12-30 10:54:56 +01:00
Joe Mooring eb1dbe0709 config/allconfig: Throw error when output format is not defined
Fixes #13199
2024-12-29 21:38:46 +01:00
Bjørn Erik Pedersen 77824d704c Fix same resource file published more than once
This may still happen, though, in low memory situations or very big sites, but I'm not sure it's worth spending time on fixing that. Writing the same file more than once isn't harmful, the negative effect is the false path warning.
 We may find a way to detect that situation if this becomes a real problem.

Fixes #13164
2024-12-27 18:55:24 +01:00
Bjørn Erik Pedersen ec0caaec7c markup/highlight: Add wrapperClass option
The need comes from Tailwind's typography plugin. There's currently no way to turn that off outside of the markup, see https://github.com/tailwindlabs/tailwindcss-typography/pull/363
2024-12-25 19:31:47 +01:00
Bjørn Erik Pedersen 845b8885de Update README.md 2024-12-23 18:57:19 +01:00
hugoreleaser 43385d6aeb releaser: Prepare repository for 0.141.0-DEV
[ci skip]
2024-12-23 16:40:37 +00:00
hugoreleaser a9b0b95ef4 releaser: Bump versions for release of 0.140.1
[ci skip]
2024-12-23 16:26:35 +00:00
Chris Moultrie e229f4b387 Update gocloud and docs for S3-Compatible Endpoints 2024-12-22 22:58:36 +01:00
Bjørn Erik Pedersen 020253904f js/esbuild: Don't try to resolve packages in /assets marked as external
Fixes #13183
2024-12-22 21:29:18 +01:00
Bjørn Erik Pedersen 4a5e94087b Fix union, complement, symdiff, and intersect for transient resources
Fixes #13181
2024-12-22 19:25:03 +01:00
Bjørn Erik Pedersen 48a7aee961 release: Add withdeploy deb extended archives
Also refactor and get the config up to date for new version of Hugoreleaser.

Closes #13166
2024-12-22 16:55:52 +01:00
Joe Mooring 6c583e3227 common/loggers: Write PrintTimerIfDelayed output to stdErr
Closes #13171
2024-12-19 19:52:13 +01:00
dependabot[bot] 5d64b492f4 build(deps): bump github.com/spf13/cast from 1.7.0 to 1.7.1
Bumps [github.com/spf13/cast](https://github.com/spf13/cast) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/spf13/cast/releases)
- [Commits](https://github.com/spf13/cast/compare/v1.7.0...v1.7.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cast
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-19 12:08:10 +01:00
Joe Mooring b3f32949cb hugolib: Fix fallbacks for menu entry Name and Title
Closes #13161
2024-12-19 08:47:53 +01:00
hugoreleaser 55ecd3a90e releaser: Prepare repository for 0.141.0-DEV
[ci skip]
2024-12-17 14:37:51 +00:00
735 changed files with 8223 additions and 5215 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ parameters:
defaults: &defaults
resource_class: large
docker:
- image: bepsays/ci-hugoreleaser:1.22300.20400
- image: bepsays/ci-hugoreleaser:1.22301.20401
environment: &buildenv
GOMODCACHE: /root/project/gomodcache
version: 2
@@ -58,7 +58,7 @@ jobs:
environment:
<<: [*buildenv]
docker:
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22300.20400
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22301.20401
steps:
- *restore-cache
- &attach-workspace
+1
View File
@@ -3,3 +3,4 @@
imports.*
dist/
public/
.DS_Store
+17 -16
View File
@@ -66,8 +66,6 @@ See the [features] section of the documentation for a comprehensive summary of H
<p float="left">
<a href="https://www.linode.com/?utm_campaign=hugosponsor&utm_medium=banner&utm_source=hugogithub" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/linode-logo_standard_light_medium.png" width="200" alt="Linode"></a>
&nbsp;&nbsp;&nbsp;
<a href="https://route4me.com/" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/Route4MeLogoBlueOnWhite.svg" width="200" alt="Route Planning & Route Optimization Software"></a>
&nbsp;&nbsp;&nbsp;
<a href="https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/goland.svg" width="200" alt="The complete IDE crafted for professional Go developers."></a>
</p>
@@ -103,6 +101,7 @@ Build the extended edition:
```text
CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest
```
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=gohugoio/hugo&type=Timeline)](https://star-history.com/#gohugoio/hugo&Timeline)
@@ -156,7 +155,7 @@ github.com/bep/clocks="v0.5.0"
github.com/bep/debounce="v1.2.0"
github.com/bep/gitmap="v1.6.0"
github.com/bep/goat="v0.5.0"
github.com/bep/godartsass/v2="v2.3.0"
github.com/bep/godartsass/v2="v2.3.2"
github.com/bep/golibsass="v1.2.0"
github.com/bep/gowebp="v0.3.0"
github.com/bep/imagemeta="v0.8.3"
@@ -191,7 +190,7 @@ github.com/gohugoio/locales="v0.14.0"
github.com/gohugoio/localescompressed="v1.0.1"
github.com/google/go-cmp="v0.6.0"
github.com/gorilla/websocket="v1.5.3"
github.com/hairyhenderson/go-codeowners="v0.6.1"
github.com/hairyhenderson/go-codeowners="v0.7.0"
github.com/hashicorp/golang-lru/v2="v2.0.7"
github.com/invopop/yaml="v0.2.0"
github.com/jdkato/prose="v1.2.1"
@@ -220,30 +219,32 @@ github.com/russross/blackfriday/v2="v2.1.0"
github.com/sass/dart-sass/compiler="1.81.0"
github.com/sass/dart-sass/implementation="1.81.0"
github.com/sass/dart-sass/protocol="3.1.0"
github.com/sass/libsass="3.6.6"
github.com/spf13/afero="v1.11.0"
github.com/spf13/cast="v1.7.0"
github.com/spf13/cast="v1.7.1"
github.com/spf13/cobra="v1.8.1"
github.com/spf13/fsync="v0.10.1"
github.com/spf13/pflag="v1.0.5"
github.com/tdewolff/minify/v2="v2.21.1"
github.com/tdewolff/parse/v2="v2.7.18"
github.com/tetratelabs/wazero="v1.8.1"
github.com/tdewolff/minify/v2="v2.20.37"
github.com/tdewolff/parse/v2="v2.7.15"
github.com/tetratelabs/wazero="v1.8.2"
github.com/webmproject/libwebp="v1.3.2"
github.com/yuin/goldmark-emoji="v1.0.4"
github.com/yuin/goldmark="v1.7.8"
go.uber.org/automaxprocs="v1.5.3"
golang.org/x/crypto="v0.29.0"
golang.org/x/crypto="v0.31.0"
golang.org/x/exp="v0.0.0-20221031165847-c99f073a8326"
golang.org/x/image="v0.22.0"
golang.org/x/mod="v0.22.0"
golang.org/x/net="v0.31.0"
golang.org/x/sync="v0.9.0"
golang.org/x/sys="v0.27.0"
golang.org/x/text="v0.20.0"
golang.org/x/tools="v0.27.0"
google.golang.org/protobuf="v1.35.1"
golang.org/x/net="v0.33.0"
golang.org/x/sync="v0.10.0"
golang.org/x/sys="v0.28.0"
golang.org/x/text="v0.21.0"
golang.org/x/tools="v0.28.0"
google.golang.org/protobuf="v1.35.2"
gopkg.in/yaml.v2="v2.4.0"
gopkg.in/yaml.v3="v3.0.1"
howett.net/plist="v1.0.0"
rsc.io/qr="v0.2.0"
software.sslmate.com/src/go-pkcs12="v0.2.0"
```
</details>
+3 -1
View File
@@ -447,6 +447,8 @@ func (r *rootCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
if err != nil {
return err
}
// Set up the global logger early to allow info deprecations during config load.
loggers.InitGlobalLogger(r.logger.Level(), false)
r.changesFromBuild = make(chan []identity.Identity, 10)
@@ -538,6 +540,7 @@ Complete documentation is available at https://gohugo.io/.`
cmd.PersistentFlags().StringP("themesDir", "", "", "filesystem path to themes directory")
_ = cmd.MarkFlagDirname("themesDir")
cmd.PersistentFlags().StringP("ignoreVendorPaths", "", "", "ignores any _vendor for module paths matching the given Glob pattern")
cmd.PersistentFlags().BoolP("noBuildLock", "", false, "don't create .hugo_build.lock file")
_ = cmd.RegisterFlagCompletionFunc("ignoreVendorPaths", cobra.NoFileCompletions)
cmd.PersistentFlags().String("clock", "", "set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00")
_ = cmd.RegisterFlagCompletionFunc("clock", cobra.NoFileCompletions)
@@ -593,7 +596,6 @@ func applyLocalFlagsBuild(cmd *cobra.Command, r *rootCommand) {
cmd.Flags().BoolVar(&r.forceSyncStatic, "forceSyncStatic", false, "copy all files when static is changed.")
cmd.Flags().BoolP("noTimes", "", false, "don't sync modification time of files")
cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files")
cmd.Flags().BoolP("noBuildLock", "", false, "don't create .hugo_build.lock file")
cmd.Flags().BoolP("printI18nWarnings", "", false, "print missing translations")
cmd.Flags().BoolP("printPathWarnings", "", false, "print warnings on duplicate target paths etc.")
cmd.Flags().BoolP("printUnusedTemplates", "", false, "print warnings on unused templates.")
+5 -3
View File
@@ -43,8 +43,9 @@ func newConfigCommand() *configCommand {
type configCommand struct {
r *rootCommand
format string
lang string
format string
lang string
printZero bool
commands []simplecobra.Commander
}
@@ -78,7 +79,7 @@ func (c *configCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, arg
dec.SetIndent("", " ")
dec.SetEscapeHTML(false)
if err := dec.Encode(parser.ReplacingJSONMarshaller{Value: config, KeysToLower: true, OmitEmpty: true}); err != nil {
if err := dec.Encode(parser.ReplacingJSONMarshaller{Value: config, KeysToLower: true, OmitEmpty: !c.printZero}); err != nil {
return err
}
@@ -115,6 +116,7 @@ func (c *configCommand) Init(cd *simplecobra.Commandeer) error {
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.")
cmd.Flags().BoolVar(&c.printZero, "printZero", false, `include config options with zero values (e.g. false, 0, "") in the output`)
_ = cmd.RegisterFlagCompletionFunc("lang", cobra.NoFileCompletions)
applyLocalFlagsBuildConfig(cmd, c.r)
+3 -1
View File
@@ -75,7 +75,9 @@ See https://xyproto.github.io/splash/docs/all.html for a preview of the availabl
return err
}
formatter := html.New(html.WithAllClasses(true))
formatter.WriteCSS(os.Stdout, style)
w := os.Stdout
fmt.Fprintf(w, "/* Generated using: hugo %s */\n\n", strings.Join(os.Args[1:], " "))
formatter.WriteCSS(w, style)
return nil
},
withc: func(cmd *cobra.Command, r *rootCommand) {
+3 -3
View File
@@ -62,7 +62,7 @@ type hugoBuilder struct {
// Currently only set when in "fast render mode".
changeDetector *fileChangeDetector
visitedURLs *types.EvictingStringQueue
visitedURLs *types.EvictingQueue[string]
fullRebuildSem *semaphore.Weighted
debounce func(f func())
@@ -1103,7 +1103,7 @@ func (c *hugoBuilder) rebuildSites(events []fsnotify.Event) (err error) {
if err != nil {
return
}
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()}, events...)
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, RecentlyTouched: c.visitedURLs, ErrRecovery: c.errState.wasErr()}, events...)
return
}
@@ -1119,7 +1119,7 @@ func (c *hugoBuilder) rebuildSitesForChanges(ids []identity.Identity) (err error
}
whatChanged := &hugolib.WhatChanged{}
whatChanged.Add(ids...)
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, WhatChanged: whatChanged, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()})
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, WhatChanged: whatChanged, RecentlyTouched: c.visitedURLs, ErrRecovery: c.errState.wasErr()})
return
}
+8 -5
View File
@@ -85,9 +85,9 @@ const (
)
func newHugoBuilder(r *rootCommand, s *serverCommand, onConfigLoaded ...func(reloaded bool) error) *hugoBuilder {
var visitedURLs *types.EvictingStringQueue
var visitedURLs *types.EvictingQueue[string]
if s != nil && !s.disableFastRender {
visitedURLs = types.NewEvictingStringQueue(20)
visitedURLs = types.NewEvictingQueue[string](20)
}
return &hugoBuilder{
r: r,
@@ -364,7 +364,10 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, net.Listener, string
}
if f.c.fastRenderMode && f.c.errState.buildErr() == nil {
if strings.HasSuffix(requestURI, "/") || strings.HasSuffix(requestURI, "html") || strings.HasSuffix(requestURI, "htm") {
// Sec-Fetch-Mode should be sent by all recent browser versions, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode#navigate
// Fall back to the file extension if not set.
// The main take here is that we don't want to have CSS/JS files etc. partake in this logic.
if r.Header.Get("Sec-Fetch-Mode") == "navigate" || strings.HasSuffix(requestURI, "/") || strings.HasSuffix(requestURI, "html") || strings.HasSuffix(requestURI, "htm") {
if !f.c.visitedURLs.Contains(requestURI) {
// If not already on stack, re-render that single page.
if err := f.c.partialReRender(requestURI); err != nil {
@@ -838,7 +841,7 @@ func (c *serverCommand) partialReRender(urls ...string) (err error) {
defer func() {
c.errState.setWasErr(false)
}()
visited := types.NewEvictingStringQueue(len(urls))
visited := types.NewEvictingQueue[string](len(urls))
for _, url := range urls {
visited.Add(url)
}
@@ -850,7 +853,7 @@ func (c *serverCommand) partialReRender(urls ...string) (err error) {
}
// Note: We do not set NoBuildLock as the file lock is not acquired at this stage.
err = h.Build(hugolib.BuildCfg{NoBuildLock: false, RecentlyVisited: visited, PartialReRender: true, ErrRecovery: c.errState.wasErr()})
err = h.Build(hugolib.BuildCfg{NoBuildLock: false, RecentlyTouched: visited, PartialReRender: true, ErrRecovery: c.errState.wasErr()})
return
}
+32 -4
View File
@@ -38,6 +38,19 @@ func XXHashFromReader(r io.Reader) (uint64, int64, error) {
return h.Sum64(), size, nil
}
// XxHashFromReaderHexEncoded calculates the xxHash for the given reader
// and returns the hash as a hex encoded string.
func XxHashFromReaderHexEncoded(r io.Reader) (string, error) {
h := getXxHashReadFrom()
defer putXxHashReadFrom(h)
_, err := io.Copy(h, r)
if err != nil {
return "", err
}
hash := h.Sum(nil)
return hex.EncodeToString(hash), nil
}
// XXHashFromString calculates the xxHash for the given string.
func XXHashFromString(s string) (uint64, error) {
h := xxhash.New()
@@ -70,6 +83,13 @@ func HashString(vs ...any) string {
return strconv.FormatUint(hash, 10)
}
// HashStringHex returns a hash from the given elements as a hex encoded string.
// See HashString for more information.
func HashStringHex(vs ...any) string {
hash := HashUint64(vs...)
return strconv.FormatUint(hash, 16)
}
var hashOptsPool = sync.Pool{
New: func() any {
return &hashstructure.HashOptions{
@@ -103,16 +123,24 @@ func HashUint64(vs ...any) uint64 {
o = elements
}
hashOpts := getHashOpts()
defer putHashOpts(hashOpts)
hash, err := hashstructure.Hash(o, hashOpts)
hash, err := Hash(o)
if err != nil {
panic(err)
}
return hash
}
// Hash returns a hash from vs.
func Hash(vs ...any) (uint64, error) {
hashOpts := getHashOpts()
defer putHashOpts(hashOpts)
var v any = vs
if len(vs) == 1 {
v = vs[0]
}
return hashstructure.Hash(v, hashOpts)
}
type keyer interface {
Key() string
}
+13
View File
@@ -142,3 +142,16 @@ func BenchmarkHashString(b *testing.B) {
})
}
}
func BenchmarkHashMap(b *testing.B) {
m := map[string]interface{}{}
for i := 0; i < 1000; i++ {
m[fmt.Sprintf("key%d", i)] = i
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
HashString(m)
}
}
+21 -2
View File
@@ -258,8 +258,27 @@ func openFile(filename string, fs afero.Fs) (afero.File, string, error) {
return f, realFilename, nil
}
// Cause returns the underlying error or itself if it does not implement Unwrap.
// Cause returns the underlying error, that is,
// it unwraps errors until it finds one that does not implement
// the Unwrap method.
// For a shallow variant, see Unwrap.
func Cause(err error) error {
type unwrapper interface {
Unwrap() error
}
for err != nil {
cause, ok := err.(unwrapper)
if !ok {
break
}
err = cause.Unwrap()
}
return err
}
// Unwrap returns the underlying error or itself if it does not implement Unwrap.
func Unwrap(err error) error {
if u := errors.Unwrap(err); u != nil {
return u
}
@@ -267,7 +286,7 @@ func Cause(err error) error {
}
func extractFileTypePos(err error) (string, text.Position) {
err = Cause(err)
err = Unwrap(err)
var fileType string
+85 -17
View File
@@ -26,7 +26,10 @@ import (
"strings"
"sync"
"github.com/bep/logg"
"github.com/cli/safeexec"
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/security"
)
@@ -86,7 +89,7 @@ var WithEnviron = func(env []string) func(c *commandeer) {
}
// New creates a new Exec using the provided security config.
func New(cfg security.Config, workingDir string) *Exec {
func New(cfg security.Config, workingDir string, log loggers.Logger) *Exec {
var baseEnviron []string
for _, v := range os.Environ() {
k, _ := config.SplitEnvVar(v)
@@ -96,9 +99,11 @@ func New(cfg security.Config, workingDir string) *Exec {
}
return &Exec{
sc: cfg,
workingDir: workingDir,
baseEnviron: baseEnviron,
sc: cfg,
workingDir: workingDir,
infol: log.InfoCommand("exec"),
baseEnviron: baseEnviron,
newNPXRunnerCache: maps.NewCache[string, func(arg ...any) (Runner, error)](),
}
}
@@ -124,12 +129,14 @@ func SafeCommand(name string, arg ...string) (*exec.Cmd, error) {
type Exec struct {
sc security.Config
workingDir string
infol logg.LevelLogger
// os.Environ filtered by the Exec.OsEnviron whitelist filter.
baseEnviron []string
npxInit sync.Once
npxAvailable bool
newNPXRunnerCache *maps.Cache[string, func(arg ...any) (Runner, error)]
npxInit sync.Once
npxAvailable bool
}
func (e *Exec) New(name string, arg ...any) (Runner, error) {
@@ -155,25 +162,86 @@ func (e *Exec) new(name string, fullyQualifiedName string, arg ...any) (Runner,
return cm.command(arg...)
}
type binaryLocation int
func (b binaryLocation) String() string {
switch b {
case binaryLocationNodeModules:
return "node_modules/.bin"
case binaryLocationNpx:
return "npx"
case binaryLocationPath:
return "PATH"
}
return "unknown"
}
const (
binaryLocationNodeModules binaryLocation = iota + 1
binaryLocationNpx
binaryLocationPath
)
// Npx will in order:
// 1. Try fo find the binary in the WORKINGDIR/node_modules/.bin directory.
// 2. If not found, and npx is available, run npx --no-install <name> <args>.
// 3. Fall back to the PATH.
// If name is "tailwindcss", we will try the PATH as the second option.
func (e *Exec) Npx(name string, arg ...any) (Runner, error) {
// npx is slow, so first try the common case.
nodeBinFilename := filepath.Join(e.workingDir, nodeModulesBinPath, name)
_, err := safeexec.LookPath(nodeBinFilename)
if err == nil {
return e.new(name, nodeBinFilename, arg...)
if err := e.sc.CheckAllowedExec(name); err != nil {
return nil, err
}
e.checkNpx()
if e.npxAvailable {
r, err := e.npx(name, arg...)
if err == nil {
return r, nil
newRunner, err := e.newNPXRunnerCache.GetOrCreate(name, func() (func(...any) (Runner, error), error) {
type tryFunc func() func(...any) (Runner, error)
tryFuncs := map[binaryLocation]tryFunc{
binaryLocationNodeModules: func() func(...any) (Runner, error) {
nodeBinFilename := filepath.Join(e.workingDir, nodeModulesBinPath, name)
_, err := safeexec.LookPath(nodeBinFilename)
if err != nil {
return nil
}
return func(arg2 ...any) (Runner, error) {
return e.new(name, nodeBinFilename, arg2...)
}
},
binaryLocationNpx: func() func(...any) (Runner, error) {
e.checkNpx()
if !e.npxAvailable {
return nil
}
return func(arg2 ...any) (Runner, error) {
return e.npx(name, arg2...)
}
},
binaryLocationPath: func() func(...any) (Runner, error) {
if _, err := safeexec.LookPath(name); err != nil {
return nil
}
return func(arg2 ...any) (Runner, error) {
return e.New(name, arg2...)
}
},
}
locations := []binaryLocation{binaryLocationNodeModules, binaryLocationNpx, binaryLocationPath}
if name == "tailwindcss" {
// See https://github.com/gohugoio/hugo/issues/13221#issuecomment-2574801253
locations = []binaryLocation{binaryLocationNodeModules, binaryLocationPath, binaryLocationNpx}
}
for _, loc := range locations {
if f := tryFuncs[loc](); f != nil {
e.infol.Logf("resolve %q using %s", name, loc)
return f, nil
}
}
return nil, &NotFoundError{name: name, method: fmt.Sprintf("in %s", locations[len(locations)-1])}
})
if err != nil {
return nil, err
}
return e.New(name, arg...)
return newRunner(arg...)
}
const (
+4 -4
View File
@@ -48,16 +48,16 @@ func TestHasBytesWriter(t *testing.T) {
for i := 0; i < 22; i++ {
h, w := neww()
fmt.Fprintf(w, rndStr()+"abc __foobar"+rndStr())
fmt.Fprint(w, rndStr()+"abc __foobar"+rndStr())
c.Assert(h.Patterns[0].Match, qt.Equals, true)
h, w = neww()
fmt.Fprintf(w, rndStr()+"abc __f")
fmt.Fprintf(w, "oo bar"+rndStr())
fmt.Fprint(w, rndStr()+"abc __f")
fmt.Fprint(w, "oo bar"+rndStr())
c.Assert(h.Patterns[0].Match, qt.Equals, true)
h, w = neww()
fmt.Fprintf(w, rndStr()+"abc __moo bar")
fmt.Fprint(w, rndStr()+"abc __moo bar")
c.Assert(h.Patterns[0].Match, qt.Equals, false)
}
+1 -1
View File
@@ -423,7 +423,7 @@ func DeprecateLevel(item, alternative, version string, level logg.Level) {
msg = fmt.Sprintf("%s was deprecated in Hugo %s and will be removed in a future release. %s", item, version, alternative)
}
loggers.Log().Logger().WithLevel(level).WithField(loggers.FieldNameCmd, "deprecated").Logf(msg)
loggers.Log().Logger().WithLevel(level).WithField(loggers.FieldNameCmd, "deprecated").Logf("%s", msg)
}
// We usually do about one minor version a month.
+2 -2
View File
@@ -17,7 +17,7 @@ package hugo
// This should be the only one.
var CurrentVersion = Version{
Major: 0,
Minor: 140,
Minor: 143,
PatchLevel: 0,
Suffix: "",
Suffix: "-DEV",
}
+1 -1
View File
@@ -275,7 +275,7 @@ func (l *logAdapter) PrintTimerIfDelayed(start time.Time, name string) {
if milli < 500 {
return
}
l.Printf("%s in %v ms", name, milli)
fmt.Fprintf(l.stdErr, "%s in %v ms", name, milli)
}
func (l *logAdapter) Printf(format string, v ...any) {
+133
View File
@@ -0,0 +1,133 @@
// Copyright 2024 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package maps
import (
"github.com/gohugoio/hugo/common/hashing"
)
// Ordered is a map that can be iterated in the order of insertion.
// Note that insertion order is not affected if a key is re-inserted into the map.
// In a nil map, all operations are no-ops.
// This is not thread safe.
type Ordered[K comparable, T any] struct {
// The keys in the order they were added.
keys []K
// The values.
values map[K]T
}
// NewOrdered creates a new Ordered map.
func NewOrdered[K comparable, T any]() *Ordered[K, T] {
return &Ordered[K, T]{values: make(map[K]T)}
}
// Set sets the value for the given key.
// Note that insertion order is not affected if a key is re-inserted into the map.
func (m *Ordered[K, T]) Set(key K, value T) {
if m == nil {
return
}
// Check if key already exists.
if _, found := m.values[key]; !found {
m.keys = append(m.keys, key)
}
m.values[key] = value
}
// Get gets the value for the given key.
func (m *Ordered[K, T]) Get(key K) (T, bool) {
if m == nil {
var v T
return v, false
}
value, found := m.values[key]
return value, found
}
// Delete deletes the value for the given key.
func (m *Ordered[K, T]) Delete(key K) {
if m == nil {
return
}
delete(m.values, key)
for i, k := range m.keys {
if k == key {
m.keys = append(m.keys[:i], m.keys[i+1:]...)
break
}
}
}
// Clone creates a shallow copy of the map.
func (m *Ordered[K, T]) Clone() *Ordered[K, T] {
if m == nil {
return nil
}
clone := NewOrdered[K, T]()
for _, k := range m.keys {
clone.Set(k, m.values[k])
}
return clone
}
// Keys returns the keys in the order they were added.
func (m *Ordered[K, T]) Keys() []K {
if m == nil {
return nil
}
return m.keys
}
// Values returns the values in the order they were added.
func (m *Ordered[K, T]) Values() []T {
if m == nil {
return nil
}
var values []T
for _, k := range m.keys {
values = append(values, m.values[k])
}
return values
}
// Len returns the number of items in the map.
func (m *Ordered[K, T]) Len() int {
if m == nil {
return 0
}
return len(m.keys)
}
// Range calls f sequentially for each key and value present in the map.
// If f returns false, range stops the iteration.
// TODO(bep) replace with iter.Seq2 when we bump go Go 1.24.
func (m *Ordered[K, T]) Range(f func(key K, value T) bool) {
if m == nil {
return
}
for _, k := range m.keys {
if !f(k, m.values[k]) {
return
}
}
}
// Hash calculates a hash from the values.
func (m *Ordered[K, T]) Hash() (uint64, error) {
if m == nil {
return 0, nil
}
return hashing.Hash(m.values)
}
+99
View File
@@ -0,0 +1,99 @@
// Copyright 2024 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package maps
import (
"testing"
qt "github.com/frankban/quicktest"
)
func TestOrdered(t *testing.T) {
c := qt.New(t)
m := NewOrdered[string, int]()
m.Set("a", 1)
m.Set("b", 2)
m.Set("c", 3)
c.Assert(m.Keys(), qt.DeepEquals, []string{"a", "b", "c"})
c.Assert(m.Values(), qt.DeepEquals, []int{1, 2, 3})
v, found := m.Get("b")
c.Assert(found, qt.Equals, true)
c.Assert(v, qt.Equals, 2)
m.Set("b", 22)
c.Assert(m.Keys(), qt.DeepEquals, []string{"a", "b", "c"})
c.Assert(m.Values(), qt.DeepEquals, []int{1, 22, 3})
m.Delete("b")
c.Assert(m.Keys(), qt.DeepEquals, []string{"a", "c"})
c.Assert(m.Values(), qt.DeepEquals, []int{1, 3})
}
func TestOrderedHash(t *testing.T) {
c := qt.New(t)
m := NewOrdered[string, int]()
m.Set("a", 1)
m.Set("b", 2)
m.Set("c", 3)
h1, err := m.Hash()
c.Assert(err, qt.IsNil)
m.Set("d", 4)
h2, err := m.Hash()
c.Assert(err, qt.IsNil)
c.Assert(h1, qt.Not(qt.Equals), h2)
m = NewOrdered[string, int]()
m.Set("b", 2)
m.Set("a", 1)
m.Set("c", 3)
h3, err := m.Hash()
c.Assert(err, qt.IsNil)
// Order does not matter.
c.Assert(h1, qt.Equals, h3)
}
func TestOrderedNil(t *testing.T) {
c := qt.New(t)
var m *Ordered[string, int]
m.Set("a", 1)
c.Assert(m.Keys(), qt.IsNil)
c.Assert(m.Values(), qt.IsNil)
v, found := m.Get("a")
c.Assert(found, qt.Equals, false)
c.Assert(v, qt.Equals, 0)
m.Delete("a")
var b bool
m.Range(func(k string, v int) bool {
b = true
return true
})
c.Assert(b, qt.Equals, false)
c.Assert(m.Len(), qt.Equals, 0)
c.Assert(m.Clone(), qt.IsNil)
h, err := m.Hash()
c.Assert(err, qt.IsNil)
c.Assert(h, qt.Equals, uint64(0))
}
+1 -1
View File
@@ -228,7 +228,7 @@ func UrlFromFilename(filename string) (*url.URL, error) {
}, nil
}
// UrlToFilename converts the URL s to a filename.
// UrlStringToFilename converts the URL s to a filename.
// If ParseRequestURI fails, the input is just converted to OS specific slashes and returned.
func UrlStringToFilename(s string) (string, bool) {
u, err := url.ParseRequestURI(s)
+20 -17
View File
@@ -18,24 +18,24 @@ import (
"sync"
)
// EvictingStringQueue is a queue which automatically evicts elements from the head of
// EvictingQueue is a queue which automatically evicts elements from the head of
// the queue when attempting to add new elements onto the queue and it is full.
// This queue orders elements LIFO (last-in-first-out). It throws away duplicates.
// Note: This queue currently does not contain any remove (poll etc.) methods.
type EvictingStringQueue struct {
type EvictingQueue[T comparable] struct {
size int
vals []string
set map[string]bool
vals []T
set map[T]bool
mu sync.Mutex
zero T
}
// NewEvictingStringQueue creates a new queue with the given size.
func NewEvictingStringQueue(size int) *EvictingStringQueue {
return &EvictingStringQueue{size: size, set: make(map[string]bool)}
// NewEvictingQueue creates a new queue with the given size.
func NewEvictingQueue[T comparable](size int) *EvictingQueue[T] {
return &EvictingQueue[T]{size: size, set: make(map[T]bool)}
}
// Add adds a new string to the tail of the queue if it's not already there.
func (q *EvictingStringQueue) Add(v string) *EvictingStringQueue {
func (q *EvictingQueue[T]) Add(v T) *EvictingQueue[T] {
q.mu.Lock()
if q.set[v] {
q.mu.Unlock()
@@ -54,7 +54,7 @@ func (q *EvictingStringQueue) Add(v string) *EvictingStringQueue {
return q
}
func (q *EvictingStringQueue) Len() int {
func (q *EvictingQueue[T]) Len() int {
if q == nil {
return 0
}
@@ -64,7 +64,7 @@ func (q *EvictingStringQueue) Len() int {
}
// Contains returns whether the queue contains v.
func (q *EvictingStringQueue) Contains(v string) bool {
func (q *EvictingQueue[T]) Contains(v T) bool {
if q == nil {
return false
}
@@ -74,12 +74,12 @@ func (q *EvictingStringQueue) Contains(v string) bool {
}
// Peek looks at the last element added to the queue.
func (q *EvictingStringQueue) Peek() string {
func (q *EvictingQueue[T]) Peek() T {
q.mu.Lock()
l := len(q.vals)
if l == 0 {
q.mu.Unlock()
return ""
return q.zero
}
elem := q.vals[l-1]
q.mu.Unlock()
@@ -87,9 +87,12 @@ func (q *EvictingStringQueue) Peek() string {
}
// PeekAll looks at all the elements in the queue, with the newest first.
func (q *EvictingStringQueue) PeekAll() []string {
func (q *EvictingQueue[T]) PeekAll() []T {
if q == nil {
return nil
}
q.mu.Lock()
vals := make([]string, len(q.vals))
vals := make([]T, len(q.vals))
copy(vals, q.vals)
q.mu.Unlock()
for i, j := 0, len(vals)-1; i < j; i, j = i+1, j-1 {
@@ -99,9 +102,9 @@ func (q *EvictingStringQueue) PeekAll() []string {
}
// PeekAllSet returns PeekAll as a set.
func (q *EvictingStringQueue) PeekAllSet() map[string]bool {
func (q *EvictingQueue[T]) PeekAllSet() map[T]bool {
all := q.PeekAll()
set := make(map[string]bool)
set := make(map[T]bool)
for _, v := range all {
set[v] = true
}
+2 -2
View File
@@ -23,7 +23,7 @@ import (
func TestEvictingStringQueue(t *testing.T) {
c := qt.New(t)
queue := NewEvictingStringQueue(3)
queue := NewEvictingQueue[string](3)
c.Assert(queue.Peek(), qt.Equals, "")
queue.Add("a")
@@ -53,7 +53,7 @@ func TestEvictingStringQueueConcurrent(t *testing.T) {
var wg sync.WaitGroup
val := "someval"
queue := NewEvictingStringQueue(3)
queue := NewEvictingQueue[string](3)
for j := 0; j < 100; j++ {
wg.Add(1)
-19
View File
@@ -133,22 +133,3 @@ func NewBool(b bool) *bool {
type PrintableValueProvider interface {
PrintableValue() any
}
var _ PrintableValueProvider = Result[any]{}
// Result is a generic result type.
type Result[T any] struct {
// The result value.
Value T
// The error value.
Err error
}
// PrintableValue returns the value or panics if there is an error.
func (r Result[T]) PrintableValue() any {
if r.Err != nil {
panic(r.Err)
}
return r.Value
}
+77 -37
View File
@@ -143,7 +143,7 @@ type Config struct {
// The cascade configuration section contains the top level front matter cascade configuration options,
// a slice of page matcher and params to apply to those pages.
Cascade *config.ConfigNamespace[[]page.PageMatcherParamsConfig, map[page.PageMatcher]maps.Params] `mapstructure:"-"`
Cascade *config.ConfigNamespace[[]page.PageMatcherParamsConfig, *maps.Ordered[page.PageMatcher, maps.Params]] `mapstructure:"-"`
// The segments defines segments for the site. Used for partial/segmented builds.
Segments *config.ConfigNamespace[map[string]segments.SegmentConfig, segments.Segments] `mapstructure:"-"`
@@ -301,6 +301,18 @@ func (c *Config) CompileConfig(logger loggers.Logger) error {
}
}
defaultOutputFormat := outputFormats[0]
c.DefaultOutputFormat = strings.ToLower(c.DefaultOutputFormat)
if c.DefaultOutputFormat != "" {
f, found := outputFormats.GetByName(c.DefaultOutputFormat)
if !found {
return fmt.Errorf("unknown default output format %q", c.DefaultOutputFormat)
}
defaultOutputFormat = f
} else {
c.DefaultOutputFormat = defaultOutputFormat.Name
}
disabledLangs := make(map[string]bool)
for _, lang := range c.DisableLanguages {
disabledLangs[lang] = true
@@ -390,23 +402,46 @@ func (c *Config) CompileConfig(logger loggers.Logger) error {
c.Pagination.Path = c.PaginatePath
}
// Legacy privacy values.
if c.Privacy.Twitter.Disable {
hugo.Deprecate("site config key privacy.twitter.disable", "Use privacy.x.disable instead.", "v0.141.0")
c.Privacy.X.Disable = c.Privacy.Twitter.Disable
}
if c.Privacy.Twitter.EnableDNT {
hugo.Deprecate("site config key privacy.twitter.enableDNT", "Use privacy.x.enableDNT instead.", "v0.141.0")
c.Privacy.X.EnableDNT = c.Privacy.Twitter.EnableDNT
}
if c.Privacy.Twitter.Simple {
hugo.Deprecate("site config key privacy.twitter.simple", "Use privacy.x.simple instead.", "v0.141.0")
c.Privacy.X.Simple = c.Privacy.Twitter.Simple
}
// Legacy services values.
if c.Services.Twitter.DisableInlineCSS {
hugo.Deprecate("site config key services.twitter.disableInlineCSS", "Use services.x.disableInlineCSS instead.", "v0.141.0")
c.Services.X.DisableInlineCSS = c.Services.Twitter.DisableInlineCSS
}
c.C = &ConfigCompiled{
Timeout: timeout,
BaseURL: baseURL,
BaseURLLiveReload: baseURL,
DisabledKinds: disabledKinds,
DisabledLanguages: disabledLangs,
IgnoredLogs: ignoredLogIDs,
KindOutputFormats: kindOutputFormats,
ContentTypes: media.DefaultContentTypes.FromTypes(c.MediaTypes.Config),
CreateTitle: helpers.GetTitleFunc(c.TitleCaseStyle),
IsUglyURLSection: isUglyURL,
IgnoreFile: ignoreFile,
SegmentFilter: c.Segments.Config.Get(func(s string) { logger.Warnf("Render segment %q not found in configuration", s) }, c.RootConfig.RenderSegments...),
MainSections: c.MainSections,
Clock: clock,
HTTPCache: httpCache,
transientErr: transientErr,
Timeout: timeout,
BaseURL: baseURL,
BaseURLLiveReload: baseURL,
DisabledKinds: disabledKinds,
DisabledLanguages: disabledLangs,
IgnoredLogs: ignoredLogIDs,
KindOutputFormats: kindOutputFormats,
DefaultOutputFormat: defaultOutputFormat,
ContentTypes: media.DefaultContentTypes.FromTypes(c.MediaTypes.Config),
CreateTitle: helpers.GetTitleFunc(c.TitleCaseStyle),
IsUglyURLSection: isUglyURL,
IgnoreFile: ignoreFile,
SegmentFilter: c.Segments.Config.Get(func(s string) { logger.Warnf("Render segment %q not found in configuration", s) }, c.RootConfig.RenderSegments...),
MainSections: c.MainSections,
Clock: clock,
HTTPCache: httpCache,
transientErr: transientErr,
}
for _, s := range allDecoderSetups {
@@ -430,22 +465,23 @@ func (c *Config) IsLangDisabled(lang string) bool {
// ConfigCompiled holds values and functions that are derived from the config.
type ConfigCompiled struct {
Timeout time.Duration
BaseURL urls.BaseURL
BaseURLLiveReload urls.BaseURL
ServerInterface string
KindOutputFormats map[string]output.Formats
ContentTypes media.ContentTypes
DisabledKinds map[string]bool
DisabledLanguages map[string]bool
IgnoredLogs map[string]bool
CreateTitle func(s string) string
IsUglyURLSection func(section string) bool
IgnoreFile func(filename string) bool
SegmentFilter segments.SegmentFilter
MainSections []string
Clock time.Time
HTTPCache httpcache.ConfigCompiled
Timeout time.Duration
BaseURL urls.BaseURL
BaseURLLiveReload urls.BaseURL
ServerInterface string
KindOutputFormats map[string]output.Formats
DefaultOutputFormat output.Format
ContentTypes media.ContentTypes
DisabledKinds map[string]bool
DisabledLanguages map[string]bool
IgnoredLogs map[string]bool
CreateTitle func(s string) string
IsUglyURLSection func(section string) bool
IgnoreFile func(filename string) bool
SegmentFilter segments.SegmentFilter
MainSections []string
Clock time.Time
HTTPCache httpcache.ConfigCompiled
// This is set to the last transient error found during config compilation.
// With themes/modules we compute the configuration in multiple passes, and
@@ -505,6 +541,10 @@ type RootConfig struct {
// Set this to true to put all languages below their language ID.
DefaultContentLanguageInSubdir bool
// The default output format to use for the site.
// If not set, we will use the first output format.
DefaultOutputFormat string
// Disable generation of redirect to the default language when DefaultContentLanguageInSubdir is enabled.
DisableDefaultLanguageRedirect bool
@@ -726,15 +766,16 @@ type Configs struct {
}
func (c *Configs) Validate(logger loggers.Logger) error {
for p := range c.Base.Cascade.Config {
c.Base.Cascade.Config.Range(func(p page.PageMatcher, params maps.Params) bool {
page.CheckCascadePattern(logger, p)
}
return true
})
return nil
}
// transientErr returns the last transient error found during config compilation.
func (c *Configs) transientErr() error {
for _, l := range c.LanguageConfigSlice {
for _, l := range c.LanguageConfigMap {
if l.C.transientErr != nil {
return l.C.transientErr
}
@@ -751,7 +792,6 @@ func (c *Configs) Init() error {
var languages langs.Languages
defaultContentLanguage := c.Base.DefaultContentLanguage
for k, v := range c.LanguageConfigMap {
c.LanguageConfigSlice = append(c.LanguageConfigSlice, v)
languageConf := v.Languages[k]
language, err := langs.NewLanguage(k, defaultContentLanguage, v.TimeZone, languageConf)
if err != nil {
@@ -175,3 +175,43 @@ func TestMapUglyURLs(t *testing.T) {
b.Assert(c.C.IsUglyURLSection("posts"), qt.IsTrue)
b.Assert(c.C.IsUglyURLSection("blog"), qt.IsFalse)
}
// Issue 13199
func TestInvalidOutputFormat(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
[outputs]
home = ['html','foo']
-- layouts/index.html --
x
`
b, err := hugolib.TestE(t, files)
b.Assert(err, qt.IsNotNil)
b.Assert(err.Error(), qt.Contains, `failed to create config: unknown output format "foo" for kind "home"`)
}
// Issue 13201
func TestLanguageConfigSlice(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
[languages.en]
title = 'TITLE_EN'
weight = 2
[languages.de]
title = 'TITLE_DE'
weight = 1
[languages.fr]
title = 'TITLE_FR'
weight = 3
`
b := hugolib.Test(t, files)
b.Assert(b.H.Configs.LanguageConfigSlice[0].Title, qt.Equals, `TITLE_DE`)
}
+1 -1
View File
@@ -470,7 +470,7 @@ func (l *configLoader) loadModules(configs *Configs, ignoreModuleDoesNotExist bo
ignoreVendor, _ = hglob.GetGlob(hglob.NormalizePath(s))
}
ex := hexec.New(conf.Security, workingDir)
ex := hexec.New(conf.Security, workingDir, l.Logger)
hook := func(m *modules.ModulesConfig) error {
for _, tc := range m.AllModules {
+1 -1
View File
@@ -22,7 +22,7 @@ import (
func DecodeNamespace[S, C any](configSource any, buildConfig func(any) (C, any, error)) (*ConfigNamespace[S, C], error) {
// Calculate the hash of the input (not including any defaults applied later).
// This allows us to introduce new config options without breaking the hash.
h := hashing.HashString(configSource)
h := hashing.HashStringHex(configSource)
// Build the config
c, ext, err := buildConfig(configSource)
+1 -1
View File
@@ -43,7 +43,7 @@ func TestNamespace(t *testing.T) {
c.Assert(err, qt.IsNil)
c.Assert(ns, qt.Not(qt.IsNil))
c.Assert(ns.SourceStructure, qt.DeepEquals, map[string]interface{}{"foo": "bar"})
c.Assert(ns.SourceHash, qt.Equals, "1450430416588600409")
c.Assert(ns.SourceHash, qt.Equals, "1420f6c7782f7459")
c.Assert(ns.Config, qt.DeepEquals, &tstNsExt{Foo: "bar"})
c.Assert(ns.Signature(), qt.DeepEquals, []*tstNsExt(nil))
}
+20 -4
View File
@@ -30,9 +30,10 @@ type Config struct {
Disqus Disqus
GoogleAnalytics GoogleAnalytics
Instagram Instagram
Twitter Twitter
Twitter Twitter // deprecated in favor of X in v0.141.0
Vimeo Vimeo
YouTube YouTube
X X
}
// Disqus holds the privacy configuration settings related to the Disqus template.
@@ -58,7 +59,8 @@ type Instagram struct {
Simple bool
}
// Twitter holds the privacy configuration settingsrelated to the Twitter shortcode.
// Twitter holds the privacy configuration settings related to the Twitter shortcode.
// Deprecated in favor of X in v0.141.0.
type Twitter struct {
Service `mapstructure:",squash"`
@@ -70,7 +72,7 @@ type Twitter struct {
Simple bool
}
// Vimeo holds the privacy configuration settingsrelated to the Vimeo shortcode.
// Vimeo holds the privacy configuration settings related to the Vimeo shortcode.
type Vimeo struct {
Service `mapstructure:",squash"`
@@ -84,7 +86,7 @@ type Vimeo struct {
Simple bool
}
// YouTube holds the privacy configuration settingsrelated to the YouTube shortcode.
// YouTube holds the privacy configuration settings related to the YouTube shortcode.
type YouTube struct {
Service `mapstructure:",squash"`
@@ -94,6 +96,20 @@ type YouTube struct {
PrivacyEnhanced bool
}
// X holds the privacy configuration settings related to the X shortcode.
type X struct {
Service `mapstructure:",squash"`
// When set to true, the X post and its embedded page on your site are not
// used for purposes that include personalized suggestions and personalized
// ads.
EnableDNT bool
// If simple mode is enabled, a static and no-JS version of the X post will
// be built.
Simple bool
}
// DecodeConfig creates a privacy Config from a given Hugo configuration.
func DecodeConfig(cfg config.Provider) (pc Config, err error) {
if !cfg.IsSet(privacyConfigKey) {
+6 -1
View File
@@ -40,6 +40,10 @@ simple = true
disable = true
enableDNT = true
simple = true
[privacy.x]
disable = true
enableDNT = true
simple = true
[privacy.vimeo]
disable = true
enableDNT = true
@@ -61,7 +65,8 @@ simple = true
pc.GoogleAnalytics.RespectDoNotTrack, pc.Instagram.Disable,
pc.Instagram.Simple, pc.Twitter.Disable, pc.Twitter.EnableDNT,
pc.Twitter.Simple, pc.Vimeo.Disable, pc.Vimeo.EnableDNT, pc.Vimeo.Simple,
pc.YouTube.PrivacyEnhanced, pc.YouTube.Disable,
pc.YouTube.PrivacyEnhanced, pc.YouTube.Disable, pc.X.Disable, pc.X.EnableDNT,
pc.X.Simple,
}
c.Assert(got, qt.All(qt.Equals), true)
+11 -1
View File
@@ -31,7 +31,8 @@ type Config struct {
Disqus Disqus
GoogleAnalytics GoogleAnalytics
Instagram Instagram
Twitter Twitter
Twitter Twitter // deprecated in favor of X in v0.141.0
X X
RSS RSS
}
@@ -61,6 +62,7 @@ type Instagram struct {
}
// Twitter holds the functional configuration settings related to the Twitter shortcodes.
// Deprecated in favor of X in v0.141.0.
type Twitter struct {
// The Simple variant of Twitter is decorated with a basic set of inline styles.
// This means that if you want to provide your own CSS, you want
@@ -68,6 +70,14 @@ type Twitter struct {
DisableInlineCSS bool
}
// X holds the functional configuration settings related to the X shortcodes.
type X struct {
// The Simple variant of X is decorated with a basic set of inline styles.
// This means that if you want to provide your own CSS, you want
// to disable the inline CSS provided by Hugo.
DisableInlineCSS bool
}
// RSS holds the functional configuration settings related to the RSS feeds.
type RSS struct {
// Limit the number of pages.
+2
View File
@@ -36,6 +36,8 @@ id = "ga_id"
disableInlineCSS = true
[services.twitter]
disableInlineCSS = true
[services.x]
disableInlineCSS = true
`
cfg, err := config.FromConfigString(tomlConfig, "toml")
c.Assert(err, qt.IsNil)
+6 -4
View File
@@ -82,11 +82,13 @@ func NewContent(h *hugolib.HugoSites, kind, targetPath string, force bool) error
b.setArcheTypeFilenameToUse(ext)
withBuildLock := func() (string, error) {
unlock, err := h.BaseFs.LockBuild()
if err != nil {
return "", fmt.Errorf("failed to acquire a build lock: %s", err)
if !h.Configs.Base.NoBuildLock {
unlock, err := h.BaseFs.LockBuild()
if err != nil {
return "", fmt.Errorf("failed to acquire a build lock: %s", err)
}
defer unlock()
}
defer unlock()
if b.isDir {
return "", b.buildDir()
+1 -1
View File
@@ -188,7 +188,7 @@ func (d *Deps) Init() error {
}
if d.ExecHelper == nil {
d.ExecHelper = hexec.New(d.Conf.GetConfigSection("security").(security.Config), d.Conf.WorkingDir())
d.ExecHelper = hexec.New(d.Conf.GetConfigSection("security").(security.Config), d.Conf.WorkingDir(), d.Log)
}
if d.MemCache == nil {
+1
View File
@@ -23,3 +23,4 @@ MD046: false
MD049: false
MD050: false
MD053: false
MD055: false
@@ -10,9 +10,9 @@
}
code {
padding: 0.2em;
padding: 2px 3px;
margin: 0;
font-size: 85%;
font-size: 93.75%;
background-color: rgba(27,31,35,0.05);
border-radius: 3px;
}
@@ -18,3 +18,8 @@ h6:first-of-type {
h6 ~ p {
margin: 0.5em 0 2em 0;
}
/* QR codes */
img.qrcode {
width: initial;
}
@@ -4769,9 +4769,9 @@ h6:hover .header-link {
margin: 0;
}
code {
padding: 0.2em;
padding: 2px 3px;
margin: 0;
font-size: 85%;
font-size: 93.75%;
background-color: rgba(27, 31, 35, .05);
border-radius: 3px;
}
@@ -5333,6 +5333,11 @@ h6:first-of-type {
h6 ~ p {
margin: 0.5em 0 2em 0;
}
/* QR codes */
img.qrcode {
width: auto;
width: initial;
}
.nested-blockquote blockquote {
border-left: 4px solid #0594CB;
padding-left: 1em;
@@ -5,15 +5,6 @@
utm_campaign = "hugosponsor"
bgcolor = "#ffffff"
[[banners]]
name = "Route4Me"
link = "https://route4me.com/"
title = "Route Planning & Route Optimization Software"
no_query_params = true
utm_campaign = "hugosponsor"
bgcolor = "#334799"
link_attr = "style='color: #ffffff; font-weight: bold; text-decoration: none; text-align: center'"
[[banners]]
name = "GoLand"
title = "The complete IDE crafted for professional Go developers."
@@ -21,3 +12,11 @@
link = "https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo"
logo = "images/sponsors/goland.svg"
bgcolor = "#f4f4f4"
[[banners]]
name = "Your Company?"
link = "https://bep.is/en/hugo-sponsor-2023-01/"
utm_campaign = "hugosponsor"
show_on_hover = true
bgcolor = "#4e4f4f"
link_attr = "style='color: #ffffff; font-weight: bold; text-decoration: none; text-align: center'"
@@ -98,12 +98,7 @@ either of these shortcodes in conjunction with this render hook.
{{- end }}
{{- /* Determine content path for warning and error messages. */}}
{{- $contentPath := "" }}
{{- with .Page.File }}
{{- $contentPath = .Path }}
{{- else }}
{{- $contentPath = .Path }}
{{- end }}
{{- $contentPath := .Page.String }}
{{- /* Parse destination. */}}
{{- $u := urls.Parse .Destination }}
@@ -4,14 +4,14 @@
{{ $data := "" }}
{{ $url := urls.JoinPath "https://api.github.com/users" $author }}
{{ with resources.GetRemote $url }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ errorf "%s" . }}
{{ else }}
{{ else with .Value }}
{{ $data = . | transform.Unmarshal }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
<div class="tc">
@@ -4,14 +4,14 @@
{{ $data := "" }}
{{ $url := urls.JoinPath "https://api.github.com/users" $author }}
{{ with resources.GetRemote $url }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ errorf "%s" . }}
{{ else }}
{{ else with .Value }}
{{ $data = . | transform.Unmarshal }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ with $data }}
@@ -11,13 +11,13 @@ Supports CSV, JSON, TOML, YAML, and XML.
{{ $url := . }}
{{ $data := dict }}
{{ with resources.GetRemote $url }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ errorf "%s" . }}
{{ else }}
{{ else with .Value }}
{{ $data = .Content | transform.Unmarshal }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ return $data }}
@@ -0,0 +1,11 @@
{{- /*
Returns syntax-highlighted code from the given text.
This is useful as a terse way to highlight inline code snippets. Calling the
highlight shortcode for inline snippets is verbose.
*/}}
{{- $code := .Inner | strings.TrimSpace }}
{{- $lang := or (.Get 0) "go" }}
{{- $opts := dict "hl_inline" true "noClasses" true }}
{{- transform.Highlight $code $lang $opts }}
@@ -120,8 +120,8 @@ Renders the given image using the given filter, if any.
{{- $validFilters := slice
"autoorient" "brightness" "colorbalance" "colorize" "contrast" "dither"
"gamma" "gaussianblur" "grayscale" "hue" "invert" "none" "opacity" "overlay"
"padding" "pixelate" "process" "saturation" "sepia" "sigmoid" "text"
"gamma" "gaussianblur" "grayscale" "hue" "invert" "mask" "none" "opacity"
"overlay" "padding" "pixelate" "process" "saturation" "sepia" "sigmoid" "text"
"unsharpmask"
}}
@@ -229,6 +229,12 @@ Renders the given image using the given filter, if any.
{{- $ctx = merge $ctx (dict "argsRequired" 0) }}
{{- template "validate-arg-count" $ctx }}
{{- $f = images.Invert }}
{{- else if eq $filter "mask" }}
{{- $ctx = merge $ctx (dict "argsRequired" 1) }}
{{- template "validate-arg-count" $ctx }}
{{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }}
{{- $maskImage := partial "inline/get-resource.html" $ctx }}
{{- $f = images.Mask $maskImage }}
{{- else if eq $filter "opacity" }}
{{- $ctx = merge $ctx (dict "argsRequired" 1) }}
{{- template "validate-arg-count" $ctx }}
@@ -322,11 +328,15 @@ Renders the given image using the given filter, if any.
{{- end }}
{{- /* Render. */}}
{{- $class := "di va b--black-20" }}
{{- if eq $filter "mask" }}
{{- $class = "di va" }}
{{- end }}
{{- if $example }}
<p>Original</p>
<img class='di ba b--black-20' style="width: initial;" src="{{ $i.RelPermalink }}" alt="{{ $alt }}">
<img class="{{ $class}}" style="width: initial;" src="{{ $i.RelPermalink }}" alt="{{ $alt }}">
<p>Processed</p>
<img class='di ba b--black-20' style="width: initial;" src="{{ $fi.RelPermalink }}" alt="{{ $alt }}">
<img class="{{ $class }}" style="width: initial;" src="{{ $fi.RelPermalink }}" alt="{{ $alt }}">
{{- else -}}
<img class='di' style="width: initial;" src="{{ $fi.RelPermalink }}" alt="{{ $alt }}">
{{- end }}
@@ -354,15 +364,15 @@ Renders the given image using the given filter, if any.
{{- $u := urls.Parse .src }}
{{- $msg := "The %q shortcode was unable to resolve %s. See %s" }}
{{- if $u.IsAbs }}
{{- with resources.GetRemote $u.String }}
{{- with try (resources.GetRemote $u.String) }}
{{- with .Err }}
{{- errorf "%s" . }}
{{- else }}
{{- else with .Value }}
{{- /* This is a remote resource. */}}
{{- $r = . }}
{{- else }}
{{- errorf $msg $.name $u.String $.position }}
{{- end }}
{{- else }}
{{- errorf $msg $.name $u.String $.position }}
{{- end }}
{{- else }}
{{- with .page.Resources.Get (strings.TrimPrefix "./" $u.Path) }}
@@ -10,7 +10,7 @@ You must call this shortcode using the {{% %}} notation.
*/}}
{{- with .Get 0 }}
{{- with site.GetPage . }}
{{- with $.Page.GetPage . }}
{{- .RenderShortcodes }}
{{- else }}
{{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }}
+1 -2
View File
@@ -1,2 +1 @@
# github.com/gohugoio/gohugoioTheme v0.0.0-20241119115653-b92d27ede3e1
# github.com/gohugoio/gohugoioTheme v0.0.0-20250116152525-2d382cae7743
+19
View File
@@ -0,0 +1,19 @@
---
title: {{ replace .File.ContentBaseName "-" " " }}
---
<!--
You can insert these definitions in other pages using the `glossary-term` shortcode, so they must be self-contained.
Do this:
A _foo_ is big bar.
Not this:
A big bar.
Italicize the term whenever you use it in the definition.
An exception to this rule occurs when a term is an alias for another. In such cases, it is sufficient to use the phrase 'See [page kind]'."
-->
+1 -1
View File
@@ -20,7 +20,7 @@ byline: "[bep](https://github.com/bep), Hugo Lead"
To complete this showcase:
1. Write the story about your site in this file.
2. Add a summary to the `bio.md` file in this folder.
2. Add a summary to the `bio.md` file in this directory.
3. Replace the `featured-template.png` with a screenshot of your site. You can rename it, but it must contain the word `featured`.
4. Create a new pull request in https://github.com/gohugoio/hugoDocs/pulls
Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

+13 -7
View File
@@ -55,20 +55,26 @@ identifier = 'render-hooks'
pageRef = '/render-hooks/'
[[docs]]
name = 'Hugo Modules'
name = 'Shortcodes'
weight = 100
identifier = 'shortcodes'
pageRef = '/shortcodes/'
[[docs]]
name = 'Hugo Modules'
weight = 110
identifier = 'modules'
pageRef = '/hugo-modules/'
[[docs]]
name = 'Hugo Pipes'
weight = 110
weight = 120
identifier = 'hugo-pipes'
pageRef = '/hugo-pipes/'
[[docs]]
name = 'CLI'
weight = 120
weight = 130
post = 'break'
identifier = 'commands'
pageRef = '/commands/'
@@ -77,25 +83,25 @@ pageRef = '/commands/'
[[docs]]
name = 'Troubleshooting'
weight = 130
weight = 140
identifier = 'troubleshooting'
pageRef = '/troubleshooting/'
[[docs]]
name = 'Developer tools'
weight = 140
weight = 150
identifier = 'developer-tools'
pageRef = '/tools/'
[[docs]]
name = 'Hosting and deployment'
weight = 150
weight = 160
identifier = 'hosting-and-deployment'
pageRef = '/hosting-and-deployment/'
[[docs]]
name = 'Contribute'
weight = 160
weight = 170
post = 'break'
identifier = 'contribute'
pageRef = '/contribute/'
+3 -3
View File
@@ -55,7 +55,7 @@ toc: true
: Use fenced code blocks and Markdown render hooks to include diagrams in your content.
[Mathematics]
: Include mathematical equations and expressions in Markdown using LaTeX or TeX typesetting syntax.
: Include mathematical equations and expressions in Markdown using LaTeX markup.
[Syntax highlighting]
: Syntactically highlight code examples using Hugo's embedded syntax highlighter, enabled by default for fenced code blocks in Markdown. The syntax highlighter supports hundreds of code languages and dozens of styles.
@@ -123,7 +123,7 @@ toc: true
[Mathematics]: /content-management/mathematics/
[Menus]: /content-management/menus/
[Minification]: /getting-started/configuration/#configure-minify
[Modules]: https://gohugo.io/hugo-modules/
[Modules]: /hugo-modules/
[Multilingual]: /content-management/multilingual/
[Multiplatform]: /installation/
[Output formats]: /templates/output-formats/
@@ -134,6 +134,6 @@ toc: true
[Syntax highlighting]: /content-management/syntax-highlighting/
[Tailwind CSS processing]: /functions/css/tailwindcss/
[Taxonomies]: /content-management/taxonomies/
[Templates]: templates/introduction/
[Templates]: /templates/introduction/
[Themes]: https://themes.gohugo.io/
[URL management]: /content-management/urls/
+9 -9
View File
@@ -39,11 +39,11 @@ respectDoNotTrack = false
[privacy.instagram]
disable = false
simple = false
[privacy.twitter]
[privacy.vimeo]
disable = false
enableDNT = false
simple = false
[privacy.vimeo]
[privacy.x]
disable = false
enableDNT = false
simple = false
@@ -64,10 +64,10 @@ disable = true
disable = true
[privacy.instagram]
disable = true
[privacy.twitter]
disable = true
[privacy.vimeo]
disable = true
[privacy.x]
disable = true
[privacy.youtube]
disable = true
{{< /code-toggle >}}
@@ -92,19 +92,19 @@ simple
disableInlineCSS = true
{{< /code-toggle >}}
### Twitter
### X
enableDNT
: Enabling this for the twitter/tweet shortcode, the tweet and its embedded page on your site are not used for purposes that include personalized suggestions and personalized ads.
: Enabling this for the x shortcode, the post and its embedded page on your site are not used for purposes that include personalized suggestions and personalized ads.
simple
: If simple mode is enabled, a static and no-JS version of a tweet will be built.
: If simple mode is enabled, a static and no-JS version of a post will be built.
**Note:** If you use the _simple mode_ for Twitter, you may want to disable the inline styles provided by Hugo:
**Note:** If you use the _simple mode_ for X, you may want to disable the inline styles provided by Hugo:
{{< code-toggle file=hugo >}}
[services]
[services.twitter]
[services.x]
disableInlineCSS = true
{{< /code-toggle >}}
-1
View File
@@ -72,7 +72,6 @@ hugo [flags]
* [hugo completion](/commands/hugo_completion/) - Generate the autocompletion script for the specified shell
* [hugo config](/commands/hugo_config/) - Display site configuration
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
* [hugo deploy](/commands/hugo_deploy/) - Deploy your site to a cloud provider
* [hugo env](/commands/hugo_env/) - Display version and environment info
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
* [hugo import](/commands/hugo_import/) - Import a site from another system
@@ -29,6 +29,7 @@ See each sub-command's help for details on how to use the generated script.
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -52,6 +52,7 @@ hugo completion bash
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -43,6 +43,7 @@ hugo completion fish [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -40,6 +40,7 @@ hugo completion powershell [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -54,6 +54,7 @@ hugo completion zsh [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+2
View File
@@ -24,6 +24,7 @@ hugo config [command] [flags]
--format string preferred file format (toml, yaml or json) (default "toml")
-h, --help help for config
--lang string the language to display config for. Defaults to the first language defined.
--printZero include config options with zero values (e.g. false, 0, "") in the output
--renderSegments strings named segments to render (configured in the segments config)
-t, --theme strings themes to use (located in /themes/THEMENAME/)
```
@@ -38,6 +39,7 @@ hugo config [command] [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -32,6 +32,7 @@ hugo config mounts [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -31,6 +31,7 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -32,6 +32,7 @@ hugo convert toJSON [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
-o, --output string filesystem path to write files to
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
@@ -32,6 +32,7 @@ hugo convert toTOML [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
-o, --output string filesystem path to write files to
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
@@ -32,6 +32,7 @@ hugo convert toYAML [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
-o, --output string filesystem path to write files to
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
+1
View File
@@ -42,6 +42,7 @@ hugo deploy [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -31,6 +31,7 @@ hugo env [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -27,6 +27,7 @@ Generate documentation for your project using Hugo's documentation engine, inclu
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -37,6 +37,7 @@ hugo gen chromastyles [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -37,6 +37,7 @@ hugo gen doc [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -34,6 +34,7 @@ hugo gen man [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -29,6 +29,7 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -34,6 +34,7 @@ hugo import jekyll [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -29,6 +29,7 @@ List requires a subcommand, e.g. hugo list drafts
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -31,6 +31,7 @@ hugo list all [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -31,6 +31,7 @@ hugo list drafts [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -31,6 +31,7 @@ hugo list expired [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -31,6 +31,7 @@ hugo list future [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -31,6 +31,7 @@ hugo list published [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -38,6 +38,7 @@ See https://gohugo.io/hugo-modules/ for more information.
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -38,6 +38,7 @@ hugo mod clean [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -62,6 +62,7 @@ hugo mod get [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -39,6 +39,7 @@ hugo mod graph [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -43,6 +43,7 @@ hugo mod init [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -31,6 +31,7 @@ hugo mod npm [command] [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -46,6 +46,7 @@ hugo mod npm pack [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -32,6 +32,7 @@ hugo mod tidy [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -38,6 +38,7 @@ hugo mod vendor [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -37,6 +37,7 @@ hugo mod verify [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -34,6 +34,7 @@ Ensure you run this within the root directory of your site.
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -46,6 +46,7 @@ hugo new content [path] [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -35,6 +35,7 @@ hugo new site [path] [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -34,6 +34,7 @@ hugo new theme [name] [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1 -1
View File
@@ -50,7 +50,6 @@ hugo server [command] [flags]
--liveReloadPort int port for live reloading (i.e. 443 in HTTPS proxy situations) (default -1)
--minify minify any supported output format (HTML, XML etc.)
-N, --navigateToChanged navigate to changed content file on live browser reload
--noBuildLock don't create .hugo_build.lock file
--noChmod don't sync permission mode of files
--noHTTPCache prevent HTTP caching
--noTimes don't sync modification time of files
@@ -85,6 +84,7 @@ hugo server [command] [flags]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -28,6 +28,7 @@ hugo server trust [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
+1
View File
@@ -31,6 +31,7 @@ hugo version [flags] [args]
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
@@ -15,7 +15,7 @@ aliases: [/content/archetypes/]
## Overview
A content file consists of [front matter] and markup. The markup is typically Markdown, but Hugo also supports other [content formats]. Front matter can be TOML, YAML, or JSON.
A content file consists of [front matter](g) and markup. The markup is typically Markdown, but Hugo also supports other [content formats](g). Front matter can be TOML, YAML, or JSON.
The `hugo new content` command creates a new file in the `content` directory, using an archetype as a template. This is the default archetype:
@@ -25,7 +25,7 @@ date = '{{ .Date }}'
draft = true
{{< /code-toggle >}}
When you create new content, Hugo evaluates the [template actions] within the archetype. For example:
When you create new content, Hugo evaluates the [template actions](g) within the archetype. For example:
```sh
hugo new content posts/my-first-post.md
@@ -39,7 +39,7 @@ date = '2023-08-24T11:49:46-07:00'
draft = true
{{< /code-toggle >}}
You can create an archetype for one or more [content types]. For example, use one archetype for posts, and use the default archetype for everything else:
You can create an archetype for one or more [content types](g). For example, use one archetype for posts, and use the default archetype for everything else:
```text
archetypes/
@@ -59,18 +59,18 @@ hugo new content posts/my-first-post.md
The archetype lookup order is:
1. archetypes/posts.md
1. archetypes/default.md
1. themes/my-theme/archetypes/posts.md
1. themes/my-theme/archetypes/default.md
1. `archetypes/posts.md`
1. `archetypes/default.md`
1. `themes/my-theme/archetypes/posts.md`
1. `themes/my-theme/archetypes/default.md`
If none of these exists, Hugo uses a built-in default archetype.
## Functions and context
You can use any [template function] within an archetype. As shown above, the default archetype uses the [`replace`](/functions/strings/replace) function to replace hyphens with spaces when populating the title in front matter.
You can use any template [function](g) within an archetype. As shown above, the default archetype uses the [`replace`](/functions/strings/replace) function to replace hyphens with spaces when populating the title in front matter.
Archetypes receive the following [context]:
Archetypes receive the following [context](g):
Date
: (`string`) The current date and time, formatted in compliance with RFC3339.
@@ -79,9 +79,7 @@ File
: (`hugolib.fileInfo`) Returns file information for the current page. See [details](/methods/page/file).
Type
: (`string`) The [content type] inferred from the top-level directory name, or as specified by the `--kind` flag passed to the `hugo new content` command.
[content type]: /getting-started/glossary#content-type
: (`string`) The [content type](g) inferred from the top-level directory name, or as specified by the `--kind` flag passed to the `hugo new content` command.
Site
: (`page.Site`) The current site object. See [details](/methods/site/).
@@ -130,11 +128,11 @@ One or more practical examples, each within a fenced code block.
Additional information to clarify as needed.
{{< /code >}}
Although you can include [template actions] within the content body, remember that Hugo evaluates these once---at the time of content creation. In most cases, place template actions in a [template] where Hugo evaluates the actions every time you [build](/getting-started/glossary/#build) the site.
Although you can include [template actions](g) within the content body, remember that Hugo evaluates these once---at the time of content creation. In most cases, place template actions in a [template](g) where Hugo evaluates the actions every time you [build](g) the site.
## Leaf bundles
You can also create archetypes for [leaf bundles](/getting-started/glossary/#leaf-bundle).
You can also create archetypes for [leaf bundles](g).
For example, in a photography site you might have a section (content type) for galleries. Each gallery is leaf bundle with content and images.
@@ -193,11 +191,3 @@ To create an article using the tutorials archetype:
```sh
hugo new content --kind tutorials articles/something.md
```
[content formats]: /getting-started/glossary/#content-format
[content types]: /getting-started/glossary/#content-type
[context]: /getting-started/glossary/#context
[front matter]: /getting-started/glossary/#front-matter
[template actions]: /getting-started/glossary/#template-action
[template]: /getting-started/glossary/#template
[template function]: /getting-started/glossary/#function
@@ -21,7 +21,6 @@ publishResources = true
render = 'always'
{{< /code-toggle >}}
list
: When to include the page within page collections. Specify one of:
@@ -115,7 +114,7 @@ public/
In the example above, note that:
1. Hugo did not publish an HTML file for the page.
2. Despite setting `publishResources` to `false` in front matter, Hugo published the [page resources] because we invoked the [`RelPermalink`] method on each resource. This is the expected behavior.
1. Despite setting `publishResources` to `false` in front matter, Hugo published the [page resources] because we invoked the [`RelPermalink`] method on each resource. This is the expected behavior.
## Example -- headless section
@@ -181,7 +180,7 @@ public/
In the example above, note that:
1. Hugo did not publish an HTML file for the page.
2. Despite setting `publishResources` to `false` in front matter, Hugo correctly published the [page resources] because we invoked the [`RelPermalink`] method on each resource. This is the expected behavior.
1. Despite setting `publishResources` to `false` in front matter, Hugo correctly published the [page resources] because we invoked the [`RelPermalink`] method on each resource. This is the expected behavior.
## Example -- list without publishing
@@ -17,7 +17,7 @@ toc: true
A content adapter is a template that dynamically creates pages when building a site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML.
Unlike templates that reside in the layouts directory, content adapters reside in the content directory, no more than one per directory per language. When a content adapter creates a page, the page's [logical path] will be relative to the content adapter.
Unlike templates that reside in the `layouts` directory, content adapters reside in the `content` directory, no more than one per directory per language. When a content adapter creates a page, the page's [logical path](g) will be relative to the content adapter.
```text
content/
@@ -33,7 +33,7 @@ content/
└── _index.md
```
Each content adapter is named _content.gotmpl and uses the same [syntax] as templates in the layouts directory. You can use any of the [template functions] within a content adapter, as well as the methods described below.
Each content adapter is named _content.gotmpl and uses the same [syntax] as templates in the `layouts` directory. You can use any of the [template functions] within a content adapter, as well as the methods described below.
## Methods
@@ -137,9 +137,8 @@ Key|Description|Required
`dates.expiryDate`|The page expiry date as a `time.Time` value.|&nbsp;
`dates.lastmod`|The page last modification date as a `time.Time` value.|&nbsp;
`dates.publishDate`|The page publication date as a `time.Time` value.|&nbsp;
`kind`|The [page kind]. Default is `page`.|&nbsp;
`params`|A map of page parameters.|&nbsp;
`path`|The page's [logical path] relative to the content adapter. Do not include a leading slash or file extension.|:heavy_check_mark:
`path`|The page's [logical path](g) relative to the content adapter. Do not include a leading slash or file extension.|:heavy_check_mark:
`title`|The page title.|&nbsp;
{{% note %}}
@@ -158,7 +157,7 @@ Key|Description|Required
`content.value`|The content value as a string or resource.|:heavy_check_mark:
`name`|The resource name.|&nbsp;
`params`|A map of resource parameters.|&nbsp;
`path`|The resources's [logical path] relative to the content adapter. Do not include a leading slash.|:heavy_check_mark:
`path`|The resources's [logical path](g) relative to the content adapter. Do not include a leading slash.|:heavy_check_mark:
`title`|The resource title.|&nbsp;
{{% note %}}
@@ -193,14 +192,14 @@ Step 3
{{/* Get remote data. */}}
{{ $data := dict }}
{{ $url := "https://gohugo.io/shared/examples/data/books.json" }}
{{ with resources.GetRemote $url }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ errorf "Unable to get remote resource %s: %s" $url . }}
{{ else }}
{{ else with .Value }}
{{ $data = . | transform.Unmarshal }}
{{ else }}
{{ errorf "Unable to get remote resource %s" $url }}
{{ end }}
{{ else }}
{{ errorf "Unable to get remote resource %s" $url }}
{{ end }}
{{/* Add pages and page resources. */}}
@@ -223,10 +222,10 @@ Step 3
{{/* Add page resource. */}}
{{ $item := . }}
{{ with $url := $item.cover }}
{{ with resources.GetRemote $url }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ errorf "Unable to get remote resource %s: %s" $url . }}
{{ else }}
{{ else with .Value }}
{{ $content := dict "mediaType" .MediaType.Type "value" .Content }}
{{ $params := dict "alt" $item.title }}
{{ $resource := dict
@@ -235,9 +234,9 @@ Step 3
"path" (printf "%s/cover.%s" $item.title .MediaType.SubType)
}}
{{ $.AddResource $resource }}
{{ else }}
{{ errorf "Unable to get remote resource %s" $url }}
{{ end }}
{{ else }}
{{ errorf "Unable to get remote resource %s" $url }}
{{ end }}
{{ end }}
@@ -281,7 +280,7 @@ Step 4
With multilingual sites you can:
1. Create one content adapter for all languages using the [`EnableAllLanguages`](#enablealllanguages) method as described above.
2. Create content adapters unique to each language. See the examples below.
1. Create content adapters unique to each language. See the examples below.
### Translations by file name
@@ -352,8 +351,6 @@ To detect page collisions, use the `--printPathWarnings` flag when building your
[content formats]: /content-management/formats/#classification
[front matter field]: /content-management/front-matter/#fields
[logical path]: /getting-started/glossary/#logical-path
[media type]: https://en.wikipedia.org/wiki/Media_type
[page kind]: /getting-started/glossary/#page-kind
[syntax]: /templates/introduction/
[template functions]: /functions/
@@ -49,7 +49,7 @@ The pages can be referenced as follows:
{{</* relref "/blog/my-post.md" */>}}
```
index.md can be reference either by its path or by its containing folder without the ending `/`. \_index.md can be referenced only by its containing folder:
`index.md` can be reference either by its path or by its containing directory without the ending `/`. `_index.md` can be referenced only by its containing directory:
```text
{{</* ref "/about" */>}} <-- References /about/_index.md
@@ -12,21 +12,15 @@ toc: true
aliases: [/extras/datafiles/,/extras/datadrivencontent/,/doc/datafiles/,/templates/data-templates/]
---
Hugo can access and [unmarshal] local and remote data sources including CSV, JSON, TOML, YAML, and XML. Use this data to augment existing content or to create new content.
Hugo can access and [unmarshal](g) local and remote data sources including CSV, JSON, TOML, YAML, and XML. Use this data to augment existing content or to create new content.
[unmarshal]: /getting-started/glossary/#unmarshal
A data source might be a file in the data directory, a [global resource], a [page resource], or a [remote resource].
[global resource]: /getting-started/glossary/#global-resource
[page resource]: /getting-started/glossary/#page-resource
[remote resource]: /getting-started/glossary/#remote-resource
A data source might be a file in the `data` directory, a [global resource](g), a [page resource](g), or a [remote resource](g).
## Data directory
The data directory in the root of your project may contain one or more data files, in either a flat or nested tree. Hugo merges the data files to create a single data structure, accessible with the `Data` method on a `Site` object.
The `data` directory in the root of your project may contain one or more data files, in either a flat or nested tree. Hugo merges the data files to create a single data structure, accessible with the `Data` method on a `Site` object.
Hugo also merges data directories from themes and modules into this single data structure, where the data directory in the root of your project takes precedence.
Hugo also merges data directories from themes and modules into this single data structure, where the `data` directory in the root of your project takes precedence.
{{% note %}}
Hugo reads the combined data structure into memory and keeps it there for the entire build. For data that is infrequently accessed, use global or page resources instead.
@@ -42,7 +36,7 @@ project/
```
{{% note %}}
Do not place CSV files in the data directory. Access CSV files as page, global, or remote resources.
Do not place CSV files in the `data` directory. Access CSV files as page, global, or remote resources.
{{% /note %}}
See the documentation for the [`Data`] method on a `Site` object for details and examples.

Some files were not shown because too many files have changed in this diff Show More