From: Bjørn Erik Pedersen Date: Thu, 13 Feb 2025 09:40:34 +0000 (+0100) Subject: Merge commit 'a024bc7d76fcc5e49e8210f9b0896db9ef21861a' X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=304a7e5e7439a8a45449623057cad790c6053e4d;p=brevno-suite%2Fhugo Merge commit 'a024bc7d76fcc5e49e8210f9b0896db9ef21861a' --- 304a7e5e7439a8a45449623057cad790c6053e4d diff --cc docs/.codespellrc index 000000000,000000000..564fc77c0 new file mode 100644 --- /dev/null +++ b/docs/.codespellrc @@@ -1,0 -1,0 +1,13 @@@ ++# Config file for codespell. ++# https://github.com/codespell-project/codespell#using-a-config-file ++ ++[codespell] ++ ++# Comma separated list of dirs to be skipped. ++skip = _vendor,.cspell.json,chroma.css,chroma_dark.css ++ ++# Comma separated list of words to be ignored. Words must be lowercased. ++ignore-words-list = abl,edn,te,ue,trys,januar,womens,crossreferences ++ ++# Check file names as well. ++check-filenames = true diff --cc docs/.cspell.json index 6596a160c,000000000..8d51085ab mode 100644,000000..100644 --- a/docs/.cspell.json +++ b/docs/.cspell.json @@@ -1,177 -1,0 +1,182 @@@ +{ + "version": "0.2", + "allowCompoundWords": true, + "files": [ + "**/*.md" + ], + "flagWords": [ + "alot", + "hte", + "langauge", + "reccommend", + "seperate", + "teh" + ], + "ignorePaths": [ + "**/emojis.md", + "**/commands/*", + "**/showcase/*", + "**/tools/*" + ], + "ignoreRegExpList": [ + "# cspell: ignore fenced code blocks", + "^(\\s*`{3,}).*[\\s\\S]*?^\\1$", + "# cspell: ignore words joined with dot", + "\\w+\\.\\w+", + "# cspell: ignore strings within backticks", + "`.+`", + "# cspell: ignore strings within double quotes", + "\".+\"", + "# cspell: ignore strings within brackets", + "\\[.+\\]", + "# cspell: ignore strings within parentheses", + "\\(.+\\)", + "# cspell: ignore words that begin with a slash", + "/\\w+", + "# cspell: ignore everything within action delimiters", + "\\{\\{.+\\}\\}", + "# cspell: ignore everything after a right arrow", + "\\s+→\\s+.+" + ], + "language": "en", + "words": [ + "composability", + "configurators", + "defang", + "deindent", + "downscale", + "downscaling", + "exif", + "geolocalized", + "grayscale", + "marshal", + "marshaling", + "multihost", + "multiplatfom", + "performantly", + "preconfigured", + "prerendering", + "redirection", + "redirections", + "subexpression", + "suppressible", + "templating", + "transpile", + "unmarshal", + "unmarshaling", + "unmarshals", + "# ----------------------------------------------------------------------", + "# cspell: ignore hugo terminology", + "# ----------------------------------------------------------------------", ++ "alignx", + "attrlink", + "canonify", + "codeowners", + "dynacache", + "eturl", + "getenv", + "gohugo", + "gohugoio", + "keyvals", + "leftdelim", + "linkify", + "numworkermultiplier", + "rightdelim", + "shortcode", + "stringifier", + "struct", + "toclevels", ++ "unmarshal", + "unpublishdate", + "zgotmplz", + "# ----------------------------------------------------------------------", + "# cspell: ignore foreign language words", + "# ----------------------------------------------------------------------", + "bezpieczeństwo", + "blatt", + "buch", + "descripción", + "dokumentation", + "erklärungen", + "libros", + "mercredi", + "miesiąc", + "miesiąc", + "miesiąca", + "miesiące", + "miesięcy", + "misérables", + "mittwoch", + "muchos", + "novembre", + "otro", + "pocos", + "produkte", + "projekt", + "prywatność", + "referenz", + "régime", + "# ----------------------------------------------------------------------", + "# cspell: ignore names", + "# ----------------------------------------------------------------------", + "Atishay", + "Cosette", + "Eliott", + "Furet", + "Gregor", + "Jaco", + "Lanczos", + "Ninke", + "Noll", + "Pastorius", + "Samsa", + "Stucki", + "Thénardier", + "WASI", + "# ----------------------------------------------------------------------", + "# cspell: ignore operating systems and software packages", + "# ----------------------------------------------------------------------", + "asciidoctor", + "brotli", + "cifs", + "corejs", + "disqus", + "docutils", + "dpkg", + "doas", + "eopkg", + "gitee", + "goldmark", + "katex", + "kubuntu", + "lubuntu", + "mathjax", + "nosql", + "pandoc", + "pkgin", + "rclone", + "xubuntu", + "# ----------------------------------------------------------------------", + "# cspell: ignore miscellaneous", + "# ----------------------------------------------------------------------", + "achristie", ++ "ccpa", ++ "crpa", + "ddmaurier", + "dring", + "fleqn", + "inor", + "jausten", + "jdoe", + "jsmith", + "leqno", + "milli", + "rgba", + "rsmith", + "tdewolff", + "tjones", ++ "vcard", + "wcag", + "xfeff" + ] +} diff --cc docs/.github/ISSUE_TEMPLATE/config.yml index 000000000,000000000..3ba13e0ce new file mode 100644 --- /dev/null +++ b/docs/.github/ISSUE_TEMPLATE/config.yml @@@ -1,0 -1,0 +1,1 @@@ ++blank_issues_enabled: false diff --cc docs/.github/ISSUE_TEMPLATE/default.md index 000000000,000000000..ada35b3a5 new file mode 100644 --- /dev/null +++ b/docs/.github/ISSUE_TEMPLATE/default.md @@@ -1,0 -1,0 +1,6 @@@ ++--- ++name: Default ++about: This is the default issue template. ++labels: ++ - NeedsTriage ++--- diff --cc docs/.github/workflows/spellcheck.yml index 86f8f53a5,000000000..e01ab1764 mode 100644,000000..100644 --- a/docs/.github/workflows/spellcheck.yml +++ b/docs/.github/workflows/spellcheck.yml @@@ -1,22 -1,0 +1,27 @@@ +name: "Check spelling" +on: + push: + pull_request: + branches-ignore: + - "dependabot/**" + +permissions: + contents: read + +jobs: + spellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: streetsidesoftware/cspell-action@v5 + with: + check_dot_files: false + files: content/**/*.md + incremental_files_only: true + inline: warning + strict: false ++ - uses: codespell-project/actions-codespell@v2 ++ with: ++ check_filenames: true ++ check_hidden: true ++ # by default, codespell uses configuration from the .codespellrc diff --cc docs/.gitignore index f9cab2f80,000000000..debc86d46 mode 100644,000000..100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@@ -1,10 -1,0 +1,13 @@@ ++.DS_Store ++.hugo_build.lock +/.idea +/.vscode - /public +/dist - node_modules ++/public ++hugo_stats.json ++node_modules/ +nohup.out - .DS_Store - trace.out - .hugo_build.lock - resources/_gen/images/ ++package-lock.json ++public/ ++resources/ ++trace.out diff --cc docs/LICENSE.md index b09cd7856,000000000..979711275 mode 100644,000000..100644 --- a/docs/LICENSE.md +++ b/docs/LICENSE.md @@@ -1,201 -1,0 +1,3 @@@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ ++See [content/LICENSE.md](content/LICENSE.md) for the license of the content of this repository. + - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. ++The theme (layouts, CSS, JavaScript etc.) of this repository has no open source license. It is custom made for the Hugo sites and is not meant for reuse. diff --cc docs/README.md index 7550a93cd,000000000..64ba31a48 mode 100644,000000..100644 --- a/docs/README.md +++ b/docs/README.md @@@ -1,18 -1,0 +1,27 @@@ +Hugo + +A fast and flexible static site generator built with love by [bep], [spf13], and [friends] in [Go]. + +--- + +[![Netlify Status](https://api.netlify.com/api/v1/badges/e0dbbfc7-34f1-4393-a679-c16e80162705/deploy-status)](https://app.netlify.com/sites/gohugoio/deploys) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://gohugo.io/contribute/documentation/) + +This is the repository for the [Hugo](https://github.com/gohugoio/hugo) documentation site. + +Please see the [contributing] section for guidelines, examples, and process. + +[bep]: https://github.com/bep +[spf13]: https://github.com/spf13 +[friends]: https://github.com/gohugoio/hugo/graphs/contributors +[go]: https://go.dev/ +[contributing]: https://gohugo.io/contribute/documentation ++ ++# Install ++ ++```bash ++npm i ++hugo server ++``` ++ ++**Note:** We're working on removing the need to run `npm i` for local development. Stay tuned. diff --cc docs/archetypes/glossary.md index b38ced64a,000000000..4fa4669ec mode 100644,000000..100644 --- a/docs/archetypes/glossary.md +++ b/docs/archetypes/glossary.md @@@ -1,19 -1,0 +1,12 @@@ +--- +title: {{ replace .File.ContentBaseName "-" " " }} ++reference: +--- + + diff --cc docs/assets/css/components/all.css index 000000000,000000000..117f19998 new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/all.css @@@ -1,0 -1,0 +1,7 @@@ ++/* The ordeer of these does not matter. */ ++@import "./content.css"; ++@import "./fonts.css"; ++@import "./helpers.css"; ++@import "./shortcodes.css"; ++@import "./tableofcontents.css"; ++@import "./view-transitions.css"; diff --cc docs/assets/css/components/chroma.css index 000000000,000000000..9d4c91f7b new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/chroma.css @@@ -1,0 -1,0 +1,85 @@@ ++/* Background */ .bg { background-color: var(--color-light); } ++/* PreWrapper */ .chroma { background-color: var(--color-light); } ++/* Other */ .chroma .x { } ++/* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 } ++/* CodeLine */ .chroma .cl { } ++/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } ++/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } ++/* LineHighlight */ .chroma .hl { background-color: #ffffcc } ++/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } ++/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } ++/* Line */ .chroma .line { display: flex; } ++/* Keyword */ .chroma .k { font-weight: bold } ++/* KeywordConstant */ .chroma .kc { font-weight: bold } ++/* KeywordDeclaration */ .chroma .kd { font-weight: bold } ++/* KeywordNamespace */ .chroma .kn { font-weight: bold } ++/* KeywordPseudo */ .chroma .kp { font-weight: bold } ++/* KeywordReserved */ .chroma .kr { font-weight: bold } ++/* KeywordType */ .chroma .kt { color: #445588; font-weight: bold } ++/* Name */ .chroma .n { } ++/* NameAttribute */ .chroma .na { color: #008080 } ++/* NameBuiltin */ .chroma .nb { color: #999999 } ++/* NameBuiltinPseudo */ .chroma .bp { } ++/* NameClass */ .chroma .nc { color: #445588; font-weight: bold } ++/* NameConstant */ .chroma .no { color: #008080 } ++/* NameDecorator */ .chroma .nd { } ++/* NameEntity */ .chroma .ni { color: #800080 } ++/* NameException */ .chroma .ne { color: #990000; font-weight: bold } ++/* NameFunction */ .chroma .nf { color: #990000; font-weight: bold } ++/* NameFunctionMagic */ .chroma .fm { } ++/* NameLabel */ .chroma .nl { } ++/* NameNamespace */ .chroma .nn { color: #555555 } ++/* NameOther */ .chroma .nx { } ++/* NameProperty */ .chroma .py { } ++/* NameTag */ .chroma .nt { color: #000080 } ++/* NameVariable */ .chroma .nv { color: #008080 } ++/* NameVariableClass */ .chroma .vc { } ++/* NameVariableGlobal */ .chroma .vg { } ++/* NameVariableInstance */ .chroma .vi { } ++/* NameVariableMagic */ .chroma .vm { } ++/* Literal */ .chroma .l { } ++/* LiteralDate */ .chroma .ld { } ++/* LiteralString */ .chroma .s { color: #bb8844 } ++/* LiteralStringAffix */ .chroma .sa { color: #bb8844 } ++/* LiteralStringBacktick */ .chroma .sb { color: #bb8844 } ++/* LiteralStringChar */ .chroma .sc { color: #bb8844 } ++/* LiteralStringDelimiter */ .chroma .dl { color: #bb8844 } ++/* LiteralStringDoc */ .chroma .sd { color: #bb8844 } ++/* LiteralStringDouble */ .chroma .s2 { color: #bb8844 } ++/* LiteralStringEscape */ .chroma .se { color: #bb8844 } ++/* LiteralStringHeredoc */ .chroma .sh { color: #bb8844 } ++/* LiteralStringInterpol */ .chroma .si { color: #bb8844 } ++/* LiteralStringOther */ .chroma .sx { color: #bb8844 } ++/* LiteralStringRegex */ .chroma .sr { color: #808000 } ++/* LiteralStringSingle */ .chroma .s1 { color: #bb8844 } ++/* LiteralStringSymbol */ .chroma .ss { color: #bb8844 } ++/* LiteralNumber */ .chroma .m { color: #009999 } ++/* LiteralNumberBin */ .chroma .mb { color: #009999 } ++/* LiteralNumberFloat */ .chroma .mf { color: #009999 } ++/* LiteralNumberHex */ .chroma .mh { color: #009999 } ++/* LiteralNumberInteger */ .chroma .mi { color: #009999 } ++/* LiteralNumberIntegerLong */ .chroma .il { color: #009999 } ++/* LiteralNumberOct */ .chroma .mo { color: #009999 } ++/* Operator */ .chroma .o { font-weight: bold } ++/* OperatorWord */ .chroma .ow { font-weight: bold } ++/* Punctuation */ .chroma .p { } ++/* Comment */ .chroma .c { color: #999988; font-style: italic } ++/* CommentHashbang */ .chroma .ch { color: #999988; font-style: italic } ++/* CommentMultiline */ .chroma .cm { color: #999988; font-style: italic } ++/* CommentSingle */ .chroma .c1 { color: #999988; font-style: italic } ++/* CommentSpecial */ .chroma .cs { color: #999999; font-weight: bold; font-style: italic } ++/* CommentPreproc */ .chroma .cp { color: #999999; font-weight: bold } ++/* CommentPreprocFile */ .chroma .cpf { color: #999999; font-weight: bold } ++/* Generic */ .chroma .g { } ++/* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd } ++/* GenericEmph */ .chroma .ge { font-style: italic } ++/* GenericError */ .chroma .gr { color: #aa0000 } ++/* GenericHeading */ .chroma .gh { color: #999999 } ++/* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd } ++/* GenericOutput */ .chroma .go { color: #888888 } ++/* GenericPrompt */ .chroma .gp { color: #555555 } ++/* GenericStrong */ .chroma .gs { font-weight: bold } ++/* GenericSubheading */ .chroma .gu { color: #aaaaaa } ++/* GenericTraceback */ .chroma .gt { color: #aa0000 } ++/* GenericUnderline */ .chroma .gl { text-decoration: underline } ++/* TextWhitespace */ .chroma .w { color: #bbbbbb } diff --cc docs/assets/css/components/chroma_dark.css index 000000000,000000000..0dd9d7bfa new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/chroma_dark.css @@@ -1,0 -1,0 +1,85 @@@ ++/* Background */.dark .bg { background-color: var(--color-dark); } ++/* PreWrapper */ .dark .chroma { background-color: var(--color-dark); } ++/* Other */ .dark .chroma .x { } ++/* Error */ .dark .chroma .err { color: #ef6155 } ++/* CodeLine */ .dark .chroma .cl { } ++/* LineTableTD */ .dark .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } ++/* LineTable */ .dark .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } ++/* LineHighlight */ .dark .chroma .hl { background-color: #ffffcc } ++/* LineNumbersTable */ .dark .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } ++/* LineNumbers */ .dark .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } ++/* Line */ .dark .chroma .line { display: flex; } ++/* Keyword */ .dark .chroma .k { color: #815ba4 } ++/* KeywordConstant */ .dark .chroma .kc { color: #815ba4 } ++/* KeywordDeclaration */ .dark .chroma .kd { color: #815ba4 } ++/* KeywordNamespace */ .dark .chroma .kn { color: #5bc4bf } ++/* KeywordPseudo */ .dark .chroma .kp { color: #815ba4 } ++/* KeywordReserved */ .dark .chroma .kr { color: #815ba4 } ++/* KeywordType */ .dark .chroma .kt { color: #fec418 } ++/* Name */ .dark .chroma .n { } ++/* NameAttribute */ .dark .chroma .na { color: #06b6ef } ++/* NameBuiltin */ .dark .chroma .nb { } ++/* NameBuiltinPseudo */ .dark .chroma .bp { } ++/* NameClass */ .dark .chroma .nc { color: #fec418 } ++/* NameConstant */ .dark .chroma .no { color: #ef6155 } ++/* NameDecorator */ .dark .chroma .nd { color: #5bc4bf } ++/* NameEntity */ .dark .chroma .ni { } ++/* NameException */ .dark .chroma .ne { color: #ef6155 } ++/* NameFunction */ .dark .chroma .nf { color: #06b6ef } ++/* NameFunctionMagic */ .dark .chroma .fm { } ++/* NameLabel */ .dark .chroma .nl { } ++/* NameNamespace */ .dark .chroma .nn { color: #fec418 } ++/* NameOther */ .dark .chroma .nx { color: #06b6ef } ++/* NameProperty */ .dark .chroma .py { } ++/* NameTag */ .dark .chroma .nt { color: #5bc4bf } ++/* NameVariable */ .dark .chroma .nv { color: #ef6155 } ++/* NameVariableClass */ .dark .chroma .vc { } ++/* NameVariableGlobal */ .dark .chroma .vg { } ++/* NameVariableInstance */ .dark .chroma .vi { } ++/* NameVariableMagic */ .dark .chroma .vm { } ++/* Literal */ .dark .chroma .l { color: #f99b15 } ++/* LiteralDate */ .dark .chroma .ld { color: #48b685 } ++/* LiteralString */ .dark .chroma .s { color: #48b685 } ++/* LiteralStringAffix */ .dark .chroma .sa { color: #48b685 } ++/* LiteralStringBacktick */ .dark .chroma .sb { color: #48b685 } ++/* LiteralStringChar */ .dark .chroma .sc { } ++/* LiteralStringDelimiter */ .dark .chroma .dl { color: #48b685 } ++/* LiteralStringDoc */ .dark .chroma .sd { color: #776e71 } ++/* LiteralStringDouble */ .dark .chroma .s2 { color: #48b685 } ++/* LiteralStringEscape */ .dark .chroma .se { color: #f99b15 } ++/* LiteralStringHeredoc */ .dark .chroma .sh { color: #48b685 } ++/* LiteralStringInterpol */ .dark .chroma .si { color: #f99b15 } ++/* LiteralStringOther */ .dark .chroma .sx { color: #48b685 } ++/* LiteralStringRegex */ .dark .chroma .sr { color: #48b685 } ++/* LiteralStringSingle */ .dark .chroma .s1 { color: #48b685 } ++/* LiteralStringSymbol */ .dark .chroma .ss { color: #48b685 } ++/* LiteralNumber */ .dark .chroma .m { color: #f99b15 } ++/* LiteralNumberBin */ .dark .chroma .mb { color: #f99b15 } ++/* LiteralNumberFloat */ .dark .chroma .mf { color: #f99b15 } ++/* LiteralNumberHex */ .dark .chroma .mh { color: #f99b15 } ++/* LiteralNumberInteger */ .dark .chroma .mi { color: #f99b15 } ++/* LiteralNumberIntegerLong */ .dark .chroma .il { color: #f99b15 } ++/* LiteralNumberOct */ .dark .chroma .mo { color: #f99b15 } ++/* Operator */ .dark .chroma .o { color: #5bc4bf } ++/* OperatorWord */ .dark .chroma .ow { color: #5bc4bf } ++/* Punctuation */ .dark .chroma .p { } ++/* Comment */ .dark .chroma .c { color: #776e71 } ++/* CommentHashbang */ .dark .chroma .ch { color: #776e71 } ++/* CommentMultiline */ .dark .chroma .cm { color: #776e71 } ++/* CommentSingle */ .dark .chroma .c1 { color: #776e71 } ++/* CommentSpecial */ .dark .chroma .cs { color: #776e71 } ++/* CommentPreproc */ .dark .chroma .cp { color: #776e71 } ++/* CommentPreprocFile */ .dark .chroma .cpf { color: #776e71 } ++/* Generic */ .dark .chroma .g { } ++/* GenericDeleted */ .dark .chroma .gd { color: #ef6155 } ++/* GenericEmph */ .dark .chroma .ge { font-style: italic } ++/* GenericError */ .dark .chroma .gr { } ++/* GenericHeading */ .dark .chroma .gh { font-weight: bold } ++/* GenericInserted */ .dark .chroma .gi { color: #48b685 } ++/* GenericOutput */ .dark .chroma .go { } ++/* GenericPrompt */ .dark .chroma .gp { color: #776e71; font-weight: bold } ++/* GenericStrong */ .dark .chroma .gs { font-weight: bold } ++/* GenericSubheading */ .dark .chroma .gu { color: #5bc4bf; font-weight: bold } ++/* GenericTraceback */ .dark .chroma .gt { } ++/* GenericUnderline */ .dark .chroma .gl { } ++/* TextWhitespace */ .dark .chroma .w { } diff --cc docs/assets/css/components/content.css index 000000000,000000000..c52949625 new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/content.css @@@ -1,0 -1,0 +1,48 @@@ ++@import "./chroma_dark.css"; ++@import "./chroma.css"; ++@import "./highlight.css"; ++ ++/* Some contrast ratio fixes as reported by Google Page Speed. */ ++.chroma .c1 { ++ @apply text-gray-500; ++} ++ ++.dark .chroma .c1 { ++ @apply text-gray-400; ++} ++ ++.highlight code { ++ @apply text-sm; ++} ++ ++.content { ++ @apply prose prose-sm sm:prose-base prose-stone max-w-none dark:prose-invert dark:text-slate-200; ++ /* headings */ ++ @apply prose-h4:font-bold prose-h5:font-bold prose-h6:font-bold; ++ /* lead */ ++ @apply prose-lead:text-slate-500 prose-lead:text-xl prose-lead:mt-2 sm:prose-lead:mt-4 prose-lead:leading-relaxed dark:prose-lead:text-slate-400; ++ /* links */ ++ @apply prose-a:text-primary prose-a:hover:text-primary/70 prose-a:underline; ++ @apply prose-a:prose-code:underline prose-a:prose-code:hover:text-primary/70 prose-a:prose-code:hover:underline; ++ /* pre */ ++ @apply prose-pre:text-gray-800 prose-pre:border-1 prose-pre:border-gray-100 prose-pre:bg-light dark:prose-pre:bg-dark dark:prose-pre:ring-1 dark:prose-pre:ring-slate-300/10; ++ /* code */ ++ @apply prose-code:px-0.5 prose-code:text-gray-500 prose-code:dark:text-gray-300 border-none; ++ @apply prose-code:before:hidden prose-code:after:hidden prose-code:font-mono; ++ /* tables */ ++ @apply prose-table:border-2 prose-table:border-gray-100 prose-table:dark:border-gray-800 prose-table:relative prose-table:overflow-scroll prose-table:prose-th:font-bold prose-table:prose-th:bg-blue-500 dark:prose-table:prose-th:bg-blue-500/50 prose-table:prose-th:p-2 prose-table:prose-td:p-2 prose-table:prose-th:text-white; ++ /* hr */ ++ @apply dark:prose-hr:border-slate-800; ++ ++ h6 + * { ++ @apply mt-2; ++ } ++} ++ ++/* This will not match highlighting inside e.g. the code-toggle shortcode. */ ++/* For more fine grained control of this, see components/shortcodes.css. */ ++.content > .highlight, ++.content dd > .highlight, ++.content li > .highlight { ++ @apply border-1 border-gray-200 dark:border-slate-600 mt-6 mb-8; ++} diff --cc docs/assets/css/components/fonts.css index 000000000,000000000..06f40b4bf new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/fonts.css @@@ -1,0 -1,0 +1,15 @@@ ++@font-face { ++ font-family: "Mulish"; ++ font-style: normal; ++ src: url("../fonts/Mulish-VariableFont_wght.ttf") format("truetype"); ++ font-weight: 1 999; ++ font-display: swap; ++} ++ ++@font-face { ++ font-family: "Mulish"; ++ font-style: italic; ++ src: url("../fonts/Mulish-Italic-VariableFont_wght.ttf") format("truetype"); ++ font-weight: 1 999; ++ font-display: swap; ++} diff --cc docs/assets/css/components/helpers.css index 000000000,000000000..8eb6930b8 new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/helpers.css @@@ -1,0 -1,0 +1,19 @@@ ++/* Helper class to limit a text block to two lines. */ ++.two-lines-ellipsis { ++ display: block; ++ display: -webkit-box; ++ -webkit-line-clamp: 2; ++ -webkit-box-orient: vertical; ++ overflow: hidden; ++ text-overflow: ellipsis; ++} ++ ++/* Helper class to limit a text block to three lines. */ ++.three-lines-ellipsis { ++ display: block; ++ display: -webkit-box; ++ -webkit-line-clamp: 3; ++ -webkit-box-orient: vertical; ++ overflow: hidden; ++ text-overflow: ellipsis; ++} diff --cc docs/assets/css/components/highlight.css index 000000000,000000000..5f25fe368 new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/highlight.css @@@ -1,0 -1,0 +1,11 @@@ ++.highlight { ++ @apply bg-light dark:bg-dark rounded-none; ++} ++ ++.highlight pre { ++ @apply m-0 p-3 w-full h-full overflow-x-auto dark:border-black rounded-none; ++} ++ ++.highlight pre code { ++ @apply m-0 p-0 w-full h-full; ++} diff --cc docs/assets/css/components/shortcodes.css index 000000000,000000000..7314d5b20 new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/shortcodes.css @@@ -1,0 -1,0 +1,4 @@@ ++.shortcode-code { ++ .highlight { ++ } ++} diff --cc docs/assets/css/components/tableofcontents.css index 000000000,000000000..3640adf6d new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/tableofcontents.css @@@ -1,0 -1,0 +1,14 @@@ ++.tableofcontents { ++ ul { ++ @apply list-none; ++ li { ++ @apply mb-2; ++ a { ++ @apply text-primary; ++ &:hover { ++ @apply text-primary/60; ++ } ++ } ++ } ++ } ++} diff --cc docs/assets/css/components/view-transitions.css index 000000000,000000000..3e7217c4e new file mode 100644 --- /dev/null +++ b/docs/assets/css/components/view-transitions.css @@@ -1,0 -1,0 +1,22 @@@ ++/* Global slight fade */ ++::view-transition-old(root), ++::view-transition-new(root) { ++ animation-duration: 200ms; ++} ++ ++::view-transition-old(qr), ++::view-transition-new(qr) { ++ animation-duration: 800ms; ++ animation-delay: 250ms; ++} ++ ++.view-transition-qr { ++ view-transition-name: qr; ++} ++ ++/* Turbo styles */ ++.turbo-progress-bar { ++ @apply bg-blue-500; ++ opacity: 0.35; ++ height: 3px; ++} diff --cc docs/assets/css/styles.css index 000000000,000000000..cbe34e401 new file mode 100644 --- /dev/null +++ b/docs/assets/css/styles.css @@@ -1,0 -1,0 +1,123 @@@ ++@import "tailwindcss"; ++@plugin "@tailwindcss/typography"; ++@variant dark (&:where(.dark, .dark *)); ++ ++@import "components/all.css"; ++ ++/* TailwindCSS ignores files in .gitignore, so make it explicit. */ ++@source "hugo_stats.json"; ++ ++@theme { ++ /* Breakpoints. */ ++ --breakpoint-sm: 40rem; ++ --breakpoint-md: 48rem; ++ --breakpoint-lg: 68rem; /* Default 64rem; */ ++ --breakpoint-xl: 80rem; ++ --breakpoint-2xl: 96rem; ++ ++ /* Colors. */ ++ --color-primary: var(--color-blue-600); ++ --color-dark: #000; ++ --color-light: var(--color-gray-50); ++ --color-accent: var(--color-orange-500); ++ --color-accent-light: var(--color-pink-500); ++ --color-accent-dark: var(--color-green-500); ++ ++ /* https://www.tints.dev/blue/0594CB */ ++ --color-blue-50: #e1f6fe; ++ --color-blue-100: #c3edfe; ++ --color-blue-200: #88dbfc; ++ --color-blue-300: #4cc9fb; ++ --color-blue-400: #15b9f9; ++ --color-blue-500: #0594cb; ++ --color-blue-600: #0477a4; ++ --color-blue-700: #035677; ++ --color-blue-800: #023a50; ++ --color-blue-900: #011d28; ++ --color-blue-950: #000e14; ++ ++ /* https://www.tints.dev/orange/EBB951 */ ++ --color-orange-50: #fdf8ed; ++ --color-orange-100: #fbf1da; ++ --color-orange-200: #f7e4ba; ++ --color-orange-300: #f3d596; ++ --color-orange-400: #efc976; ++ --color-orange-500: #ebb951; ++ --color-orange-600: #e5a51a; ++ --color-orange-700: #a97a13; ++ --color-orange-800: #72520d; ++ --color-orange-900: #372806; ++ --color-orange-950: #1b1403; ++ ++ /* https://www.tints.dev/pink/FF4088 */ ++ --color-pink-50: #ffebf2; ++ --color-pink-100: #ffdbe9; ++ --color-pink-200: #ffb3d0; ++ --color-pink-300: #ff8fba; ++ --color-pink-400: #ff66a1; ++ --color-pink-500: #ff4088; ++ --color-pink-600: #ff0062; ++ --color-pink-700: #c2004a; ++ --color-pink-800: #800031; ++ --color-pink-900: #420019; ++ --color-pink-950: #1f000c; ++ ++ /* https://www.tints.dev/green/33BA91 */ ++ --color-green-50: #ebfaf5; ++ --color-green-100: #d3f3e9; ++ --color-green-200: #abe8d6; ++ --color-green-300: #7fdcc0; ++ --color-green-400: #53d0aa; ++ --color-green-500: #33ba91; ++ --color-green-600: #299474; ++ --color-green-700: #1f7058; ++ --color-green-800: #154c3b; ++ --color-green-900: #0a241c; ++ --color-green-950: #051410; ++ ++ /* Fonts. */ ++ --font-sans: "Mulish", ui-sans-serif, system-ui, sans-serif, ++ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; ++} ++ ++html { ++ scroll-padding-top: 100px; ++} ++ ++body { ++ @apply antialiased font-sans text-black dark:text-gray-100; ++} ++ ++.p-safe-area-x { ++ padding-left: env(safe-area-inset-left); ++ padding-right: env(safe-area-inset-right); ++} ++ ++.p-safe-area-y { ++ padding-top: env(safe-area-inset-top); ++ padding-bottom: env(safe-area-inset-bottom); ++} ++ ++.px-main { ++ padding-left: max(env(safe-area-inset-left), 1rem); ++ padding-right: max(env(safe-area-inset-right), 1rem); ++} ++ ++@media screen(md) { ++ .px-main { ++ padding-left: max(env(safe-area-inset-left), 2rem); ++ padding-right: max(env(safe-area-inset-right), 2rem); ++ } ++} ++ ++@media screen(lg) { ++ .px-main { ++ padding-left: max(env(safe-area-inset-left), 3rem); ++ padding-right: max(env(safe-area-inset-right), 3rem); ++ } ++} ++ ++/* Algolia DocSearch */ ++.algolia-docsearch-suggestion--highlight { ++ color: var(--color-primary); ++} diff --cc docs/assets/images/hugo-github-screenshot.png index 000000000,000000000..275b6969d new file mode 100644 Binary files differ diff --cc docs/assets/images/sponsors/Route4MeLogoBlueOnWhite.svg index 000000000,000000000..d4334e8d8 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/Route4MeLogoBlueOnWhite.svg @@@ -1,0 -1,0 +1,15 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --cc docs/assets/images/sponsors/bep-consulting.svg index 000000000,000000000..598a1eb71 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/bep-consulting.svg @@@ -1,0 -1,0 +1,4 @@@ ++ ++ ++ ++ diff --cc docs/assets/images/sponsors/butter-dark.svg index 000000000,000000000..657b75c50 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/butter-dark.svg @@@ -1,0 -1,0 +1,1 @@@ ++ diff --cc docs/assets/images/sponsors/butter-light.svg index 000000000,000000000..a0697df08 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/butter-light.svg @@@ -1,0 -1,0 +1,1 @@@ ++ diff --cc docs/assets/images/sponsors/cloudcannon-blue.svg index 000000000,000000000..79b13f431 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/cloudcannon-blue.svg @@@ -1,0 -1,0 +1,6 @@@ ++ ++ ++ ++ ++ ++ diff --cc docs/assets/images/sponsors/cloudcannon-white.svg index 000000000,000000000..83e319a6d new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/cloudcannon-white.svg @@@ -1,0 -1,0 +1,6 @@@ ++ ++ ++ ++ ++ ++ diff --cc docs/assets/images/sponsors/esolia-logo.svg index 000000000,000000000..3f5344c61 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/esolia-logo.svg @@@ -1,0 -1,0 +1,67 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --cc docs/assets/images/sponsors/goland.svg index 000000000,000000000..c32f25d7f new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/goland.svg @@@ -1,0 -1,0 +1,20 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --cc docs/assets/images/sponsors/graitykit-dark.svg index 000000000,000000000..fd7d12f5c new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/graitykit-dark.svg @@@ -1,0 -1,0 +1,3 @@@ ++ ++ ++ diff --cc docs/assets/images/sponsors/linode-logo.svg index 000000000,000000000..873678398 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/linode-logo.svg @@@ -1,0 -1,0 +1,1 @@@ ++ diff --cc docs/assets/images/sponsors/linode-logo_standard_light_medium.png index 000000000,000000000..269e6af84 new file mode 100644 Binary files differ diff --cc docs/assets/images/sponsors/your-company-dark.svg index 000000000,000000000..58fd601f5 new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/your-company-dark.svg @@@ -1,0 -1,0 +1,4 @@@ ++ ++ ++ ++ diff --cc docs/assets/images/sponsors/your-company.svg index 000000000,000000000..3b85ece5c new file mode 100644 --- /dev/null +++ b/docs/assets/images/sponsors/your-company.svg @@@ -1,0 -1,0 +1,4 @@@ ++ ++ ++ ++ diff --cc docs/assets/js/alpinejs/data/explorer.js index 000000000,000000000..4be8fb104 new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/data/explorer.js @@@ -1,0 -1,0 +1,123 @@@ ++var debug = 0 ? console.log.bind(console, '[explorer]') : function () {}; ++ ++// This is cureently not used, but kept in case I change my mind. ++export const explorer = (Alpine) => ({ ++ uiState: { ++ containerScrollTop: -1, ++ lastActiveRef: '', ++ }, ++ treeState: { ++ // The href of the current page. ++ currentNode: '', ++ // The state of each node in the tree. ++ nodes: {}, ++ ++ // We currently only list the sections, not regular pages, in the side bar. ++ // This strikes me as the right balance. The pages gets listed on the section pages. ++ // This array is sorted by length, so we can find the longest prefix of the current page ++ // without having to iterate over all the keys. ++ nodeRefsByLength: [], ++ }, ++ async init() { ++ let keys = Reflect.ownKeys(this.$refs); ++ for (let key of keys) { ++ let n = { ++ open: false, ++ active: false, ++ }; ++ this.treeState.nodes[key] = n; ++ this.treeState.nodeRefsByLength.push(key); ++ } ++ ++ this.treeState.nodeRefsByLength.sort((a, b) => b.length - a.length); ++ ++ this.setCurrentActive(); ++ }, ++ ++ longestPrefix(ref) { ++ let longestPrefix = ''; ++ for (let key of this.treeState.nodeRefsByLength) { ++ if (ref.startsWith(key)) { ++ longestPrefix = key; ++ break; ++ } ++ } ++ return longestPrefix; ++ }, ++ ++ setCurrentActive() { ++ let ref = this.longestPrefix(window.location.pathname); ++ let activeChanged = this.uiState.lastActiveRef !== ref; ++ debug('setCurrentActive', this.uiState.lastActiveRef, window.location.pathname, '=>', ref, activeChanged); ++ this.uiState.lastActiveRef = ref; ++ if (this.uiState.containerScrollTop === -1 && activeChanged) { ++ // Navigation outside of the explorer menu. ++ let el = document.querySelector(`[x-ref="${ref}"]`); ++ if (el) { ++ this.$nextTick(() => { ++ debug('scrolling to', ref); ++ el.scrollIntoView({ behavior: 'smooth', block: 'center' }); ++ }); ++ } ++ } ++ this.treeState.currentNode = ref; ++ for (let key in this.treeState.nodes) { ++ let n = this.treeState.nodes[key]; ++ n.active = false; ++ n.open = ref == key || ref.startsWith(key); ++ if (n.open) { ++ debug('open', key); ++ } ++ } ++ ++ let n = this.treeState.nodes[this.longestPrefix(ref)]; ++ if (n) { ++ n.active = true; ++ } ++ }, ++ ++ getScrollingContainer() { ++ return document.getElementById('leftsidebar'); ++ }, ++ ++ onLoad() { ++ debug('onLoad', this.uiState.containerScrollTop); ++ if (this.uiState.containerScrollTop >= 0) { ++ debug('onLoad: scrolling to', this.uiState.containerScrollTop); ++ this.getScrollingContainer().scrollTo(0, this.uiState.containerScrollTop); ++ } ++ this.uiState.containerScrollTop = -1; ++ }, ++ ++ onBeforeRender() { ++ debug('onBeforeRender', this.uiState.containerScrollTop); ++ this.setCurrentActive(); ++ }, ++ ++ toggleNode(ref) { ++ this.uiState.containerScrollTop = this.getScrollingContainer().scrollTop; ++ this.uiState.lastActiveRef = ''; ++ debug('toggleNode', ref, this.uiState.containerScrollTop); ++ ++ let node = this.treeState.nodes[ref]; ++ if (!node) { ++ debug('node not found', ref); ++ return; ++ } ++ let wasOpen = node.open; ++ }, ++ ++ isCurrent(ref) { ++ let n = this.treeState.nodes[ref]; ++ return n && n.active; ++ }, ++ ++ isOpen(ref) { ++ let node = this.treeState.nodes[ref]; ++ if (!node) return false; ++ if (node.open) { ++ debug('isOpen', ref); ++ } ++ return node.open; ++ }, ++}); diff --cc docs/assets/js/alpinejs/data/index.js index 000000000,000000000..7bf0532e3 new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/data/index.js @@@ -1,0 -1,0 +1,3 @@@ ++export * from './navbar'; ++export * from './search'; ++export * from './toc'; diff --cc docs/assets/js/alpinejs/data/navbar.js index 000000000,000000000..d2b119f0c new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/data/navbar.js @@@ -1,0 -1,0 +1,10 @@@ ++export const navbar = (Alpine) => ({ ++ init: function () { ++ Alpine.bind(this.$root, this.root); ++ }, ++ root: { ++ ['@scroll.window.debounce.10ms'](event) { ++ this.$store.nav.scroll.atTop = window.scrollY < 40 ? true : false; ++ }, ++ }, ++}); diff --cc docs/assets/js/alpinejs/data/search.js index 000000000,000000000..9be42617e new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/data/search.js @@@ -1,0 -1,0 +1,109 @@@ ++const designMode = false; ++ ++const groupByLvl0 = (array) => { ++ if (!array) return []; ++ return array.reduce((result, currentValue) => { ++ (result[currentValue.hierarchy.lvl0] = result[currentValue.hierarchy.lvl0] || []).push(currentValue); ++ return result; ++ }, {}); ++}; ++ ++const applyHelperFuncs = (array) => { ++ if (!array) return []; ++ return array.map((item) => { ++ item.getHeadingHTML = function () { ++ let lvl2 = this._highlightResult.hierarchy.lvl2; ++ let lvl3 = this._highlightResult.hierarchy.lvl3; ++ ++ if (!lvl3) { ++ if (lvl2) { ++ return lvl2.value; ++ } ++ return ''; ++ } ++ ++ if (!lvl2) { ++ return lvl3.value; ++ } ++ ++ return `${lvl2.value}  >  ${lvl3.value}`; ++ }; ++ return item; ++ }); ++}; ++ ++export const search = (Alpine, cfg) => ({ ++ query: designMode ? 'shortcodes' : '', ++ open: designMode, ++ result: {}, ++ ++ init() { ++ Alpine.bind(this.$root, this.root); ++ ++ this.checkOpen(); ++ return this.$nextTick(() => { ++ this.$watch('query', () => { ++ this.search(); ++ }); ++ }); ++ }, ++ toggleOpen: function () { ++ this.open = !this.open; ++ this.checkOpen(); ++ }, ++ checkOpen: function () { ++ if (!this.open) { ++ return; ++ } ++ this.search(); ++ this.$nextTick(() => { ++ this.$refs.input.focus(); ++ }); ++ }, ++ ++ search: function () { ++ if (!this.query) { ++ this.result = {}; ++ return; ++ } ++ var queries = { ++ requests: [ ++ { ++ indexName: cfg.index, ++ params: `query=${encodeURIComponent(this.query)}`, ++ attributesToHighlight: ['hierarchy', 'content'], ++ attributesToRetrieve: ['hierarchy', 'url', 'content'], ++ }, ++ ], ++ }; ++ ++ const host = `https://${cfg.app_id}-dsn.algolia.net`; ++ const url = `${host}/1/indexes/*/queries`; ++ ++ fetch(url, { ++ method: 'POST', ++ headers: { ++ 'X-Algolia-Application-Id': cfg.app_id, ++ 'X-Algolia-API-Key': cfg.api_key, ++ }, ++ body: JSON.stringify(queries), ++ }) ++ .then((response) => response.json()) ++ .then((data) => { ++ this.result = groupByLvl0(applyHelperFuncs(data.results[0].hits)); ++ }); ++ }, ++ root: { ++ ['@click']() { ++ if (!this.open) { ++ this.toggleOpen(); ++ } ++ }, ++ ['@search-toggle.window']() { ++ this.toggleOpen(); ++ }, ++ ['@keydown.meta.k.window.prevent']() { ++ this.toggleOpen(); ++ }, ++ }, ++}); diff --cc docs/assets/js/alpinejs/data/toc.js index 000000000,000000000..3da9f7eac new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/data/toc.js @@@ -1,0 -1,0 +1,71 @@@ ++var debug = 0 ? console.log.bind(console, '[toc]') : function () {}; ++ ++export const toc = (Alpine) => ({ ++ contentScrollSpy: null, ++ activeHeading: '', ++ justClicked: false, ++ ++ setActive(id) { ++ debug('setActive', id); ++ this.activeHeading = id; ++ // Prevent the intersection observer from changing the active heading right away. ++ this.justClicked = true; ++ setTimeout(() => { ++ this.justClicked = false; ++ }, 200); ++ }, ++ ++ init() { ++ this.$watch('$store.nav.scroll.atTop', (value) => { ++ if (!value) return; ++ this.activeHeading = ''; ++ this.$root.scrollTop = 0; ++ }); ++ ++ return this.$nextTick(() => { ++ let contentEl = document.getElementById('content'); ++ if (contentEl) { ++ const handleIntersect = (entries) => { ++ if (this.justClicked) { ++ return; ++ } ++ for (let entry of entries) { ++ if (entry.isIntersecting) { ++ let id = entry.target.id; ++ this.activeHeading = id; ++ let liEl = this.$refs[id]; ++ if (liEl) { ++ // If liEl is not in the viewport, scroll it into view. ++ let bounding = liEl.getBoundingClientRect(); ++ if (bounding.top < 0 || bounding.bottom > window.innerHeight) { ++ this.$root.scrollTop = liEl.offsetTop - 100; ++ } ++ } ++ debug('intersecting', id); ++ break; ++ } ++ } ++ }; ++ ++ let opts = { ++ rootMargin: '0px 0px -75%', ++ threshold: 0.75, ++ }; ++ ++ this.contentScrollSpy = new IntersectionObserver(handleIntersect, opts); ++ // Observe all headings. ++ let headings = contentEl.querySelectorAll('h2, h3, h4, h5, h6'); ++ for (let heading of headings) { ++ this.contentScrollSpy.observe(heading); ++ } ++ } ++ }); ++ }, ++ ++ destroy() { ++ if (this.contentScrollSpy) { ++ debug('disconnecting'); ++ this.contentScrollSpy.disconnect(); ++ } ++ }, ++}); diff --cc docs/assets/js/alpinejs/magics/helpers.js index 000000000,000000000..de9fa24e9 new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/magics/helpers.js @@@ -1,0 -1,0 +1,36 @@@ ++'use strict'; ++ ++export function registerMagics(Alpine) { ++ Alpine.magic('copy', (currentEl) => { ++ return function (el) { ++ if (!el) { ++ el = currentEl; ++ } ++ ++ // Select the element to copy. ++ let range = document.createRange(); ++ range.selectNode(el); ++ window.getSelection().removeAllRanges(); ++ window.getSelection().addRange(range); ++ ++ // Remove the selection after some time. ++ setTimeout(() => { ++ window.getSelection().removeAllRanges(); ++ }, 500); ++ ++ // Trim whitespace. ++ let text = el.textContent.trim(); ++ ++ navigator.clipboard.writeText(text); ++ }; ++ }); ++ ++ Alpine.magic('isScrollX', (currentEl) => { ++ return function (el) { ++ if (!el) { ++ el = currentEl; ++ } ++ return el.clientWidth < el.scrollWidth; ++ }; ++ }); ++} diff --cc docs/assets/js/alpinejs/magics/index.js index 000000000,000000000..c5f595cf9 new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/magics/index.js @@@ -1,0 -1,0 +1,1 @@@ ++export * from './helpers'; diff --cc docs/assets/js/alpinejs/stores/index.js index 000000000,000000000..17e2a347b new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/stores/index.js @@@ -1,0 -1,0 +1,1 @@@ ++export * from './nav.js'; diff --cc docs/assets/js/alpinejs/stores/nav.js index 000000000,000000000..c5620cf7c new file mode 100644 --- /dev/null +++ b/docs/assets/js/alpinejs/stores/nav.js @@@ -1,0 -1,0 +1,94 @@@ ++var debug = 1 ? console.log.bind(console, '[navStore]') : function () {}; ++ ++var ColorScheme = { ++ System: 1, ++ Light: 2, ++ Dark: 3, ++}; ++ ++const localStorageUserSettingsKey = 'hugoDocsUserSettings'; ++ ++export const navStore = (Alpine) => ({ ++ init() { ++ // There is no $watch available in Alpine stores, ++ // but this has the same effect. ++ this.userSettings.onColorSchemeChanged = Alpine.effect(() => { ++ if (this.userSettings.settings.colorScheme) { ++ this.userSettings.isDark = isDark(this.userSettings.settings.colorScheme); ++ toggleDarkMode(this.userSettings.isDark); ++ } ++ }); ++ ++ // Also react to changes in system settings. ++ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { ++ this.userSettings.setColorScheme(ColorScheme.System); ++ }); ++ }, ++ ++ destroy() {}, ++ ++ scroll: { ++ atTop: true, ++ }, ++ ++ userSettings: { ++ // settings gets persisted between page navigations. ++ settings: Alpine.$persist({ ++ // light, dark or system mode. ++ // If not set, we use the OS setting. ++ colorScheme: ColorScheme.System, ++ // Used to show the most relevant tab in config listings etc. ++ configFileType: 'toml', ++ }).as(localStorageUserSettingsKey), ++ ++ isDark: false, ++ ++ setColorScheme(colorScheme) { ++ this.settings.colorScheme = colorScheme; ++ this.isDark = isDark(colorScheme); ++ }, ++ ++ toggleColorScheme() { ++ let next = this.settings.colorScheme + 1; ++ if (next > ColorScheme.Dark) { ++ next = ColorScheme.System; ++ } ++ this.setColorScheme(next); ++ }, ++ colorScheme() { ++ return this.settings.colorScheme ? this.settings.colorScheme : ColorScheme.System; ++ }, ++ }, ++}); ++ ++function isMediaDark() { ++ return window.matchMedia('(prefers-color-scheme: dark)').matches; ++} ++ ++function isDark(colorScheme) { ++ if (!colorScheme || colorScheme == ColorScheme.System) { ++ return isMediaDark(); ++ } ++ ++ return colorScheme == ColorScheme.Dark; ++} ++ ++export function initColorScheme() { ++ // The AlpineJS store has not have been initialized yet, so access the ++ // localStorage directly. ++ let settingsJSON = localStorage[localStorageUserSettingsKey]; ++ if (settingsJSON) { ++ let settings = JSON.parse(settingsJSON); ++ toggleDarkMode(isDark(settings.colorScheme)); ++ return; ++ } ++ toggleDarkMode(isDark(null)); ++} ++ ++const toggleDarkMode = function (dark) { ++ if (dark) { ++ document.body.classList.add('dark'); ++ } else { ++ document.body.classList.remove('dark'); ++ } ++}; diff --cc docs/assets/js/body-start.js index 000000000,000000000..f9b596671 new file mode 100644 --- /dev/null +++ b/docs/assets/js/body-start.js @@@ -1,0 -1,0 +1,6 @@@ ++import { initColorScheme } from './alpinejs/stores/index'; ++ ++(function () { ++ // This allows us to initialize the color scheme before AlpineJS etc. is loaded. ++ initColorScheme(); ++})(); diff --cc docs/assets/js/head-early.js index 000000000,000000000..250bdd6cb new file mode 100644 --- /dev/null +++ b/docs/assets/js/head-early.js @@@ -1,0 -1,0 +1,16 @@@ ++import { scrollToActive } from 'js/helpers/index'; ++ ++(function () { ++ // Now we know that the browser has JS enabled. ++ document.documentElement.classList.remove('no-js'); ++ ++ // Add os-macos class to body if user is using macOS. ++ if (navigator.userAgent.indexOf('Mac') > -1) { ++ document.documentElement.classList.add('os-macos'); ++ } ++ ++ // Wait for the DOM to be ready. ++ document.addEventListener('DOMContentLoaded', function () { ++ scrollToActive('DOMContentLoaded'); ++ }); ++})(); diff --cc docs/assets/js/helpers/bridgeTurboAndAlpine.js index 000000000,000000000..0494d02f2 new file mode 100644 --- /dev/null +++ b/docs/assets/js/helpers/bridgeTurboAndAlpine.js @@@ -1,0 -1,0 +1,67 @@@ ++export function bridgeTurboAndAlpine(Alpine) { ++ document.addEventListener('turbo:before-render', (event) => { ++ event.detail.newBody.querySelectorAll('[data-alpine-generated]').forEach((el) => { ++ if (el.hasAttribute('data-alpine-generated')) { ++ el.removeAttribute('data-alpine-generated'); ++ el.remove(); ++ } ++ }); ++ }); ++ ++ document.addEventListener('turbo:render', () => { ++ if (document.documentElement.hasAttribute('data-turbo-preview')) { ++ return; ++ } ++ ++ document.querySelectorAll('[data-alpine-ignored]').forEach((el) => { ++ el.removeAttribute('x-ignore'); ++ el.removeAttribute('data-alpine-ignored'); ++ }); ++ ++ document.body.querySelectorAll('[x-data]').forEach((el) => { ++ if (el.hasAttribute('data-turbo-permanent')) { ++ return; ++ } ++ Alpine.initTree(el); ++ }); ++ ++ Alpine.startObservingMutations(); ++ }); ++ ++ // Cleanup Alpine state on navigation. ++ document.addEventListener('turbo:before-cache', () => { ++ // This will be restarted in turbo:render. ++ Alpine.stopObservingMutations(); ++ ++ document.body.querySelectorAll('[data-turbo-permanent]').forEach((el) => { ++ if (!el.hasAttribute('x-ignore')) { ++ el.setAttribute('x-ignore', true); ++ el.setAttribute('data-alpine-ignored', true); ++ } ++ }); ++ ++ document.body.querySelectorAll('[x-for],[x-if],[x-teleport]').forEach((el) => { ++ if (el.hasAttribute('x-for') && el._x_lookup) { ++ Object.values(el._x_lookup).forEach((el) => el.setAttribute('data-alpine-generated', true)); ++ } ++ ++ if (el.hasAttribute('x-if') && el._x_currentIfEl) { ++ el._x_currentIfEl.setAttribute('data-alpine-generated', true); ++ } ++ ++ if (el.hasAttribute('x-teleport') && el._x_teleport) { ++ el._x_teleport.setAttribute('data-alpine-generated', true); ++ } ++ }); ++ ++ document.body.querySelectorAll('[x-data]').forEach((el) => { ++ if (!el.hasAttribute('data-turbo-permanent')) { ++ Alpine.destroyTree(el); ++ // Turbo leaks DOM elements via their data-turbo-permanent handling. ++ // That needs to be fixed upstream, but until then. ++ let clone = el.cloneNode(true); ++ el.replaceWith(clone); ++ } ++ }); ++ }); ++} diff --cc docs/assets/js/helpers/helpers.js index 000000000,000000000..818eac40c new file mode 100644 --- /dev/null +++ b/docs/assets/js/helpers/helpers.js @@@ -1,0 -1,0 +1,17 @@@ ++export const scrollToActive = (when) => { ++ let els = document.querySelectorAll('.scroll-active'); ++ if (!els.length) { ++ return; ++ } ++ els.forEach((el) => { ++ // Find scrolling container. ++ let container = el.closest('[data-turbo-preserve-scroll-container]'); ++ if (container) { ++ // Avoid scrolling if el is already in view. ++ if (el.offsetTop >= container.scrollTop && el.offsetTop <= container.scrollTop + container.clientHeight) { ++ return; ++ } ++ container.scrollTop = el.offsetTop - container.offsetTop; ++ } ++ }); ++}; diff --cc docs/assets/js/helpers/index.js index 000000000,000000000..b02d81cf0 new file mode 100644 --- /dev/null +++ b/docs/assets/js/helpers/index.js @@@ -1,0 -1,0 +1,2 @@@ ++export * from './bridgeTurboAndAlpine'; ++export * from './helpers'; diff --cc docs/assets/js/main.js index 000000000,000000000..14440044b new file mode 100644 --- /dev/null +++ b/docs/assets/js/main.js @@@ -1,0 -1,0 +1,89 @@@ ++import Alpine from 'alpinejs'; ++import { registerMagics } from './alpinejs/magics/index'; ++import { navbar, search, toc } from './alpinejs/data/index'; ++import { navStore, initColorScheme } from './alpinejs/stores/index'; ++import { bridgeTurboAndAlpine } from './helpers/index'; ++import persist from '@alpinejs/persist'; ++import focus from '@alpinejs/focus'; ++ ++var debug = 0 ? console.log.bind(console, '[index]') : function () {}; ++ ++// Turbolinks init. ++(function () { ++ document.addEventListener('turbo:render', function (e) { ++ // This is also called right after the body start. This is added to prevent flicker on navigation. ++ initColorScheme(); ++ }); ++})(); ++ ++// Set up and start Alpine. ++(function () { ++ // Register AlpineJS plugins. ++ { ++ Alpine.plugin(focus); ++ Alpine.plugin(persist); ++ } ++ // Register AlpineJS magics and directives. ++ { ++ // Handles copy to clipboard etc. ++ registerMagics(Alpine); ++ } ++ ++ // Register AlpineJS controllers. ++ { ++ // Register AlpineJS data controllers. ++ let searchConfig = { ++ index: 'hugodocs', ++ app_id: 'D1BPLZHGYQ', ++ api_key: '6df94e1e5d55d258c56f60d974d10314', ++ }; ++ ++ Alpine.data('navbar', () => navbar(Alpine)); ++ Alpine.data('search', () => search(Alpine, searchConfig)); ++ Alpine.data('toc', () => toc(Alpine)); ++ } ++ ++ // Register AlpineJS stores. ++ { ++ Alpine.store('nav', navStore(Alpine)); ++ } ++ ++ // Start AlpineJS. ++ Alpine.start(); ++ ++ // Start the Turbo-Alpine bridge. ++ bridgeTurboAndAlpine(Alpine); ++ ++ { ++ let containerScrollTops = {}; ++ ++ // To preserve scroll position in scrolling elements on navigation add data-turbo-preserve-scroll-container="somename" to the scrolling container. ++ addEventListener('turbo:click', () => { ++ document.querySelectorAll('[data-turbo-preserve-scroll-container]').forEach((el2) => { ++ containerScrollTops[el2.dataset.turboPreserveScrollContainer] = el2.scrollTop; ++ }); ++ }); ++ ++ addEventListener('turbo:render', () => { ++ document.querySelectorAll('[data-turbo-preserve-scroll-container]').forEach((ele) => { ++ const containerScrollTop = containerScrollTops[ele.dataset.turboPreserveScrollContainer]; ++ if (containerScrollTop) { ++ ele.scrollTop = containerScrollTop; ++ } else { ++ let els = ele.querySelectorAll('.scroll-active'); ++ if (els.length) { ++ els.forEach((el) => { ++ // Avoid scrolling if el is already in view. ++ if (el.offsetTop >= ele.scrollTop && el.offsetTop <= ele.scrollTop + ele.clientHeight) { ++ return; ++ } ++ ele.scrollTop = el.offsetTop - ele.offsetTop; ++ }); ++ } ++ } ++ }); ++ ++ containerScrollTops = {}; ++ }); ++ } ++})(); diff --cc docs/assets/js/turbo.js index 000000000,000000000..c007896f6 new file mode 100644 --- /dev/null +++ b/docs/assets/js/turbo.js @@@ -1,0 -1,0 +1,1 @@@ ++import * as Turbo from '@hotwired/turbo'; diff --cc docs/assets/jsconfig.json index 000000000,000000000..377218ccb new file mode 100644 --- /dev/null +++ b/docs/assets/jsconfig.json @@@ -1,0 -1,0 +1,10 @@@ ++{ ++ "compilerOptions": { ++ "baseUrl": ".", ++ "paths": { ++ "*": [ ++ "*" ++ ] ++ } ++ } ++} diff --cc docs/assets/opengraph/gohugoio-card-base-1.png index 000000000,000000000..65555845b new file mode 100644 Binary files differ diff --cc docs/assets/opengraph/mulish-black.ttf index 000000000,000000000..db680a088 new file mode 100644 Binary files differ diff --cc docs/content/LICENSE.md index 000000000,000000000..b09cd7856 new file mode 100644 --- /dev/null +++ b/docs/content/LICENSE.md @@@ -1,0 -1,0 +1,201 @@@ ++Apache License ++ Version 2.0, January 2004 ++ http://www.apache.org/licenses/ ++ ++ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION ++ ++ 1. Definitions. ++ ++ "License" shall mean the terms and conditions for use, reproduction, ++ and distribution as defined by Sections 1 through 9 of this document. ++ ++ "Licensor" shall mean the copyright owner or entity authorized by ++ the copyright owner that is granting the License. ++ ++ "Legal Entity" shall mean the union of the acting entity and all ++ other entities that control, are controlled by, or are under common ++ control with that entity. For the purposes of this definition, ++ "control" means (i) the power, direct or indirect, to cause the ++ direction or management of such entity, whether by contract or ++ otherwise, or (ii) ownership of fifty percent (50%) or more of the ++ outstanding shares, or (iii) beneficial ownership of such entity. ++ ++ "You" (or "Your") shall mean an individual or Legal Entity ++ exercising permissions granted by this License. ++ ++ "Source" form shall mean the preferred form for making modifications, ++ including but not limited to software source code, documentation ++ source, and configuration files. ++ ++ "Object" form shall mean any form resulting from mechanical ++ transformation or translation of a Source form, including but ++ not limited to compiled object code, generated documentation, ++ and conversions to other media types. ++ ++ "Work" shall mean the work of authorship, whether in Source or ++ Object form, made available under the License, as indicated by a ++ copyright notice that is included in or attached to the work ++ (an example is provided in the Appendix below). ++ ++ "Derivative Works" shall mean any work, whether in Source or Object ++ form, that is based on (or derived from) the Work and for which the ++ editorial revisions, annotations, elaborations, or other modifications ++ represent, as a whole, an original work of authorship. For the purposes ++ of this License, Derivative Works shall not include works that remain ++ separable from, or merely link (or bind by name) to the interfaces of, ++ the Work and Derivative Works thereof. ++ ++ "Contribution" shall mean any work of authorship, including ++ the original version of the Work and any modifications or additions ++ to that Work or Derivative Works thereof, that is intentionally ++ submitted to Licensor for inclusion in the Work by the copyright owner ++ or by an individual or Legal Entity authorized to submit on behalf of ++ the copyright owner. For the purposes of this definition, "submitted" ++ means any form of electronic, verbal, or written communication sent ++ to the Licensor or its representatives, including but not limited to ++ communication on electronic mailing lists, source code control systems, ++ and issue tracking systems that are managed by, or on behalf of, the ++ Licensor for the purpose of discussing and improving the Work, but ++ excluding communication that is conspicuously marked or otherwise ++ designated in writing by the copyright owner as "Not a Contribution." ++ ++ "Contributor" shall mean Licensor and any individual or Legal Entity ++ on behalf of whom a Contribution has been received by Licensor and ++ subsequently incorporated within the Work. ++ ++ 2. Grant of Copyright License. Subject to the terms and conditions of ++ this License, each Contributor hereby grants to You a perpetual, ++ worldwide, non-exclusive, no-charge, royalty-free, irrevocable ++ copyright license to reproduce, prepare Derivative Works of, ++ publicly display, publicly perform, sublicense, and distribute the ++ Work and such Derivative Works in Source or Object form. ++ ++ 3. Grant of Patent License. Subject to the terms and conditions of ++ this License, each Contributor hereby grants to You a perpetual, ++ worldwide, non-exclusive, no-charge, royalty-free, irrevocable ++ (except as stated in this section) patent license to make, have made, ++ use, offer to sell, sell, import, and otherwise transfer the Work, ++ where such license applies only to those patent claims licensable ++ by such Contributor that are necessarily infringed by their ++ Contribution(s) alone or by combination of their Contribution(s) ++ with the Work to which such Contribution(s) was submitted. If You ++ institute patent litigation against any entity (including a ++ cross-claim or counterclaim in a lawsuit) alleging that the Work ++ or a Contribution incorporated within the Work constitutes direct ++ or contributory patent infringement, then any patent licenses ++ granted to You under this License for that Work shall terminate ++ as of the date such litigation is filed. ++ ++ 4. Redistribution. You may reproduce and distribute copies of the ++ Work or Derivative Works thereof in any medium, with or without ++ modifications, and in Source or Object form, provided that You ++ meet the following conditions: ++ ++ (a) You must give any other recipients of the Work or ++ Derivative Works a copy of this License; and ++ ++ (b) You must cause any modified files to carry prominent notices ++ stating that You changed the files; and ++ ++ (c) You must retain, in the Source form of any Derivative Works ++ that You distribute, all copyright, patent, trademark, and ++ attribution notices from the Source form of the Work, ++ excluding those notices that do not pertain to any part of ++ the Derivative Works; and ++ ++ (d) If the Work includes a "NOTICE" text file as part of its ++ distribution, then any Derivative Works that You distribute must ++ include a readable copy of the attribution notices contained ++ within such NOTICE file, excluding those notices that do not ++ pertain to any part of the Derivative Works, in at least one ++ of the following places: within a NOTICE text file distributed ++ as part of the Derivative Works; within the Source form or ++ documentation, if provided along with the Derivative Works; or, ++ within a display generated by the Derivative Works, if and ++ wherever such third-party notices normally appear. The contents ++ of the NOTICE file are for informational purposes only and ++ do not modify the License. You may add Your own attribution ++ notices within Derivative Works that You distribute, alongside ++ or as an addendum to the NOTICE text from the Work, provided ++ that such additional attribution notices cannot be construed ++ as modifying the License. ++ ++ You may add Your own copyright statement to Your modifications and ++ may provide additional or different license terms and conditions ++ for use, reproduction, or distribution of Your modifications, or ++ for any such Derivative Works as a whole, provided Your use, ++ reproduction, and distribution of the Work otherwise complies with ++ the conditions stated in this License. ++ ++ 5. Submission of Contributions. Unless You explicitly state otherwise, ++ any Contribution intentionally submitted for inclusion in the Work ++ by You to the Licensor shall be under the terms and conditions of ++ this License, without any additional terms or conditions. ++ Notwithstanding the above, nothing herein shall supersede or modify ++ the terms of any separate license agreement you may have executed ++ with Licensor regarding such Contributions. ++ ++ 6. Trademarks. This License does not grant permission to use the trade ++ names, trademarks, service marks, or product names of the Licensor, ++ except as required for reasonable and customary use in describing the ++ origin of the Work and reproducing the content of the NOTICE file. ++ ++ 7. Disclaimer of Warranty. Unless required by applicable law or ++ agreed to in writing, Licensor provides the Work (and each ++ Contributor provides its Contributions) on an "AS IS" BASIS, ++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or ++ implied, including, without limitation, any warranties or conditions ++ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A ++ PARTICULAR PURPOSE. You are solely responsible for determining the ++ appropriateness of using or redistributing the Work and assume any ++ risks associated with Your exercise of permissions under this License. ++ ++ 8. Limitation of Liability. In no event and under no legal theory, ++ whether in tort (including negligence), contract, or otherwise, ++ unless required by applicable law (such as deliberate and grossly ++ negligent acts) or agreed to in writing, shall any Contributor be ++ liable to You for damages, including any direct, indirect, special, ++ incidental, or consequential damages of any character arising as a ++ result of this License or out of the use or inability to use the ++ Work (including but not limited to damages for loss of goodwill, ++ work stoppage, computer failure or malfunction, or any and all ++ other commercial damages or losses), even if such Contributor ++ has been advised of the possibility of such damages. ++ ++ 9. Accepting Warranty or Additional Liability. While redistributing ++ the Work or Derivative Works thereof, You may choose to offer, ++ and charge a fee for, acceptance of support, warranty, indemnity, ++ or other liability obligations and/or rights consistent with this ++ License. However, in accepting such obligations, You may act only ++ on Your own behalf and on Your sole responsibility, not on behalf ++ of any other Contributor, and only if You agree to indemnify, ++ defend, and hold each Contributor harmless for any liability ++ incurred by, or claims asserted against, such Contributor by reason ++ of your accepting any such warranty or additional liability. ++ ++ END OF TERMS AND CONDITIONS ++ ++ APPENDIX: How to apply the Apache License to your work. ++ ++ To apply the Apache License to your work, attach the following ++ boilerplate notice, with the fields enclosed by brackets "[]" ++ replaced with your own identifying information. (Don't include ++ the brackets!) The text should be enclosed in the appropriate ++ comment syntax for the file format. We also recommend that a ++ file or class name and description of purpose be included on the ++ same "printed page" as the copyright notice for easier ++ identification within third-party archives. ++ ++ Copyright [yyyy] [name of copyright owner] ++ ++ 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. diff --cc docs/content/en/_common/_index.md index 000000000,000000000..4328d4d14 new file mode 100644 --- /dev/null +++ b/docs/content/en/_common/_index.md @@@ -1,0 -1,0 +1,13 @@@ ++--- ++cascade: ++ _build: ++ list: never ++ publishResources: false ++ render: never ++--- ++ ++ diff --cc docs/content/en/_common/scratch-pad-scope.md index 000000000,000000000..b659497d8 new file mode 100644 --- /dev/null +++ b/docs/content/en/_common/scratch-pad-scope.md @@@ -1,0 -1,0 +1,21 @@@ ++--- ++_comment: Do not remove front matter. ++--- ++ ++## Scope ++ ++The method or function used to create a scratch pad determines its scope. For example, use the `Store` method on a `Page` object to create a scratch pad scoped to the page. ++ ++Scope|Method or function ++:--|:-- ++page|[`PAGE.Store`] ++site|[`SITE.Store`] ++global|[`hugo.Store`] ++local|[`collections.NewScratch`] ++shortcode|[`SHORTCODE.Store`] ++ ++[`page.store`]: /methods/page/store ++[`site.store`]: /methods/site/store ++[`hugo.store`]: /functions/hugo/store ++[`collections.newscratch`]: functions/collections/newscratch ++[`shortcode.store`]: /methods/shortcode/store diff --cc docs/content/en/_common/store-methods.md index 000000000,000000000..074216f7b new file mode 100644 --- /dev/null +++ b/docs/content/en/_common/store-methods.md @@@ -1,0 -1,0 +1,86 @@@ ++--- ++# Do not remove front matter. ++--- ++ ++## Methods ++ ++###### Set ++ ++Sets the value of the given key. ++ ++```go-html-template ++{{ .Store.Set "greeting" "Hello" }} ++``` ++ ++###### Get ++ ++Gets the value of the given key. ++ ++```go-html-template ++{{ .Store.Set "greeting" "Hello" }} ++{{ .Store.Get "greeting" }} → Hello ++``` ++ ++###### Add ++ ++Adds the given value to the existing value(s) of the given key. ++ ++For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list. ++ ++```go-html-template ++{{ .Store.Set "greeting" "Hello" }} ++{{ .Store.Add "greeting" "Welcome" }} ++{{ .Store.Get "greeting" }} → HelloWelcome ++``` ++ ++```go-html-template ++{{ .Store.Set "total" 3 }} ++{{ .Store.Add "total" 7 }} ++{{ .Store.Get "total" }} → 10 ++``` ++ ++```go-html-template ++{{ .Store.Set "greetings" (slice "Hello") }} ++{{ .Store.Add "greetings" (slice "Welcome" "Cheers") }} ++{{ .Store.Get "greetings" }} → [Hello Welcome Cheers] ++``` ++ ++###### SetInMap ++ ++Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`. ++ ++```go-html-template ++{{ .Store.SetInMap "greetings" "english" "Hello" }} ++{{ .Store.SetInMap "greetings" "french" "Bonjour" }} ++{{ .Store.Get "greetings" }} → map[english:Hello french:Bonjour] ++``` ++ ++###### DeleteInMap ++ ++Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`. ++ ++```go-html-template ++{{ .Store.SetInMap "greetings" "english" "Hello" }} ++{{ .Store.SetInMap "greetings" "french" "Bonjour" }} ++{{ .Store.DeleteInMap "greetings" "english" }} ++{{ .Store.Get "greetings" }} → map[french:Bonjour] ++``` ++ ++###### GetSortedMapValues ++ ++Returns an array of values from `key` sorted by `mapKey`. ++ ++```go-html-template ++{{ .Store.SetInMap "greetings" "english" "Hello" }} ++{{ .Store.SetInMap "greetings" "french" "Bonjour" }} ++{{ .Store.GetSortedMapValues "greetings" }} → [Hello Bonjour] ++``` ++ ++###### Delete ++ ++Removes the given key. ++ ++```go-html-template ++{{ .Store.Set "greeting" "Hello" }} ++{{ .Store.Delete "greeting" }} ++``` diff --cc docs/content/en/about/_index.md index 333a9ba36,000000000..f15c38dcc mode 100644,000000..100644 --- a/docs/content/en/about/_index.md +++ b/docs/content/en/about/_index.md @@@ -1,16 -1,0 +1,16 @@@ +--- +title: About Hugo - linkTitle: In this section - description: Learn about Hugo and its features, security model, and privacy protections. ++linktitle: About ++description: Learn about Hugo and its features, privacy protections, and security model. +categories: [] +keywords: [] +menu: + docs: + identifier: about-hugo-in-this-section + parent: about + weight: 10 +weight: 10 +aliases: [/about-hugo/,/docs/] +--- + +Learn about Hugo and its features, privacy protections, and security model. diff --cc docs/content/en/about/features.md index c04f69686,000000000..883d53407 mode 100644,000000..100644 --- a/docs/content/en/about/features.md +++ b/docs/content/en/about/features.md @@@ -1,139 -1,0 +1,141 @@@ +--- +title: Features +description: Hugo's rich and powerful feature set provides the framework and tools to create static sites that build in seconds, often less. +categories: [about] +keywords: [] +menu: + docs: + parent: about + weight: 30 +weight: 30 +toc: true +--- + +## Framework + +[Multiplatform] +: Install Hugo's single executable on Linux, macOS, Windows, and more. + +[Multilingual] +: Localize your project for each language and region, including translations, images, dates, currencies, numbers, percentages, and collation sequence. Hugo's multilingual framework supports single-host and multihost configurations. + +[Output formats] +: Render each page of your site to one or more output formats, with granular control by page kind, section, and path. While HTML is the default output format, you can add JSON, RSS, CSV, and more. For example, create a REST API to access content. + +[Templates] +: Create templates using variables, functions, and methods to transform your content, resources, and data into a published page. While HTML templates are the most common, you can create templates for any output format. + +[Themes] +: Reduce development time and cost by using one of the hundreds of themes contributed by the Hugo community. Themes are available for corporate sites, documentation projects, image portfolios, landing pages, personal and professional blogs, resumes, CVs, and more. + +[Modules] +: Reduce development time and cost by creating or importing packaged combinations of archetypes, assets, content, data, templates, translation tables, static files, or configuration settings. A module may serve as the basis for a new site, or to augment an existing site. + +[Privacy] - : Configure the behavior of Hugo's embedded templates and shortcodes to facilitate compliance with regional privacy regulations, including the [GDPR] and [CCPA]. ++: Configure your site to help comply with regional privacy regulations. + +[Security] +: Hugo's security model is based on the premise that template and configuration authors are trusted, but content authors are not. This model enables generation of HTML output safe against code injection. Other protections prevent "shelling out" to arbitrary applications, limit access to specific environment variables, prevent connections to arbitrary remote data sources, and more. + +## Content authoring + +[Content formats] +: Create your content using Markdown, HTML, AsciiDoc, Emacs Org Mode, Pandoc, or reStructuredText. Markdown is the default content format, conforming to the [CommonMark] and [GitHub Flavored Markdown] specifications. + +[Markdown attributes] +: Apply HTML attributes such as `class` and `id` to Markdown images and block elements including blockquotes, fenced code blocks, headings, horizontal rules, lists, paragraphs, and tables. + +[Markdown extensions] +: Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more. + +[Markdown render hooks] +: Override the conversion of Markdown to HTML when rendering blockquotes, fenced code blocks, headings, images, links, and tables. For example, render every standalone image as an HTML `figure` element. + +[Diagrams] +: Use fenced code blocks and Markdown render hooks to include diagrams in your content. + +[Mathematics] +: 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. + +[Shortcodes] +: Use Hugo's embedded shortcodes, or create your own, to insert complex content. For example, use shortcodes to include `audio` and `video` elements, render tables from local or remote data sources, insert snippets from other pages, and more. + +## Content management + +[Content adapters] +: Create content adapters to dynamically add content when building your site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML. + +[Taxonomies] +: Classify content to establish simple or complex logical relationships between pages. For example, create an authors taxonomy, and assign one or more authors to each page. Among other uses, the taxonomy system provides an inverted, weighted index to render a list of related pages, ordered by relevance. + +[Data] +: Augment your content using local or remote data sources including CSV, JSON, TOML, YAML, and XML. For example, create a shortcode to render an HTML table from a remote CSV file. + +[Menus] +: Provide rapid access to content via Hugo's menu system, configured automatically, globally, or on a page-by-page basis. The menu system is a key component of Hugo's multilingual architecture. + +[URL management] +: Serve any page from any path via global configuration or on a page-by-page basis. + +## Asset pipelines + +[Image processing] +: Convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data. + +[JavaScript bundling] +: Transpile TypeScript and JSX to JavaScript, bundle, tree shake, minify, create source maps, and perform SRI hashing. + +[Sass processing] +: Transpile Sass to CSS, bundle, tree shake, minify, create source maps, perform SRI hashing, and integrate with PostCSS. + +[Tailwind CSS processing] +: Compile Tailwind CSS utility classes into standard CSS, bundle, tree shake, optimize, minify, perform SRI hashing, and integrate with PostCSS. + +## Performance + +[Caching] +: Reduce build time and cost by rendering a partial template once then cache the result, either globally or within a given context. For example, cache the result of an asset pipeline to prevent reprocessing on every rendered page. + +[Segmentation] +: Reduce build time and cost by partitioning your sites into segments. For example, render the home page and the "news section" every hour, and render the entire site once a week. + +[Minification] +: Minify HTML, CSS, and JavaScript to reduce file size, bandwidth consumption, and loading times. + - [CCPA]: https://en.wikipedia.org/wiki/California_Consumer_Privacy_Act - [Sass processing]: /functions/css/Sass/ - [Caching]: /functions/partials/includecached/ - [CommonMark]: https://spec.commonmark.org/current/ - [Content adapters]: /content-management/content-adapters/ ++[Multilingual]: /content-management/multilingual/ ++[Multiplatform]: /installation/ ++[Output formats]: /templates/output-formats/ ++[Templates]: /templates/introduction/ ++[Themes]: https://themes.gohugo.io/ ++[Modules]: /hugo-modules/ ++[Privacy]: /about/privacy/ ++[Security]: /about/security/ ++ +[Content formats]: /content-management/formats/ - [Data]: /content-management/data-sources/ - [Diagrams]: /content-management/diagrams/ - [GDPR]: https://en.wikipedia.org/wiki/General_Data_Protection_Regulation ++[CommonMark]: https://spec.commonmark.org/current/ +[GitHub Flavored Markdown]: https://github.github.com/gfm/ - [Image processing]: /content-management/image-processing/ - [JavaScript bundling]: /functions/js/build/ +[Markdown attributes]: /content-management/markdown-attributes/ +[Markdown extensions]: /getting-started/configuration-markup/#goldmark-extensions +[Markdown render hooks]: /render-hooks/introduction/ ++[Diagrams]: /content-management/diagrams/ +[Mathematics]: /content-management/mathematics/ - [Menus]: /content-management/menus/ - [Minification]: /getting-started/configuration/#configure-minify - [Modules]: /hugo-modules/ - [Multilingual]: /content-management/multilingual/ - [Multiplatform]: /installation/ - [Output formats]: /templates/output-formats/ - [Privacy]: /about/privacy/ - [Security]: /about/security/ - [Segmentation]: /getting-started/configuration/#configure-segments - [Shortcodes]: /content-management/shortcodes/ +[Syntax highlighting]: /content-management/syntax-highlighting/ - [Tailwind CSS processing]: /functions/css/tailwindcss/ ++[Shortcodes]: /content-management/shortcodes/ ++ ++[Content adapters]: /content-management/content-adapters/ +[Taxonomies]: /content-management/taxonomies/ - [Templates]: /templates/introduction/ - [Themes]: https://themes.gohugo.io/ ++[Data]: /content-management/data-sources/ ++[Menus]: /content-management/menus/ +[URL management]: /content-management/urls/ ++ ++[Image processing]: /content-management/image-processing/ ++[JavaScript bundling]: /functions/js/build/ ++[Sass processing]: /functions/css/Sass/ ++[Tailwind CSS processing]: /functions/css/tailwindcss/ ++ ++[Caching]: /functions/partials/includecached/ ++[Segmentation]: /getting-started/configuration/#configure-segments ++[Minification]: /getting-started/configuration/#configure-minify diff --cc docs/content/en/about/privacy.md index 425af0bcf,000000000..ef4faa793 mode 100644,000000..100644 --- a/docs/content/en/about/privacy.md +++ b/docs/content/en/about/privacy.md @@@ -1,122 -1,0 +1,52 @@@ +--- +title: Privacy +linkTitle: Privacy - description: Configure your site to facilitate compliance with regional privacy regulations. ++description: Configure your site to help comply with regional privacy regulations. +categories: [about] +keywords: ["GDPR", "Privacy", "Data Protection"] +menu: + docs: + parent: about + weight: 40 +weight: 40 +toc: true +aliases: [/gdpr/,/about/hugo-and-gdpr/] ++toc: true +--- + - General Data Protection Regulation ([GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation)) is a regulation in EU law on data protection and privacy for all individuals within the European Union and the European Economic Area. It became enforceable on 25 May 2018. - - **Hugo is a static site generator. By using Hugo you are already standing on very solid ground. Static HTML files on disk are much easier to reason about compared to server and database driven websites.** - - But even static websites can integrate with external services, so from version `0.41`, Hugo provides a **privacy configuration** that covers the relevant built-in templates. - - Note that: - - * These settings have their defaults setting set to _off_, i.e. how it worked before Hugo `0.41`. You must do your own evaluation of your site and apply the appropriate settings. - * These settings work with the [embedded templates](/templates/embedded/). Some theme may contain custom templates for embedding services like Google Analytics. In that case these options have no effect. - * We will continue this work and improve this further in future Hugo versions. - - ## All privacy settings - - Below are all privacy settings and their default value. These settings need to be put in your site configuration (e.g. `hugo.toml`). - - {{< code-toggle file=hugo >}} - [privacy] - [privacy.disqus] - disable = false - [privacy.googleAnalytics] - disable = false - respectDoNotTrack = false - [privacy.instagram] - disable = false - simple = false - [privacy.vimeo] - disable = false - enableDNT = false - simple = false - [privacy.x] - disable = false - enableDNT = false - simple = false - [privacy.youtube] - disable = false - privacyEnhanced = false - {{< /code-toggle >}} - - ## Disable all services - - An example privacy configuration that disables all the relevant services in Hugo. With this configuration, the other settings will not matter. - - {{< code-toggle file=hugo >}} - [privacy] - [privacy.disqus] - disable = true - [privacy.googleAnalytics] - disable = true - [privacy.instagram] - disable = true - [privacy.vimeo] - disable = true - [privacy.x] - disable = true - [privacy.youtube] - disable = true - {{< /code-toggle >}} - - ## The privacy settings explained - - ### GoogleAnalytics - - respectDoNotTrack - : Enabling this will make the GA templates respect the "Do Not Track" HTTP header. - - ### Instagram ++## Responsibility + - simple - : If simple mode is enabled, a static and no-JS version of the Instagram image card will be built. Note that this only supports image cards and the image itself will be fetched from Instagram's servers. ++Site authors are responsible for ensuring compliance with regional privacy regulations, including but not limited to: + - **Note:** If you use the _simple mode_ for Instagram and a site styled with Bootstrap 4, you may want to disable the inline styles provided by Hugo: ++- GDPR (General Data Protection Regulation): Applies to individuals within the European Union and the European Economic Area. ++- CCPA (California Consumer Privacy Act): Applies to California residents. ++- CPRA (California Privacy Rights Act): Expands upon the CCPA with stronger consumer privacy protections. ++- Virginia Consumer Data Protection Act (CDPA): Applies to businesses that collect, process, or sell the personal data of Virginia residents. + - {{< code-toggle file=hugo >}} - [services] - [services.instagram] - disableInlineCSS = true - {{< /code-toggle >}} ++Hugo's privacy settings can assist in compliance efforts. + - ### X ++## Embedded templates + - enableDNT - : 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. ++Hugo provides [embedded templates](g) to simplify site and content creation. Some of these templates interact with external services. For example, the `youtube` shortcode connects with YouTube's servers to embed videos on your site. + - simple - : If simple mode is enabled, a static and no-JS version of a post will be built. ++Some of these templates include settings to enhance privacy. + - **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.x] - disableInlineCSS = true - {{< /code-toggle >}} ++## Configuration + - ### YouTube ++{{% note %}} ++These settings affect the behavior of some of Hugo's embedded templates. These settings may or may not affect the behavior of templates provided by third parties in their modules or themes. ++{{% /note %}} + - privacyEnhanced - : When you turn on privacy-enhanced mode, YouTube won’t store information about visitors on your website unless the user plays the embedded video. ++These are the default privacy settings for Hugo's embedded templates: + - ### Vimeo ++{{< code-toggle config=privacy />}} + - enableDNT - : Enabling this for the vimeo shortcode, the Vimeo player will be blocked from tracking any session data, including all cookies and stats. ++See each template's documentation for a description of its privacy settings: + - simple - : If simple mode is enabled, the video thumbnail is fetched from Vimeo's servers and it is overlaid with a play button. If the user clicks to play the video, it will open in a new tab directly on Vimeo's website. ++- [Disqus partial](/templates/embedded/#privacy-disqus) ++- [Google Analytics partial](/templates/embedded/#privacy-google-analytics) ++- [Instagram shortcode](/shortcodes/instagram/#privacy) ++- [Vimeo shortcode](/shortcodes/vimeo/#privacy) ++- [X shortcode](/shortcodes/x/#privacy) ++- [YouTube shortcode](/shortcodes/youtube/#privacy) diff --cc docs/content/en/commands/_index.md index 000000000,000000000..89f673bf2 new file mode 100644 --- /dev/null +++ b/docs/content/en/commands/_index.md @@@ -1,0 -1,0 +1,12 @@@ ++--- ++title: Command line interface ++linkTitle: CLI ++description: Use the command line interface (CLI) to manage your site. ++categories: [] ++keywords: [] ++menu: ++ docs: ++ parent: commands ++ weight: 10 ++weight: 10 ++--- diff --cc docs/content/en/commands/hugo_gen.md index d6333b52d,000000000..ae11a0321 mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_gen.md +++ b/docs/content/en/commands/hugo_gen.md @@@ -1,43 -1,0 +1,43 @@@ +--- +title: "hugo gen" +slug: hugo_gen +url: /commands/hugo_gen/ +--- +## hugo gen + +Generate documentation and syntax highlighting styles + +### Synopsis + +Generate documentation for your project using Hugo's documentation engine, including syntax highlighting for various programming languages. + +### Options + +``` + -h, --help help for gen +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo](/commands/hugo/) - Build your site +* [hugo gen chromastyles](/commands/hugo_gen_chromastyles/) - Generate CSS stylesheet for the Chroma code highlighter - * [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI. ++* [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI +* [hugo gen man](/commands/hugo_gen_man/) - Generate man pages for the Hugo CLI + diff --cc docs/content/en/commands/hugo_gen_doc.md index 2c2c3a118,000000000..3d808e75c mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_gen_doc.md +++ b/docs/content/en/commands/hugo_gen_doc.md @@@ -1,50 -1,0 +1,50 @@@ +--- +title: "hugo gen doc" +slug: hugo_gen_doc +url: /commands/hugo_gen_doc/ +--- +## hugo gen doc + - Generate Markdown documentation for the Hugo CLI. ++Generate Markdown documentation for the Hugo CLI + +### Synopsis + +Generate Markdown documentation for the Hugo CLI. + This command is, mostly, used to create up-to-date documentation + of Hugo's command-line interface for https://gohugo.io/. + + It creates one Markdown file per command with front matter suitable + for rendering in Hugo. + +``` +hugo gen doc [flags] [args] +``` + +### Options + +``` + --dir string the directory to write the doc. (default "/tmp/hugodoc/") + -h, --help help for doc +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles + diff --cc docs/content/en/commands/hugo_mod.md index c037be6da,000000000..25a27185d mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod.md +++ b/docs/content/en/commands/hugo_mod.md @@@ -1,59 -1,0 +1,59 @@@ +--- +title: "hugo mod" +slug: hugo_mod +url: /commands/hugo_mod/ +--- +## hugo mod + +Manage modules + +### Synopsis + +Various helpers to help manage the modules in your project's dependency graph. +Most operations here requires a Go version installed on your system (>= Go 1.12) and the relevant VCS client (typically Git). +This is not needed if you only operate on modules inside /themes or if you have vendored them via "hugo mod vendor". + + +Note that Hugo will always start out by resolving the components defined in the site +configuration, provided by a _vendor directory (if no --ignoreVendorPaths flag provided), +Go Modules, or a folder inside the themes directory, in that order. + +See https://gohugo.io/hugo-modules/ for more information. + + + +### Options + +``` + -h, --help help for mod +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo](/commands/hugo/) - Build your site - * [hugo mod clean](/commands/hugo_mod_clean/) - Delete the Hugo Module cache for the current project. - * [hugo mod get](/commands/hugo_mod_get/) - Resolves dependencies in your current Hugo Project. - * [hugo mod graph](/commands/hugo_mod_graph/) - Print a module dependency graph. - * [hugo mod init](/commands/hugo_mod_init/) - Initialize this project as a Hugo Module. - * [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers. - * [hugo mod tidy](/commands/hugo_mod_tidy/) - Remove unused entries in go.mod and go.sum. - * [hugo mod vendor](/commands/hugo_mod_vendor/) - Vendor all module dependencies into the _vendor directory. - * [hugo mod verify](/commands/hugo_mod_verify/) - Verify dependencies. ++* [hugo mod clean](/commands/hugo_mod_clean/) - Delete the Hugo Module cache for the current project ++* [hugo mod get](/commands/hugo_mod_get/) - Resolves dependencies in your current Hugo project ++* [hugo mod graph](/commands/hugo_mod_graph/) - Print a module dependency graph ++* [hugo mod init](/commands/hugo_mod_init/) - Initialize this project as a Hugo Module ++* [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers ++* [hugo mod tidy](/commands/hugo_mod_tidy/) - Remove unused entries in go.mod and go.sum ++* [hugo mod vendor](/commands/hugo_mod_vendor/) - Vendor all module dependencies into the _vendor directory ++* [hugo mod verify](/commands/hugo_mod_verify/) - Verify dependencies + diff --cc docs/content/en/commands/hugo_mod_clean.md index 6f49284b7,000000000..ff2255e53 mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_clean.md +++ b/docs/content/en/commands/hugo_mod_clean.md @@@ -1,51 -1,0 +1,51 @@@ +--- +title: "hugo mod clean" +slug: hugo_mod_clean +url: /commands/hugo_mod_clean/ +--- +## hugo mod clean + - Delete the Hugo Module cache for the current project. ++Delete the Hugo Module cache for the current project + +### Synopsis + +Delete the Hugo Module cache for the current project. + +``` +hugo mod clean [flags] [args] +``` + +### Options + +``` + --all clean entire module cache + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --cacheDir string filesystem path to cache directory + -c, --contentDir string filesystem path to content directory + -h, --help help for clean + --pattern string pattern matching module paths to clean (all if not set), e.g. "**hugo*" + --renderSegments strings named segments to render (configured in the segments config) + -t, --theme strings themes to use (located in /themes/THEMENAME/) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules + diff --cc docs/content/en/commands/hugo_mod_get.md index 08e1e5c84,000000000..a5c9a9ea9 mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_get.md +++ b/docs/content/en/commands/hugo_mod_get.md @@@ -1,75 -1,0 +1,75 @@@ +--- +title: "hugo mod get" +slug: hugo_mod_get +url: /commands/hugo_mod_get/ +--- +## hugo mod get + - Resolves dependencies in your current Hugo Project. ++Resolves dependencies in your current Hugo project + +### Synopsis + + - Resolves dependencies in your current Hugo Project. ++Resolves dependencies in your current Hugo project. + +Some examples: + +Install the latest version possible for a given module: + + hugo mod get github.com/gohugoio/testshortcodes - ++ +Install a specific version: + + hugo mod get github.com/gohugoio/testshortcodes@v0.3.0 + +Install the latest versions of all direct module dependencies: + + hugo mod get + hugo mod get ./... (recursive) + +Install the latest versions of all module dependencies (direct and indirect): + + hugo mod get -u + hugo mod get -u ./... (recursive) + +Run "go help get" for more information. All flags available for "go get" is also relevant here. + +Note that Hugo will always start out by resolving the components defined in the site +configuration, provided by a _vendor directory (if no --ignoreVendorPaths flag provided), +Go Modules, or a folder inside the themes directory, in that order. + +See https://gohugo.io/hugo-modules/ for more information. + + + +``` +hugo mod get [flags] [args] +``` + +### Options + +``` + -h, --help help for get +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules + diff --cc docs/content/en/commands/hugo_mod_graph.md index b7bfc6bfe,000000000..cb2bdfb5a mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_graph.md +++ b/docs/content/en/commands/hugo_mod_graph.md @@@ -1,52 -1,0 +1,52 @@@ +--- +title: "hugo mod graph" +slug: hugo_mod_graph +url: /commands/hugo_mod_graph/ +--- +## hugo mod graph + - Print a module dependency graph. ++Print a module dependency graph + +### Synopsis + +Print a module dependency graph with information about module status (disabled, vendored). +Note that for vendored modules, that is the version listed and not the one from go.mod. + + +``` +hugo mod graph [flags] [args] +``` + +### Options + +``` + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --cacheDir string filesystem path to cache directory + --clean delete module cache for dependencies that fail verification + -c, --contentDir string filesystem path to content directory + -h, --help help for graph + --renderSegments strings named segments to render (configured in the segments config) + -t, --theme strings themes to use (located in /themes/THEMENAME/) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules + diff --cc docs/content/en/commands/hugo_mod_init.md index 0d9f1fd4e,000000000..3315e97d6 mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_init.md +++ b/docs/content/en/commands/hugo_mod_init.md @@@ -1,56 -1,0 +1,56 @@@ +--- +title: "hugo mod init" +slug: hugo_mod_init +url: /commands/hugo_mod_init/ +--- +## hugo mod init + - Initialize this project as a Hugo Module. ++Initialize this project as a Hugo Module + +### Synopsis + +Initialize this project as a Hugo Module. + It will try to guess the module path, but you may help by passing it as an argument, e.g: - ++ + hugo mod init github.com/gohugoio/testshortcodes - ++ + Note that Hugo Modules supports multi-module projects, so you can initialize a Hugo Module + inside a subfolder on GitHub, as one example. + + +``` +hugo mod init [flags] [args] +``` + +### Options + +``` + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --cacheDir string filesystem path to cache directory + -c, --contentDir string filesystem path to content directory + -h, --help help for init + --renderSegments strings named segments to render (configured in the segments config) + -t, --theme strings themes to use (located in /themes/THEMENAME/) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules + diff --cc docs/content/en/commands/hugo_mod_npm.md index 4c6b0c6a7,000000000..39a559e0f mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_npm.md +++ b/docs/content/en/commands/hugo_mod_npm.md @@@ -1,45 -1,0 +1,45 @@@ +--- +title: "hugo mod npm" +slug: hugo_mod_npm +url: /commands/hugo_mod_npm/ +--- +## hugo mod npm + - Various npm helpers. ++Various npm helpers + +### Synopsis + +Various npm (Node package manager) helpers. + +``` +hugo mod npm [command] [flags] +``` + +### Options + +``` + -h, --help help for npm +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules - * [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Experimental: Prepares and writes a composite package.json file for your project. ++* [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Experimental: Prepares and writes a composite package.json file for your project + diff --cc docs/content/en/commands/hugo_mod_npm_pack.md index ffbf0703e,000000000..5ece05769 mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_npm_pack.md +++ b/docs/content/en/commands/hugo_mod_npm_pack.md @@@ -1,59 -1,0 +1,59 @@@ +--- +title: "hugo mod npm pack" +slug: hugo_mod_npm_pack +url: /commands/hugo_mod_npm_pack/ +--- +## hugo mod npm pack + - Experimental: Prepares and writes a composite package.json file for your project. ++Experimental: Prepares and writes a composite package.json file for your project + +### Synopsis + +Prepares and writes a composite package.json file for your project. + +On first run it creates a "package.hugo.json" in the project root if not already there. This file will be used as a template file - with the base dependency set. ++with the base dependency set. + +This set will be merged with all "package.hugo.json" files found in the dependency tree, picking the version closest to the project. + +This command is marked as 'Experimental'. We think it's a great idea, so it's not likely to be +removed from Hugo, but we need to test this out in "real life" to get a feel of it, +so this may/will change in future versions of Hugo. + + +``` +hugo mod npm pack [flags] [args] +``` + +### Options + +``` + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --cacheDir string filesystem path to cache directory + -c, --contentDir string filesystem path to content directory + -h, --help help for pack + --renderSegments strings named segments to render (configured in the segments config) + -t, --theme strings themes to use (located in /themes/THEMENAME/) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + - * [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers. ++* [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers + diff --cc docs/content/en/commands/hugo_mod_tidy.md index cff192130,000000000..c7ae40625 mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_tidy.md +++ b/docs/content/en/commands/hugo_mod_tidy.md @@@ -1,45 -1,0 +1,45 @@@ +--- +title: "hugo mod tidy" +slug: hugo_mod_tidy +url: /commands/hugo_mod_tidy/ +--- +## hugo mod tidy + - Remove unused entries in go.mod and go.sum. ++Remove unused entries in go.mod and go.sum + +``` +hugo mod tidy [flags] [args] +``` + +### Options + +``` + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --cacheDir string filesystem path to cache directory + -c, --contentDir string filesystem path to content directory + -h, --help help for tidy + --renderSegments strings named segments to render (configured in the segments config) + -t, --theme strings themes to use (located in /themes/THEMENAME/) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules + diff --cc docs/content/en/commands/hugo_mod_vendor.md index 2b812e4c4,000000000..dc403affe mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_vendor.md +++ b/docs/content/en/commands/hugo_mod_vendor.md @@@ -1,51 -1,0 +1,51 @@@ +--- +title: "hugo mod vendor" +slug: hugo_mod_vendor +url: /commands/hugo_mod_vendor/ +--- +## hugo mod vendor + - Vendor all module dependencies into the _vendor directory. ++Vendor all module dependencies into the _vendor directory + +### Synopsis + +Vendor all module dependencies into the _vendor directory. + If a module is vendored, that is where Hugo will look for it's dependencies. + + +``` +hugo mod vendor [flags] [args] +``` + +### Options + +``` + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --cacheDir string filesystem path to cache directory + -c, --contentDir string filesystem path to content directory + -h, --help help for vendor + --renderSegments strings named segments to render (configured in the segments config) + -t, --theme strings themes to use (located in /themes/THEMENAME/) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules + diff --cc docs/content/en/commands/hugo_mod_verify.md index 051477c90,000000000..2f22a2e49 mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_mod_verify.md +++ b/docs/content/en/commands/hugo_mod_verify.md @@@ -1,50 -1,0 +1,50 @@@ +--- +title: "hugo mod verify" +slug: hugo_mod_verify +url: /commands/hugo_mod_verify/ +--- +## hugo mod verify + - Verify dependencies. ++Verify dependencies + +### Synopsis + +Verify checks that the dependencies of the current module, which are stored in a local downloaded source cache, have not been modified since being downloaded. + +``` +hugo mod verify [flags] [args] +``` + +### Options + +``` + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --cacheDir string filesystem path to cache directory + --clean delete module cache for dependencies that fail verification + -c, --contentDir string filesystem path to content directory + -h, --help help for verify + --renderSegments strings named segments to render (configured in the segments config) + -t, --theme strings themes to use (located in /themes/THEMENAME/) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo mod](/commands/hugo_mod/) - Manage modules + diff --cc docs/content/en/commands/hugo_server.md index 4ab161f8f,000000000..d735f449a mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_server.md +++ b/docs/content/en/commands/hugo_server.md @@@ -1,98 -1,0 +1,98 @@@ +--- +title: "hugo server" +slug: hugo_server +url: /commands/hugo_server/ +--- +## hugo server + +Start the embedded web server + +### Synopsis + +Hugo provides its own webserver which builds and serves the site. +While hugo server is high performance, it is a webserver with limited options. + +The `hugo server` command will by default write and serve files from disk, but +you can render to memory by using the `--renderToMemory` flag. This can be +faster in some cases, but it will consume more memory. + +By default hugo will also watch your files for any changes you make and +automatically rebuild the site. It will then live reload any open browser pages +and push the latest content to them. As most Hugo sites are built in a fraction +of a second, you will be able to save and see your changes nearly instantly. + +``` +hugo server [command] [flags] +``` + +### Options + +``` + --appendPort append port to baseURL (default true) + -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/ + --bind string interface to which the server will bind (default "127.0.0.1") + -D, --buildDrafts include content marked as draft + -E, --buildExpired include expired content + -F, --buildFuture include content with publishdate in the future + --cacheDir string filesystem path to cache directory + --cleanDestinationDir remove files from destination not found in static directories + -c, --contentDir string filesystem path to content directory + --disableBrowserError do not show build errors in the browser + --disableFastRender enables full re-renders on changes + --disableKinds strings disable different kind of pages (home, RSS etc.) + --disableLiveReload watch without enabling live browser reload on rebuild + --enableGitInfo add Git revision, date, author, and CODEOWNERS info to the pages + --forceSyncStatic copy all files when static is changed. + --gc enable to run some cleanup tasks (remove unused cache files) after the build + -h, --help help for server + --ignoreCache ignores the cache directory + -l, --layoutDir string filesystem path to layout directory + --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 + --noChmod don't sync permission mode of files + --noHTTPCache prevent HTTP caching + --noTimes don't sync modification time of files + -O, --openBrowser open the site in a browser after server startup + --panicOnWarning panic on first WARNING log + --poll string set this to a poll interval, e.g --poll 700ms, to use a poll based approach to watch for file system changes + -p, --port int port on which the server will listen (default 1313) + --pprof enable the pprof server (port 8080) + --printI18nWarnings print missing translations + --printMemoryUsage print memory usage to screen at intervals + --printPathWarnings print warnings on duplicate target paths etc. + --printUnusedTemplates print warnings on unused templates. + --renderSegments strings named segments to render (configured in the segments config) + --renderStaticToDisk serve static files from disk and dynamic files from memory + --templateMetrics display metrics about template executions + --templateMetricsHints calculate some improvement hints when combined with --templateMetrics + -t, --theme strings themes to use (located in /themes/THEMENAME/) + --tlsAuto generate and use locally-trusted certificates. + --tlsCertFile string path to TLS certificate file + --tlsKeyFile string path to TLS key file + --trace file write trace to file (not useful in general) + -w, --watch watch filesystem for changes and recreate as needed (default true) +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo](/commands/hugo/) - Build your site - * [hugo server trust](/commands/hugo_server_trust/) - Install the local CA in the system trust store. ++* [hugo server trust](/commands/hugo_server_trust/) - Install the local CA in the system trust store + diff --cc docs/content/en/commands/hugo_server_trust.md index 9d24e78e3,000000000..22ca2491e mode 100644,000000..100644 --- a/docs/content/en/commands/hugo_server_trust.md +++ b/docs/content/en/commands/hugo_server_trust.md @@@ -1,41 -1,0 +1,41 @@@ +--- +title: "hugo server trust" +slug: hugo_server_trust +url: /commands/hugo_server_trust/ +--- +## hugo server trust + - Install the local CA in the system trust store. ++Install the local CA in the system trust store + +``` +hugo server trust [flags] [args] +``` + +### Options + +``` + -h, --help help for trust + --uninstall Uninstall the local CA (but do not delete it). +``` + +### Options inherited from parent commands + +``` + --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00 + --config string config file (default is hugo.yaml|json|toml) + --configDir string config dir (default "config") + -d, --destination string filesystem path to write files to + -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 + --themesDir string filesystem path to themes directory +``` + +### SEE ALSO + +* [hugo server](/commands/hugo_server/) - Start the embedded web server + diff --cc docs/content/en/content-management/_index.md index 8fb0cf25e,000000000..21d0b8739 mode 100644,000000..100644 --- a/docs/content/en/content-management/_index.md +++ b/docs/content/en/content-management/_index.md @@@ -1,16 -1,0 +1,16 @@@ +--- +title: Content management - linkTitle: In this section ++ +description: Hugo makes managing large static sites easy with support for archetypes, content types, menus, cross references, summaries, and more. +categories: [] +keywords: [] +menu: + docs: + identifier: content-management-in-this-section + parent: content-management + weight: 10 +weight: 10 +aliases: [/content/,/content/organization] +--- + +A static site generator needs to extend beyond front matter and a couple of templates to be both scalable and *manageable*. Hugo was designed with not only developers in mind, but also content managers and authors. diff --cc docs/content/en/content-management/archetypes.md index 30747258c,000000000..966c847db mode 100644,000000..100644 --- a/docs/content/en/content-management/archetypes.md +++ b/docs/content/en/content-management/archetypes.md @@@ -1,193 -1,0 +1,193 @@@ +--- +title: Archetypes +description: An archetype is a template for new content. +categories: [content management] +keywords: [archetypes,generators,metadata,front matter] +menu: + docs: + parent: content-management + weight: 140 + quicklinks: +weight: 140 +toc: true +aliases: [/content/archetypes/] +--- + +## Overview + +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: + +{{< code-toggle file=archetypes/default.md fm=true >}} +title = '{{ replace .File.ContentBaseName `-` ` ` | title }}' +date = '{{ .Date }}' +draft = true +{{< /code-toggle >}} + +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 +``` + +With the default archetype shown above, Hugo creates this content file: + +{{< code-toggle file=content/posts/my-first-post.md fm=true >}} +title = 'My First Post' +date = '2023-08-24T11:49:46-07:00' +draft = true +{{< /code-toggle >}} + +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/ +├── default.md +└── posts.md +``` + +## Lookup order + +Hugo looks for archetypes in the `archetypes` directory in the root of your project, falling back to the `archetypes` directory in themes or installed modules. An archetype for a specific content type takes precedence over the default archetype. + +For example, with this command: + +```sh +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` + +If none of these exists, Hugo uses a built-in default archetype. + +## Functions and context + +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](g): + +Date +: (`string`) The current date and time, formatted in compliance with RFC3339. + +File - : (`hugolib.fileInfo`) Returns file information for the current page. See [details](/methods/page/file). ++: (`hugolib.fileInfo`) Returns file information for the current page. See [details](/methods/page/file). + +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/). ++: (`page.Site`) The current site object. See [details](/methods/site/). + +## Date format + +To insert date and time with a different format, use the [`time.Now`] function: + +[`time.Now`]: /functions/time/now/ + +{{< code-toggle file=archetypes/default.md fm=true >}} +title = '{{ replace .File.ContentBaseName `-` ` ` | title }}' +date = '{{ time.Now.Format "2006-01-02" }}' +draft = true +{{< /code-toggle >}} + +## Include content + +Although typically used as a front matter template, you can also use an archetype to populate content. + +For example, in a documentation site you might have a section (content type) for functions. Every page within this section should follow the same format: a brief description, the function signature, examples, and notes. We can pre-populate the page to remind content authors of the standard format. + +{{< code file=archetypes/functions.md >}} +--- +date: '{{ .Date }}' +draft: true +title: '{{ replace .File.ContentBaseName `-` ` ` | title }}' +--- + +A brief description of what the function does, using simple present tense in the third person singular form. For example: + +`someFunction` returns the string `s` repeated `n` times. + +## Signature + +```text +func someFunction(s string, n int) string +``` + +## Examples + +One or more practical examples, each within a fenced code block. + +## Notes + +Additional information to clarify as needed. +{{< /code >}} + +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](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. + +Create an archetype for galleries: + +```text +archetypes/ +├── galleries/ +│ ├── images/ +│ │ └── .gitkeep +│ └── index.md <-- same format as default.md +└── default.md +``` + +Subdirectories within an archetype must contain at least one file. Without a file, Hugo will not create the subdirectory when you create new content. The name and size of the file are irrelevant. The example above includes a `.gitkeep` file, an empty file commonly used to preserve otherwise empty directories in a Git repository. + +To create a new gallery: + +```sh +hugo new galleries/bryce-canyon +``` + +This produces: + +```text +content/ +├── galleries/ +│ └── bryce-canyon/ +│ ├── images/ +│ │ └── .gitkeep +│ └── index.md +└── _index.md +``` + +## Specify archetype + +Use the `--kind` command line flag to specify an archetype when creating content. + +For example, let's say your site has two sections: articles and tutorials. Create an archetype for each content type: + +```text +archetypes/ +├── articles.md +├── default.md +└── tutorials.md +``` + +To create an article using the articles archetype: + +```sh +hugo new content articles/something.md +``` + +To create an article using the tutorials archetype: + +```sh +hugo new content --kind tutorials articles/something.md +``` diff --cc docs/content/en/content-management/content-adapters.md index 369e91a12,000000000..420d49d9d mode 100644,000000..100644 --- a/docs/content/en/content-management/content-adapters.md +++ b/docs/content/en/content-management/content-adapters.md @@@ -1,356 -1,0 +1,356 @@@ +--- +title: Content adapters +description: Create content adapters to dynamically add content when building your site. +categories: [content management] +keywords: [] +menu: + docs: + parent: content-management + weight: 290 +weight: 290 +toc: true +--- + - {{< new-in 0.126.0 >}} ++{{< new-in 0.126.0 />}} + +## Overview + +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](g) will be relative to the content adapter. + +```text +content/ +├── articles/ +│ ├── _index.md +│ ├── article-1.md +│ └── article-2.md +├── books/ +│ ├── _content.gotmpl <-- content adapter +│ └── _index.md +└── films/ + ├── _content.gotmpl <-- content adapter + └── _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. + +## Methods + +Use these methods within a content adapter. + +###### AddPage + +Adds a page to the site. + +{{< code file=content/books/_content.gotmpl >}} +{{ $content := dict + "mediaType" "text/markdown" + "value" "The _Hunchback of Notre Dame_ was written by Victor Hugo." +}} +{{ $page := dict + "content" $content + "kind" "page" + "path" "the-hunchback-of-notre-dame" + "title" "The Hunchback of Notre Dame" +}} +{{ .AddPage $page }} +{{< /code >}} + +###### AddResource + +Adds a page resource to the site. + +{{< code file=content/books/_content.gotmpl >}} +{{ with resources.Get "images/a.jpg" }} + {{ $content := dict + "mediaType" .MediaType.Type + "value" . + }} + {{ $resource := dict + "content" $content + "path" "the-hunchback-of-notre-dame/cover.jpg" + }} + {{ $.AddResource $resource }} +{{ end }} +{{< /code >}} + +Then retrieve the new page resource with something like: + +{{< code file=layouts/_default/single.html >}} +{{ with .Resources.Get "cover.jpg" }} + +{{ end }} +{{< /code >}} + +###### Site + +Returns the `Site` to which the pages will be added. + +{{< code file=content/books/_content.gotmpl >}} +{{ .Site.Title }} +{{< /code >}} + +{{% note %}} +Note that the `Site` returned isn't fully built when invoked from the content adapters; if you try to call methods that depends on pages, e.g. `.Site.Pages`, you will get an error saying "this method cannot be called before the site is fully initialized". +{{% /note %}} + +###### Store + +Returns a persistent “scratch pad” to store and manipulate data. The main use case for this is to transfer values between executions when [EnableAllLanguages](#enablealllanguages) is set. See [examples](/methods/page/store/). + +{{< code file=content/books/_content.gotmpl >}} +{{ .Store.Set "key" "value" }} +{{ .Store.Get "key" }} +{{< /code >}} + +###### EnableAllLanguages + +By default, Hugo executes the content adapter for the language defined by the _content.gotmpl file . Use this method to activate the content adapter for all languages. + +{{< code file=content/books/_content.gotmpl >}} +{{ .EnableAllLanguages }} +{{ $content := dict + "mediaType" "text/markdown" + "value" "The _Hunchback of Notre Dame_ was written by Victor Hugo." +}} +{{ $page := dict + "content" $content + "kind" "page" + "path" "the-hunchback-of-notre-dame" + "title" "The Hunchback of Notre Dame" +}} +{{ .AddPage $page }} +{{< /code >}} + +## Page map + +Set any [front matter field] in the map passed to the [`AddPage`](#addpage) method, excluding `markup`. Instead of setting the `markup` field, specify the `content.mediaType` as described below. + +This table describes the fields most commonly passed to the `AddPage` method. + +Key|Description|Required +:--|:--|:-: +`content.mediaType`|The content [media type]. Default is `text/markdown`. See [content formats] for examples.|  +`content.value`|The content value as a string.|  +`dates.date`|The page creation date as a `time.Time` value.|  +`dates.expiryDate`|The page expiry date as a `time.Time` value.|  +`dates.lastmod`|The page last modification date as a `time.Time` value.|  +`dates.publishDate`|The page publication date as a `time.Time` value.|  +`params`|A map of page parameters.|  +`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.|  + +{{% note %}} +While `path` is the only required field, we recommend setting `title` as well. + +When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C` produces a logical path of `/section/a-b-c`. +{{% /note %}} + +## Resource map + +Construct the map passed to the [`AddResource`](#addresource) method using the fields below. + +Key|Description|Required +:--|:--|:-: +`content.mediaType`|The content [media type].|:heavy_check_mark: +`content.value`|The content value as a string or resource.|:heavy_check_mark: +`name`|The resource name.|  +`params`|A map of resource parameters.|  +`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.|  + +{{% note %}} +If the `content.value` is a string Hugo creates a new resource. If the `content.value` is a resource, Hugo obtains the value from the existing resource. + +When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C/cover.jpg` produces a logical path of `/section/a-b-c/cover.jpg`. +{{% /note %}} + +## Example + +Create pages from remote data, where each page represents a book review. + +Step 1 +: Create the content structure. + +```text +content/ +└── books/ + ├── _content.gotmpl <-- content adapter + └── _index.md +``` + +Step 2 +: Inspect the remote data to determine how to map key-value pairs to front matter fields. + +: + +Step 3 +: Create the content adapter. + +{{< code file=content/books/_content.gotmpl copy=true >}} +{{/* Get remote data. */}} +{{ $data := dict }} +{{ $url := "https://gohugo.io/shared/examples/data/books.json" }} +{{ with try (resources.GetRemote $url) }} + {{ with .Err }} + {{ errorf "Unable to get remote resource %s: %s" $url . }} + {{ else with .Value }} + {{ $data = . | transform.Unmarshal }} + {{ else }} + {{ errorf "Unable to get remote resource %s" $url }} + {{ end }} +{{ end }} + +{{/* Add pages and page resources. */}} +{{ range $data }} + + {{/* Add page. */}} + {{ $content := dict "mediaType" "text/markdown" "value" .summary }} + {{ $dates := dict "date" (time.AsTime .date) }} + {{ $params := dict "author" .author "isbn" .isbn "rating" .rating "tags" .tags }} + {{ $page := dict + "content" $content + "dates" $dates + "kind" "page" + "params" $params + "path" .title + "title" .title + }} + {{ $.AddPage $page }} + + {{/* Add page resource. */}} + {{ $item := . }} + {{ with $url := $item.cover }} + {{ with try (resources.GetRemote $url) }} + {{ with .Err }} + {{ errorf "Unable to get remote resource %s: %s" $url . }} + {{ else with .Value }} + {{ $content := dict "mediaType" .MediaType.Type "value" .Content }} + {{ $params := dict "alt" $item.title }} + {{ $resource := dict + "content" $content + "params" $params + "path" (printf "%s/cover.%s" $item.title .MediaType.SubType) + }} + {{ $.AddResource $resource }} + {{ else }} + {{ errorf "Unable to get remote resource %s" $url }} + {{ end }} + {{ end }} + {{ end }} + +{{ end }} +{{< /code >}} + +Step 4 +: Create a single template to render each book review. + +{{< code file=layouts/books/single.html copy=true >}} +{{ define "main" }} +

{{ .Title }}

+ + {{ with .Resources.GetMatch "cover.*" }} + {{ .Params.alt }} + {{ end }} + +

Author: {{ .Params.author }}

+ +

+ ISBN: {{ .Params.isbn }}
+ Rating: {{ .Params.rating }}
+ Review date: {{ .Date | time.Format ":date_long" }} +

+ + {{ with .GetTerms "tags" }} +

Tags:

+ + {{ end }} + + {{ .Content }} +{{ end }} +{{< /code >}} + +## Multilingual sites + +With multilingual sites you can: + +1. Create one content adapter for all languages using the [`EnableAllLanguages`](#enablealllanguages) method as described above. +1. Create content adapters unique to each language. See the examples below. + +### Translations by file name + +With this site configuration: + +{{< code-toggle file=hugo >}} +[languages.en] +weight = 1 + +[languages.de] +weight = 2 +{{< /code-toggle >}} + +Include a language designator in the content adapter's file name. + +```text +content/ +└── books/ + ├── _content.de.gotmpl + ├── _content.en.gotmpl + ├── _index.de.md + └── _index.en.md +``` + +### Translations by content directory + +With this site configuration: + +{{< code-toggle file=hugo >}} +[languages.en] +contentDir = 'content/en' +weight = 1 + +[languages.de] +contentDir = 'content/de' +weight = 2 +{{< /code-toggle >}} + +Create a single content adapter in each directory: + +```text +content/ +├── de/ +│ └── books/ +│ ├── _content.gotmpl +│ └── _index.md +└── en/ + └── books/ + ├── _content.gotmpl + └── _index.md +``` + +## Page collisions + +Two or more pages collide when they have the same publication path. Due to concurrency, the content of the published page is indeterminate. Consider this example: + +```text +content/ +└── books/ + ├── _content.gotmpl <-- content adapter + ├── _index.md + └── the-hunchback-of-notre-dame.md +``` + +If the content adapter also creates books/the-hunchback-of-notre-dame, the content of the published page is indeterminate. You can not define the processing order. + +To detect page collisions, use the `--printPathWarnings` flag when building your site. + +[content formats]: /content-management/formats/#classification +[front matter field]: /content-management/front-matter/#fields +[media type]: https://en.wikipedia.org/wiki/Media_type +[syntax]: /templates/introduction/ +[template functions]: /functions/ diff --cc docs/content/en/content-management/cross-references.md index 56f4c39e1,000000000..66a77924f mode 100644,000000..100644 --- a/docs/content/en/content-management/cross-references.md +++ b/docs/content/en/content-management/cross-references.md @@@ -1,148 -1,0 +1,148 @@@ +--- +title: Links and cross references +description: Shortcodes for creating links to documents. +categories: [content management] +keywords: [cross references,references,anchors,urls] +menu: + docs: + parent: content-management + weight: 170 +weight: 170 +toc: true +aliases: [/extras/crossreferences/] +--- + +The `ref` and `relref` shortcodes display the absolute and relative permalinks to a document, respectively. + +## Use of `ref` and `relref` + +The `ref` and `relref` shortcodes require a single argument: the path to a content document, with or without a file extension, with or without an anchor. Paths without a leading `/` are first resolved relative to the current page, then to the remainder of the site. + +```text +. +└── content + ├── about + | ├── _index.md + | └── credits.md + ├── pages + | ├── document1.md + | └── document2.md // has anchor #anchor + ├── products + | └── index.md + └── blog + └── my-post.md +``` + +The pages can be referenced as follows: + +```text +{{}} <-- From pages/document1.md, relative path +{{}} +{{}} +{{}} +{{}} <-- From pages/document2.md +{{}} <-- From anywhere, absolute path +{{}} +{{}} +{{}} +{{}} +{{}} +``` + +`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 +{{}} <-- References /about/_index.md +{{}} <-- Raises REF_NOT_FOUND error +{{}} <-- References /about/credits.md + +{{}} <-- References /products/index.md +{{}} <-- References /products/index.md +``` + +To generate a hyperlink using `ref` or `relref` in Markdown: + +```text +[About]({{}} "About Us") +``` + +Hugo emits an error or warning if a document cannot be uniquely resolved. The error behavior is configurable; see below. + +### Link to another language version + +Using `ref` or `relref` without specifying a language, will make the reference resolve to the language of the current content page. + +To link to another language version of a document, use this syntax: + +```text +{{}} +``` + +### Get another output format + +To link to another Output Format of a document, use this syntax: + +```text +{{}} +``` + +### Heading IDs + +When using Markdown document types, Hugo generates element IDs for every heading on a page. For example: + +```text +## Reference +``` + +produces this HTML: + +```html +

Reference

+``` + +Get the permalink to a heading by appending the ID to the path when using the `ref` or `relref` shortcodes: + +```text +{{}} +{{}} +``` + +Generate a custom heading ID by including an attribute. For example: + +```text +## Reference A {#foo} +## Reference B {id="bar"} +``` + +produces this HTML: + +```html +

Reference A

+

Reference B

+``` + +Hugo will generate unique element IDs if the same heading appears more than once on a page. For example: + +```text +## Reference +## Reference +## Reference +``` + +produces this HTML: + +```html +

Reference

+

Reference

+

Reference

+``` + +## Ref and RelRef Configuration + +The behavior can be configured in `hugo.toml`: + +refLinksErrorLevel ("ERROR") - : When using `ref` or `relref` to resolve page links and a link cannot resolved, it will be logged with this log level. Valid values are `ERROR` (default) or `WARNING`. Any `ERROR` will fail the build (`exit -1`). ++: When using `ref` or `relref` to resolve page links and a link cannot be resolved, it will be logged with this log level. Valid values are `ERROR` (default) or `WARNING`. Any `ERROR` will fail the build (`exit -1`). + +refLinksNotFoundURL +: URL to be used as a placeholder when a page reference cannot be found in `ref` or `relref`. Is used as-is. diff --cc docs/content/en/content-management/formats.md index a02aa2545,000000000..a1f203f3c mode 100644,000000..100644 --- a/docs/content/en/content-management/formats.md +++ b/docs/content/en/content-management/formats.md @@@ -1,145 -1,0 +1,145 @@@ +--- +title: Content formats +description: Create your content using Markdown, HTML, Emacs Org Mode, AsciiDoc, Pandoc, or reStructuredText. +categories: [content management] +keywords: [markdown,asciidoc,pandoc,content format] +menu: + docs: + parent: content-management + weight: 40 +weight: 40 +toc: true +aliases: [/content/markdown-extras/,/content/supported-formats/,/doc/supported-formats/] +--- + +## Introduction + +You may mix content formats throughout your site. For example: + +```text +content/ +└── posts/ + ├── post-1.md + ├── post-2.adoc + ├── post-3.org + ├── post-4.pandoc + ├── post-5.rst + └── post-6.html +``` + +Regardless of content format, all content must have [front matter], preferably including both `title` and `date`. + +Hugo selects the content renderer based on the `markup` identifier in front matter, falling back to the file extension. See the [classification] table below for a list of markup identifiers and recognized file extensions. + +[classification]: #classification +[front matter]: /content-management/front-matter/ + +## Formats + +### Markdown + +Create your content in [Markdown] preceded by front matter. + +Markdown is Hugo's default content format. Hugo natively renders Markdown to HTML using [Goldmark]. Goldmark is fast and conforms to the [CommonMark] and [GitHub Flavored Markdown] specifications. You can configure Goldmark in your [site configuration][configure goldmark]. + +Hugo provides custom Markdown features including: + +[Attributes] +: Apply HTML attributes such as `class` and `id` to Markdown images and block elements including blockquotes, fenced code blocks, headings, horizontal rules, lists, paragraphs, and tables. + +[Extensions] +: Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more. + +[Mathematics] +: Include mathematical equations and expressions in Markdown using LaTeX markup. + +[Render hooks] +: Override the conversion of Markdown to HTML when rendering fenced code blocks, headings, images, and links. For example, render every standalone image as an HTML `figure` element. + +[Attributes]: /content-management/markdown-attributes/ +[CommonMark]: https://spec.commonmark.org/current/ +[Extensions]: /getting-started/configuration-markup/#goldmark-extensions +[GitHub Flavored Markdown]: https://github.github.com/gfm/ +[Goldmark]: https://github.com/yuin/goldmark +[Markdown]: https://daringfireball.net/projects/markdown/ +[Mathematics]: /content-management/mathematics/ +[Render hooks]: /render-hooks/introduction/ +[configure goldmark]: /getting-started/configuration-markup/#goldmark + +### HTML + +Create your content in [HTML] preceded by front matter. The content is typically what you would place within an HTML document's `body` or `main` element. + +[HTML]: https://developer.mozilla.org/en-US/docs/Learn_web_development/Getting_started/Your_first_website/Creating_the_content + +### Emacs Org Mode + - Create your content in the [Emacs Org Mode] format preceded by front matter. You can use Org Mode keywords for front matter. See [details]. ++Create your content in the [Emacs Org Mode] format preceded by front matter. You can use Org Mode keywords for front matter. See [details]. + +[details]: /content-management/front-matter/#emacs-org-mode +[Emacs Org Mode]: https://orgmode.org/ + +### AsciiDoc + +Create your content in the [AsciiDoc] format preceded by front matter. Hugo renders AsciiDoc content to HTML using the Asciidoctor executable. You must install Asciidoctor and its dependencies (Ruby) to use the AsciiDoc content format. + +You can configure the AsciiDoc renderer in your [site configuration][configure asciidoc]. + +In its default configuration, Hugo passes these CLI flags when calling the Asciidoctor executable: + +```text +--no-header-footer +``` + +The CLI flags passed to the Asciidoctor executable depend on configuration. You may inspect the flags when building your site: + +```text +hugo --logLevel info +``` + +[AsciiDoc]: https://asciidoc.org/ +[configure the AsciiDoc renderer]: /getting-started/configuration-markup/#asciidoc +[configure asciidoc]: /getting-started/configuration-markup/#asciidoc + +### Pandoc + +Create your content in the [Pandoc] format preceded by front matter. Hugo renders Pandoc content to HTML using the Pandoc executable. You must install Pandoc to use the Pandoc content format. + +Hugo passes these CLI flags when calling the Pandoc executable: + +```text +--mathjax +``` + +[Pandoc]: https://pandoc.org/ + +### reStructuredText + +Create your content in the [reStructuredText] format preceded by front matter. Hugo renders reStructuredText content to HTML using [Docutils], specifically rst2html. You must install Docutils and its dependencies (Python) to use the reStructuredText content format. + +Hugo passes these CLI flags when calling the rst2html executable: + +```text +--leave-comments --initial-header-level=2 +``` + +[Docutils]: https://docutils.sourceforge.io/ +[reStructuredText]: https://docutils.sourceforge.io/rst.html + +## Classification + +Content format|Media type|Identifier|File extensions +:--|:--|:--|:-- +Markdown|`text/markdown`|`markdown`|`markdown`,`md`, `mdown` +HTML|`text/html`|`html`|`htm`, `html` +Emacs Org Mode|`text/org`|`org`|`org` +AsciiDoc|`text/asciidoc`|`asciidoc`|`ad`, `adoc`, `asciidoc` +Pandoc|`text/pandoc`|`pandoc`|`pandoc`, `pdc` +reStructuredText|`text/rst`|`rst`|`rst` + +When converting content to HTML, Hugo uses: + +- Native renderers for Markdown, HTML, and Emacs Org mode +- External renderers for AsciiDoc, Pandoc, and reStructuredText + +Native renderers are faster than external renderers. diff --cc docs/content/en/content-management/front-matter.md index dba77f1d1,000000000..9f5fc9e11 mode 100644,000000..100644 --- a/docs/content/en/content-management/front-matter.md +++ b/docs/content/en/content-management/front-matter.md @@@ -1,441 -1,0 +1,441 @@@ +--- +title: Front matter +description: Use front matter to add metadata to your content. +categories: [content management] +keywords: [front matter,yaml,toml,json,metadata,archetypes] +menu: + docs: + parent: content-management + weight: 60 +weight: 60 +toc: true +aliases: [/content/front-matter/] +--- + +## Overview + +The front matter at the top of each content file is metadata that: + +- Describes the content +- Augments the content +- Establishes relationships with other content +- Controls the published structure of your site +- Determines template selection + +Provide front matter using a serialization format, one of [JSON], [TOML], or [YAML]. Hugo determines the front matter format by examining the delimiters that separate the front matter from the page content. + +[json]: https://www.json.org/ +[toml]: https://toml.io/ +[yaml]: https://yaml.org/ + +See examples of front matter delimiters by toggling between the serialization formats below. + +{{< code-toggle file=content/example.md fm=true >}} +title = 'Example' +date = 2024-02-02T04:14:54-08:00 +draft = false +weight = 10 +[params] +author = 'John Smith' +{{< /code-toggle >}} + +Front matter fields may be [boolean](g), [integer](g), [float](g), [string](g), [arrays](g), or [maps](g). Note that the TOML format also supports unquoted date/time values. + +## Fields + +The most common front matter fields are `date`, `draft`, `title`, and `weight`, but you can specify metadata using any of fields below. + +{{% note %}} +The field names below are reserved. For example, you cannot create a custom field named `type`. Create custom fields under the `params` key. See the [parameters] section for details. + +[parameters]: #parameters +{{% /note %}} + +###### aliases + +(`string array`) An array of one or more aliases, where each alias is a relative URL that will redirect the browser to the current location. Access these values from a template using the [`Aliases`] method on a `Page` object. See the [aliases] section for details. + +[`aliases`]: /methods/page/aliases/ +[aliases]: /content-management/urls/#aliases + +###### build + +(`map`) A map of [build options]. + +[build options]: /content-management/build-options/ + +###### cascade {#cascade-field} + +(`map`) A map of front matter keys whose values are passed down to the page’s descendants unless overwritten by self or a closer ancestor’s cascade. See the [cascade] section for details. + +[cascade]: #cascade + +###### date + +(`string`) The date associated with the page, typically the creation date. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Date`] method on a `Page` object. + +[`date`]: /methods/page/date/ + +###### description + +(`string`) Conceptually different than the page `summary`, the description is typically rendered within a `meta` element within the `head` element of the published HTML file. Access this value from a template using the [`Description`] method on a `Page` object. + +[`description`]: /methods/page/description/ + +###### draft + +(`bool`) +If `true`, the page will not be rendered unless you pass the `--buildDrafts` flag to the `hugo` command. Access this value from a template using the [`Draft`] method on a `Page` object. + +[`draft`]: /methods/page/draft/ + +###### expiryDate + +(`string`) The page expiration date. On or after the expiration date, the page will not be rendered unless you pass the `--buildExpired` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`ExpiryDate`] method on a `Page` object. + +[`expirydate`]: /methods/page/expirydate/ + +###### headless + +(`bool`) Applicable to [leaf bundles], if `true` this value sets the `render` and `list` [build options] to `never`, creating a headless bundle of [page resources]. + +[leaf bundles]: /content-management/page-bundles/#leaf-bundles +[page resources]: /content-management/page-resources/ + +###### isCJKLanguage + +(`bool`) Set to `true` if the content language is in the [CJK](g) family. This value determines how Hugo calculates word count, and affects the values returned by the [`WordCount`], [`FuzzyWordCount`], [`ReadingTime`], and [`Summary`] methods on a `Page` object. + +[`fuzzywordcount`]: /methods/page/wordcount/ +[`readingtime`]: /methods/page/readingtime/ +[`summary`]: /methods/page/summary/ +[`wordcount`]: /methods/page/wordcount/ + +###### keywords + +(`string array`) An array of keywords, typically rendered within a `meta` element within the `head` element of the published HTML file, or used as a [taxonomy](g) to classify content. Access these values from a template using the [`Keywords`] method on a `Page` object. + +[`keywords`]: /methods/page/keywords/ + + + + + + + +###### lastmod + +(`string`) The date that the page was last modified. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Lastmod`] method on a `Page` object. + +[`lastmod`]: /methods/page/date/ + +###### layout + +(`string`) Provide a template name to [target a specific template], overriding the default [template lookup order]. Set the value to the base file name of the template, excluding its extension. Access this value from a template using the [`Layout`] method on a `Page` object. + +[`layout`]: /methods/page/layout/ +[template lookup order]: /templates/lookup-order/ +[target a specific template]: /templates/lookup-order/#target-a-template + +###### linkTitle + +(`string`) Typically a shorter version of the `title`. Access this value from a template using the [`LinkTitle`] method on a `Page` object. + +[`linktitle`]: /methods/page/linktitle/ + +###### markup + +(`string`) An identifier corresponding to one of the supported [content formats]. If not provided, Hugo determines the content renderer based on the file extension. + +[content formats]: /content-management/formats/#classification + +###### menus + +(`string`, `string array`, or `map`) If set, Hugo adds the page to the given menu or menus. See the [menus] page for details. + +[menus]: /content-management/menus/#define-in-front-matter + +###### modified + +Alias to [lastmod](#lastmod). + +###### outputs + +(`string array`) The [output formats] to render. + +[output formats]: /templates/output-formats/ + + + + +###### params + - {{< new-in 0.123.0 >}} ++{{< new-in 0.123.0 />}} + +(`map`) A map of custom [page parameters]. + +[page parameters]: #parameters + +###### pubdate + +Alias to [publishDate](#publishdate). + +###### publishDate + +(`string`) The page publication date. Before the publication date, the page will not be rendered unless you pass the `--buildFuture` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`PublishDate`] method on a `Page` object. + +[`publishdate`]: /methods/page/publishdate/ + +###### published + +Alias to [publishDate](#publishdate). + +###### resources + +(`map array`) An array of maps to provide metadata for [page resources]. + +[page-resources]: /content-management/page-resources/#page-resources-metadata + +###### sitemap + +(`map`) A map of sitemap options. See the [sitemap templates] page for details. Access these values from a template using the [`Sitemap`] method on a `Page` object. + +[sitemap templates]: /templates/sitemap/ +[`sitemap`]: /methods/page/sitemap/ + +###### slug + +(`string`) Overrides the last segment of the URL path. Not applicable to section pages. See the [URL management] page for details. Access this value from a template using the [`Slug`] method on a `Page` object. + +[`slug`]: /methods/page/slug/ +[URL management]: /content-management/urls/#slug + +###### summary + +(`string`) Conceptually different than the page `description`, the summary either summarizes the content or serves as a teaser to encourage readers to visit the page. Access this value from a template using the [`Summary`] method on a `Page` object. + +[`Summary`]: /methods/page/summary/ + +###### title + +(`string`) The page title. Access this value from a template using the [`Title`] method on a `Page` object. + +[`title`]: /methods/page/title/ + +###### translationKey + +(`string`) An arbitrary value used to relate two or more translations of the same page, useful when the translated pages do not share a common path. Access this value from a template using the [`TranslationKey`] method on a `Page` object. + +[`translationkey`]: /methods/page/translationkey/ + +###### type + +(`string`) The [content type](g), overriding the value derived from the top level section in which the page resides. Access this value from a template using the [`Type`] method on a `Page` object. + +[`type`]: /methods/page/type/ + +###### unpublishdate + +Alias to [expirydate](#expirydate). + +###### url + +(`string`) Overrides the entire URL path. Applicable to regular pages and section pages. See the [URL management] page for details. + +###### weight +(`int`) The page [weight](g), used to order the page within a [page collection](g). Access this value from a template using the [`Weight`] method on a `Page` object. + +[`weight`]: /methods/page/weight/ + +## Parameters + - {{< new-in 0.123.0 >}} ++{{< new-in 0.123.0 />}} + +Specify custom page parameters under the `params` key in front matter: + +{{< code-toggle file=content/example.md fm=true >}} +title = 'Example' +date = 2024-02-02T04:14:54-08:00 +draft = false +weight = 10 +[params] +author = 'John Smith' +{{< /code-toggle >}} + +Access these values from a template using the [`Params`] or [`Param`] method on a `Page` object. + +[`param`]: /methods/page/param/ +[`params`]: /methods/page/params/ + +Hugo provides [embedded templates] to optionally insert meta data within the `head` element of your rendered pages. These embedded templates expect the following front matter parameters: + +Parameter|Data type|Used by these embedded templates +:--|:--|:-- +`audio`|`[]string`|[`opengraph.html`] +`images`|`[]string`|[`opengraph.html`], [`schema.html`], [`twitter_cards.html`] +`videos`|`[]string`|[`opengraph.html`] + +The embedded templates will skip a parameter if not provided in front matter, but will throw an error if the data type is unexpected. + +[`opengraph.html`]: {{% eturl opengraph %}} +[`schema.html`]: {{% eturl schema %}} +[`twitter_cards.html`]: {{% eturl twitter_cards %}} +[embedded templates]: /templates/embedded/ + +## Taxonomies + +Classify content by adding taxonomy terms to front matter. For example, with this site configuration: + +{{< code-toggle file=hugo >}} +[taxonomies] +tag = 'tags' +genre = 'genres' +{{< /code-toggle >}} + +Add taxonomy terms as shown below: + +{{< code-toggle file=content/example.md fm=true >}} +title = 'Example' +date = 2024-02-02T04:14:54-08:00 +draft = false +weight = 10 +tags = ['red','blue'] +genres = ['mystery','romance'] +[params] +author = 'John Smith' +{{< /code-toggle >}} + +You can add taxonomy terms to the front matter of any these [page kinds](g): + +- `home` +- `page` +- `section` +- `taxonomy` +- `term` + +Access taxonomy terms from a template using the [`Params`] or [`GetTerms`] method on a `Page` object. For example: + +{{< code file=layouts/_default/single.html >}} +{{ with .GetTerms "tags" }} +

Tags

+ +{{ end }} +{{< /code >}} + +[`Params`]: /methods/page/params/ +[`GetTerms`]: /methods/page/getterms/ + +## Cascade + +Any [node](g) can pass down to its descendants a set of front matter values. + +### Target specific pages + +The `cascade` block can be an array with an optional `_target` keyword, allowing you to target different page sets while cascading values. + +{{< code-toggle file=content/_index.md fm=true >}} +title ="Home" +[[cascade]] +[cascade.params] +background = "yosemite.jpg" +[cascade._target] +path="/articles/**" +lang="en" +kind="page" +[[cascade]] +[cascade.params] +background = "goldenbridge.jpg" +[cascade._target] +kind="section" +{{}} + +Use any combination of these keywords to target a set of pages: + +###### path {#cascade-path} + +(`string`) A [Glob](https://github.com/gobwas/glob) pattern matching the content path below /content. Expects Unix-styled slashes. Note that this is the virtual path, so it starts at the mount root. The matching supports double-asterisks so you can match for patterns like `/blog/*/**` to match anything from the third level and down. + +###### kind {#cascade-kind} + +(`string`) A Glob pattern matching the Page's Kind(s), e.g. "{home,section}". + +###### lang {#cascade-lang} + +(`string`) A Glob pattern matching the Page's language, e.g. "{en,sv}". + +###### environment {#cascade-environment} + +(`string`) A Glob pattern matching the build environment, e.g. "{production,development}" + +Any of the above can be omitted. + +{{% note %}} +With a multilingual site it may be more efficient to define the `cascade` values in your site configuration to avoid duplicating the `cascade` values on the section, taxonomy, or term page for each language. + +With a multilingual site, if you choose to define the `cascade` values in front matter, you must create a section, taxonomy, or term page for each language; the `lang` keyword is ignored. +{{% /note %}} + +### Example + +{{< code-toggle file=content/posts/_index.md fm=true >}} +date = 2024-02-01T21:25:36-08:00 +title = 'Posts' +[cascade] + [cascade.params] + banner = 'images/typewriter.jpg' +{{}} + +With the above example the posts section page and its descendants will return `images/typewriter.jpg` when `.Params.banner` is invoked unless: + +- Said descendant has its own `banner` value set +- Or a closer ancestor node has its own `cascade.banner` value set. + +## Emacs Org Mode + +If your [content format] is [Emacs Org Mode], you may provide front matter using Org Mode keywords. For example: + +{{< code file=content/example.org lang=text >}} +#+TITLE: Example +#+DATE: 2024-02-02T04:14:54-08:00 +#+DRAFT: false +#+AUTHOR: John Smith +#+GENRES: mystery +#+GENRES: romance +#+TAGS: red +#+TAGS: blue +#+WEIGHT: 10 +{{< /code >}} + +Note that you can also specify array elements on a single line: + +{{< code file=content/example.org lang=text >}} +#+TAGS[]: red blue +{{< /code >}} + +[content format]: /content-management/formats/ +[emacs org mode]: https://orgmode.org/ + +## Dates + +When populating a date field, whether a [custom page parameter](#parameters) or one of the four predefined fields ([`date`](#date), [`expiryDate`](#expirydate), [`lastmod`](#lastmod), [`publishDate`](#publishdate)), use one of these parsable formats: + +{{% include "functions/time/_common/parsable-date-time-strings.md" %}} + +To override the default time zone, set the [`timeZone`](https://gohugo.io/getting-started/configuration/#timezone) in your site configuration. The order of precedence for determining the time zone is: + +1. The time zone offset in the date/time string +1. The time zone specified in your site configuration +1. The `Etc/UTC` time zone diff --cc docs/content/en/content-management/image-processing/index.md index 69ee30dc8,000000000..50e4b1e72 mode 100644,000000..100644 --- a/docs/content/en/content-management/image-processing/index.md +++ b/docs/content/en/content-management/image-processing/index.md @@@ -1,520 -1,0 +1,520 @@@ +--- +title: Image processing +description: Resize, crop, rotate, filter, and convert images. +categories: [content management,fundamentals] +keywords: [resources,images] +menu: + docs: + parent: content-management + weight: 90 +toc: true +weight: 90 +--- + +## Image resources + +To process an image you must access the file as a page resource, global resource, or remote resource. + +### Page resource + - A page resource is a file within a [page bundle]. A page bundle is a directory with an `index.md` or `_index.md` file at its root. ++A page resource is a file within a [page bundle]. A page bundle is a directory with an `index.md` or `_index.md` file at its root. + +```text +content/ +└── posts/ + └── post-1/ <-- page bundle + ├── index.md + └── sunset.jpg <-- page resource +``` + +To access an image as a page resource: + +```go-html-template +{{ $image := .Resources.Get "sunset.jpg" }} +``` + +### Global resource + +A global resource is a file within the `assets` directory, or within any directory [mounted] to the `assets` directory. + +```text +assets/ +└── images/ + └── sunset.jpg <-- global resource +``` + +To access an image as a global resource: + +```go-html-template +{{ $image := resources.Get "images/sunset.jpg" }} +``` + +### Remote resource + +A remote resource is a file on a remote server, accessible via HTTP or HTTPS. To access an image as a remote resource: + +```go-html-template +{{ $image := resources.GetRemote "https://gohugo.io/img/hugo-logo.png" }} +``` + +## Image rendering + +Once you have accessed an image as a resource, render it in your templates using the `Permalink`, `RelPermalink`, `Width`, and `Height` properties. + +Example 1: Throws an error if the resource is not found. + +```go-html-template +{{ $image := .Resources.GetMatch "sunset.jpg" }} + +``` + +Example 2: Skips image rendering if the resource is not found. + +```go-html-template +{{ $image := .Resources.GetMatch "sunset.jpg" }} +{{ with $image }} + +{{ end }} +``` + +Example 3: A more concise way to skip image rendering if the resource is not found. + +```go-html-template +{{ with .Resources.GetMatch "sunset.jpg" }} + +{{ end }} +``` + +Example 4: Skips rendering if there's problem accessing a remote resource. + +```go-html-template +{{ $url := "https://gohugo.io/img/hugo-logo.png" }} +{{ with try (resources.GetRemote $url) }} + {{ with .Err }} + {{ errorf "%s" . }} + {{ else with .Value }} + + {{ else }} + {{ errorf "Unable to get remote resource %q" $url }} + {{ end }} +{{ end }} +``` + +## Image processing methods + +The `image` resource implements the [`Process`], [`Resize`], [`Fit`], [`Fill`], [`Crop`], [`Filter`], [`Colors`] and [`Exif`] methods. + +{{% note %}} +Metadata (EXIF, IPTC, XMP, etc.) is not preserved during image transformation. Use the `Exif` method with the _original_ image to extract EXIF metadata from JPEG, PNG, TIFF, and WebP images. +{{% /note %}} + +### Process + - {{< new-in 0.119.0 >}} ++{{< new-in 0.119.0 />}} + +{{% note %}} +The `Process` method is also available as a filter, which is more effective if you need to apply multiple filters to an image. See [Process filter](/functions/images/process). +{{% /note %}} + +Process processes the image with the given specification. The specification can contain an optional action, one of `resize`, `crop`, `fit` or `fill`. This means that you can use this method instead of [`Resize`], [`Fit`], [`Fill`], or [`Crop`]. + +See [Options](#image-processing-options) for available options. + +You can also use this method apply image processing that does not need any scaling, e.g. format conversions: + +```go-html-template +{{/* Convert the image from JPG to PNG. */}} +{{ $png := $jpg.Process "png" }} +``` + +Some more examples: + +```go-html-template +{{/* Rotate the image 90 degrees counter-clockwise. */}} +{{ $image := $image.Process "r90" }} + +{{/* Scaling actions. */}} +{{ $image := $image.Process "resize 600x" }} +{{ $image := $image.Process "crop 600x400" }} +{{ $image := $image.Process "fit 600x400" }} +{{ $image := $image.Process "fill 600x400" }} +``` + +### Resize + +Resize an image to the given width and/or height. + +If you specify both width and height, the resulting image will be disproportionally scaled unless the original image has the same aspect ratio. + +```go-html-template +{{/* Resize to a width of 600px and preserve aspect ratio */}} +{{ $image := $image.Resize "600x" }} + +{{/* Resize to a height of 400px and preserve aspect ratio */}} +{{ $image := $image.Resize "x400" }} + +{{/* Resize to a width of 600px and a height of 400px */}} +{{ $image := $image.Resize "600x400" }} +``` + +### Fit + +Downscale an image to fit the given dimensions while maintaining aspect ratio. You must provide both width and height. + +```go-html-template +{{ $image := $image.Fit "600x400" }} +``` + +### Fill + +Crop and resize an image to match the given dimensions. You must provide both width and height. Use the [`anchor`] option to change the crop box anchor point. + +```go-html-template +{{ $image := $image.Fill "600x400" }} +``` + +### Crop + +Crop an image to match the given dimensions without resizing. You must provide both width and height. Use the [`anchor`] option to change the crop box anchor point. + +```go-html-template +{{ $image := $image.Crop "600x400" }} +``` + +### Filter + +Apply one or more [filters] to an image. + +```go-html-template +{{ $image := $image.Filter (images.GaussianBlur 6) (images.Pixelate 8) }} +``` + +Write this in a more functional style using pipes. Hugo applies the filters in the order given. + +```go-html-template +{{ $image := $image | images.Filter (images.GaussianBlur 6) (images.Pixelate 8) }} +``` + +Sometimes it can be useful to create the filter chain once and then reuse it. + +```go-html-template +{{ $filters := slice (images.GaussianBlur 6) (images.Pixelate 8) }} +{{ $image1 := $image1.Filter $filters }} +{{ $image2 := $image2.Filter $filters }} +``` + +### Colors + +`.Colors` returns a slice of hex strings with the dominant colors in the image using a simple histogram method. + +```go-html-template +{{ $colors := $image.Colors }} +``` + +This method is fast, but if you also scale down your images, it would be good for performance to extract the colors from the scaled down image. + +### EXIF + +Provides an [EXIF] object containing image metadata. + +You may access EXIF data in JPEG, PNG, TIFF, and WebP images. To prevent errors when processing images without EXIF data, wrap the access in a [`with`] statement. + +```go-html-template +{{ with $image.Exif }} + Date: {{ .Date }} + Lat/Long: {{ .Lat }}/{{ .Long }} + Tags: + {{ range $k, $v := .Tags }} + TAG: {{ $k }}: {{ $v }} + {{ end }} +{{ end }} +``` + +You may also access EXIF fields individually, using the [`lang.FormatNumber`] function to format the fields as needed. + +```go-html-template +{{ with $image.Exif }} + +{{ end }} +``` + +#### EXIF methods + +Date +: (`time.Time`) Returns the image creation date/time. Format with the [`time.Format`]function. + +[time.Format]: /functions/time/format/ + +Lat +: (`float64`) Returns the GPS latitude in degrees. + +Long +: (`float64`) Returns the GPS longitude in degrees. + +Tags +: (`exif.Tags`) Returns a collection of the available EXIF tags for this image. You may include or exclude specific tags from this collection in the [site configuration]. + +## Image processing options + +The [`Resize`], [`Fit`], [`Fill`], and [`Crop`] methods accept a space-delimited, case-insensitive list of options. The order of the options within the list is irrelevant. + +### Dimensions + +With the [`Resize`] method you must specify width, height, or both. The [`Fit`], [`Fill`], and [`Crop`] methods require both width and height. All dimensions are in pixels. + +```go-html-template +{{ $image := $image.Resize "600x" }} +{{ $image := $image.Resize "x400" }} +{{ $image := $image.Resize "600x400" }} +{{ $image := $image.Fit "600x400" }} +{{ $image := $image.Fill "600x400" }} +{{ $image := $image.Crop "600x400" }} +``` + +### Rotation + +Rotates an image counter-clockwise by the given angle. Hugo performs rotation _before_ scaling. For example, if the original image is 600x400 and you wish to rotate the image 90 degrees counter-clockwise while scaling it by 50%: + +```go-html-template +{{ $image = $image.Resize "200x r90" }} +``` + +In the example above, the width represents the desired width _after_ rotation. + +To rotate an image without scaling, use the dimensions of the original image: + +```go-html-template +{{ with .Resources.GetMatch "sunset.jpg" }} + {{ with .Resize (printf "%dx%d r90" .Height .Width) }} + + {{ end }} +{{ end }} +``` + +In the example above, on the second line, we have reversed width and height to reflect the desired dimensions _after_ rotation. + +### Anchor + +When using the [`Crop`] or [`Fill`] method, the _anchor_ determines the placement of the crop box. You may specify `TopLeft`, `Top`, `TopRight`, `Left`, `Center`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`, or `Smart`. + +The default value is `Smart`, which uses [Smartcrop] image analysis to determine the optimal placement of the crop box. You may override the default value in the [site configuration]. + +For example, if you have a 400x200 image with a bird in the upper left quadrant, you can create a 200x100 thumbnail containing the bird: + +```go-html-template +{{ $image.Crop "200x100 TopLeft" }} +``` + +If you apply [rotation](#rotation) when using the [`Crop`] or [`Fill`] method, specify the anchor relative to the rotated image. + +### Target format + +By default, Hugo encodes the image in the source format. You may convert the image to another format by specifying `bmp`, `gif`, `jpeg`, `jpg`, `png`, `tif`, `tiff`, or `webp`. + +```go-html-template +{{ $image.Resize "600x webp" }} +``` + +To convert an image without scaling, use the dimensions of the original image: + +```go-html-template +{{ with .Resources.GetMatch "sunset.jpg" }} + {{ with .Resize (printf "%dx%d webp" .Width .Height) }} + + {{ end }} +{{ end }} +``` + +### Quality + +Applicable to JPEG and WebP images, the `q` value determines the quality of the converted image. Higher values produce better quality images, while lower values produce smaller files. Set this value to a whole number between 1 and 100, inclusive. + +The default value is 75. You may override the default value in the [site configuration]. + +```go-html-template +{{ $image.Resize "600x webp q50" }} +``` + +### Hint + +Applicable to WebP images, this option corresponds to a set of predefined encoding parameters, and is equivalent to the `-preset` flag for the [`cwebp`] encoder. + +[`cwebp`]: https://developers.google.com/speed/webp/docs/cwebp + +Value|Example +:--|:-- +`drawing`|Hand or line drawing with high-contrast details +`icon`|Small colorful image +`photo`|Outdoor photograph with natural lighting +`picture`|Indoor photograph such as a portrait +`text`|Image that is primarily text + +The default value is `photo`. You may override the default value in the [site configuration]. + +```go-html-template +{{ $image.Resize "600x webp picture" }} +``` + +### Background color + +When converting an image from a format that supports transparency (e.g., PNG) to a format that does _not_ support transparency (e.g., JPEG), you may specify the background color of the resulting image. + +Use either a 3-digit or 6-digit hexadecimal color code (e.g., `#00f` or `#0000ff`). + +The default value is `#ffffff` (white). You may override the default value in the [site configuration]. + +```go-html-template +{{ $image.Resize "600x jpg #b31280" }} +``` + +### Resampling filter + +You may specify the resampling filter used when resizing an image. Commonly used resampling filters include: + +Filter|Description +:--|:-- +`Box`|Simple and fast averaging filter appropriate for downscaling +`Lanczos`|High-quality resampling filter for photographic images yielding sharp results +`CatmullRom`|Sharp cubic filter that is faster than the Lanczos filter while providing similar results +`MitchellNetravali`|Cubic filter that produces smoother results with less ringing artifacts than CatmullRom +`Linear`|Bilinear resampling filter, produces smooth output, faster than cubic filters +`NearestNeighbor`|Fastest resampling filter, no antialiasing + +The default value is `Box`. You may override the default value in the [site configuration]. + +```go-html-template +{{ $image.Resize "600x400 Lanczos" }} +``` + +See [github.com/disintegration/imaging] for the complete list of resampling filters. If you wish to improve image quality at the expense of performance, you may wish to experiment with the alternative filters. + +## Image processing examples + +_The photo of the sunset used in the examples below is Copyright [Bjørn Erik Pedersen](https://commons.wikimedia.org/wiki/User:Bep) (Creative Commons Attribution-Share Alike 4.0 International license)_ + +{{< imgproc "sunset.jpg" "resize 300x" />}} + +{{< imgproc "sunset.jpg" "fill 90x120 left" />}} + +{{< imgproc "sunset.jpg" "fill 90x120 right" />}} + +{{< imgproc "sunset.jpg" "fit 90x90" />}} + +{{< imgproc "sunset.jpg" "crop 250x250 center" />}} + +{{< imgproc "sunset.jpg" "resize 300x q10" />}} + +This is the shortcode used to generate the examples above: + +{{< readfile file=layouts/shortcodes/imgproc.html highlight=go-html-template >}} + +Call the shortcode from your Markdown like this: + +```go-html-template +{{}} +``` + +{{% note %}} +Note the self-closing shortcode syntax above. You may call the `imgproc` shortcode with or without **inner content**. +{{% /note %}} + +## Imaging configuration + +### Processing options + +Define an `imaging` section in your site configuration to set the default [image processing options](#image-processing-options). + +{{< code-toggle config=imaging />}} + +anchor +: See image processing options: [anchor](#anchor). + +bgColor +: See image processing options: [background color](#background-color). + +hint +: See image processing options: [hint](#hint). + +quality +: See image processing options: [quality](#quality). + +resampleFilter +: See image processing options: [resampling filter](#resampling-filter). + +### EXIF data + +Define an `imaging.exif` section in your site configuration to control the availability of EXIF data. + +{{< code-toggle file=hugo >}} +[imaging.exif] +includeFields = "" +excludeFields = "" +disableDate = false +disableLatLong = false +{{< /code-toggle >}} + +disableDate +: Hugo extracts the image creation date/time into `.Date`. Set this to `true` to disable. Default is `false`. + +disableLatLong +: Hugo extracts the GPS latitude and longitude into `.Lat` and `.Long`. Set this to `true` to disable. Default is `false`. + +excludeFields +: Regular expression matching the EXIF tags to exclude from the `.Tags` collection. Default is `""`. + +includeFields +: Regular expression matching the EXIF tags to include in the `.Tags` collection. Default is `""`. To include all available tags, set this value to `".*"`. + +{{% note %}} +To improve performance and decrease cache size, Hugo excludes the following tags: `ColorSpace`, `Contrast`, `Exif`, `Exposure[M|P|B]`, `Flash`, `GPS`, `JPEG`, `Metering`, `Resolution`, `Saturation`, `Sensing`, `Sharp`, and `WhiteBalance`. + +To control tag availability, change the `excludeFields` or `includeFields` settings as described above. +{{% /note %}} + +## Smart cropping of images + +By default, Hugo uses the [Smartcrop] library when cropping images with the `Crop` or `Fill` methods. You can set the anchor point manually, but in most cases the `Smart` option will make a good choice. + +Examples using the sunset image from above: + +{{< imgproc "sunset.jpg" "fill 200x200 smart" />}} + +{{< imgproc "sunset.jpg" "crop 200x200 smart" />}} + +## Image processing performance consideration + +Hugo caches processed images in the `resources` directory. If you include this directory in source control, Hugo will not have to regenerate the images in a CI/CD workflow (e.g., GitHub Pages, GitLab Pages, Netlify, etc.). This results in faster builds. + +If you change image processing methods or options, or if you rename or remove images, the `resources` directory will contain unused images. To remove the unused images, perform garbage collection with: + +```sh +hugo --gc +``` + +[`anchor`]: /content-management/image-processing#anchor +[mounted]: /hugo-modules/configuration#module-configuration-mounts +[page bundle]: /content-management/page-bundles/ +[`lang.FormatNumber`]: /functions/lang/formatnumber/ +[filters]: /functions/images/filter/#image-filters +[github.com/disintegration/imaging]: https://github.com/disintegration/imaging#image-resizing +[Smartcrop]: https://github.com/muesli/smartcrop#smartcrop +[Exif]: https://en.wikipedia.org/wiki/Exif +[`Process`]: #process +[`Colors`]: #colors +[`Crop`]: #crop +[`Exif`]: #exif +[`Fill`]: #fill +[`Filter`]: #filter +[`Fit`]: #fit +[`Resize`]: #resize +[site configuration]: #processing-options +[`with`]: /functions/go-template/with/ diff --cc docs/content/en/content-management/mathematics.md index 5eda9ffa3,000000000..aa398d334 mode 100644,000000..100644 --- a/docs/content/en/content-management/mathematics.md +++ b/docs/content/en/content-management/mathematics.md @@@ -1,232 -1,0 +1,251 @@@ +--- +title: Mathematics in Markdown +linkTitle: Mathematics +description: Include mathematical equations and expressions in Markdown using LaTeX markup. +categories: [content management] +keywords: [katex,latex,math,mathjax,typesetting] +menu: + docs: + parent: content-management + weight: 270 +weight: 270 +toc: true +math: true +--- + - {{< new-in 0.122.0 >}} ++{{< new-in 0.122.0 />}} + +## Overview + +Mathematical equations and expressions written in [LaTeX] are common in academic and scientific publications. Your browser typically renders this mathematical markup using an open-source JavaScript display engine such as [MathJax] or [KaTeX]. + +For example, with this LaTeX markup: + +```text +\[ +\begin{aligned} +KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \\ +JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2})) +\end{aligned} +\] +``` + +The MathJax display engine renders this: + +\[ +\begin{aligned} +KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \\ +JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2})) +\end{aligned} +\] + +Equations and expressions can be displayed inline with other text, or as standalone blocks. Block presentation is also known as "display" mode. + +Whether an equation or expression appears inline, or as a block, depends on the delimiters that surround the mathematical markup. Delimiters are defined in pairs, where each pair consists of an opening and closing delimiter. The opening and closing delimiters may be the same, or different. + +{{% note %}} - You can configure Hugo to render mathematical markup on the client-side using the MathJax or KaTeX display engine, or you can render the markup while building your site with the [`transform.ToMath`]function. ++You can configure Hugo to render mathematical markup on the client side using the MathJax or KaTeX display engine, or you can render the markup with the [`transform.ToMath`] function while building your site. + +The first approach is described below. + +[`transform.ToMath`]: /functions/transform/tomath/ +{{% /note %}} + +## Setup + +Follow these instructions to include mathematical equations and expressions in your Markdown using LaTeX markup. + +###### Step 1 + +Enable and configure the Goldmark [passthrough extension] in your site configuration. The passthrough extension preserves raw Markdown within delimited snippets of text, including the delimiters themselves. + +{{< code-toggle file=hugo copy=true >}} +[markup.goldmark.extensions.passthrough] +enable = true + +[markup.goldmark.extensions.passthrough.delimiters] +block = [['\[', '\]'], ['$$', '$$']] +inline = [['\(', '\)']] + +[params] +math = true +{{< /code-toggle >}} + +The configuration above enables mathematical rendering on every page unless you set the `math` parameter to `false` in front matter. To enable mathematical rendering as needed, set the `math` parameter to `false` in your site configuration, and set the `math` parameter to `true` in front matter. Use this parameter in your base template as shown in [Step 3]. + +{{% note %}} +The configuration above precludes the use of the `$...$` delimiter pair for inline equations. Although you can add this delimiter pair to the configuration and JavaScript, you will need to double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting. + +See the [inline delimiters](#inline-delimiters) section for details. +{{% /note %}} + +To disable passthrough of inline snippets, omit the `inline` key from the configuration: + +{{< code-toggle file=hugo >}} +[markup.goldmark.extensions.passthrough.delimiters] +block = [['\[', '\]'], ['$$', '$$']] +{{< /code-toggle >}} + +You can define your own opening and closing delimiters, provided they match the delimiters that you set in [Step 2]. + +{{< code-toggle file=hugo >}} +[markup.goldmark.extensions.passthrough.delimiters] +block = [['@@', '@@']] +inline = [['@', '@']] +{{< /code-toggle >}} + +###### Step 2 + +Create a partial template to load MathJax or KaTeX. The example below loads MathJax, or you can use KaTeX as described in the [engines](#engines) section. + +{{< code file=layouts/partials/math.html copy=true >}} + + +{{< /code >}} + +The delimiters above must match the delimiters in your site configuration. + +###### Step 3 + +Conditionally call the partial template from the base template. + +{{< code file=layouts/_default/baseof.html >}} + + ... + {{ if .Param "math" }} + {{ partialCached "math.html" . }} + {{ end }} + ... + +{{< /code >}} + +The example above loads the partial template if you have set the `math` parameter in front matter to `true`. If you have not set the `math` parameter in front matter, the conditional statement falls back to the `math` parameter in your site configuration. + +###### Step 4 + +Include mathematical equations and expressions in Markdown using LaTeX markup. + +{{< code file=content/math-examples.md copy=true >}} +This is an inline \(a^*=x-b^*\) equation. + +These are block equations: + +\[a^*=x-b^*\] + +\[ a^*=x-b^* \] + +\[ +a^*=x-b^* +\] + +These are also block equations: + +$$a^*=x-b^*$$ + +$$ a^*=x-b^* $$ + +$$ +a^*=x-b^* +$$ +{{< /code >}} + +If you set the `math` parameter to `false` in your site configuration, you must set the `math` parameter to `true` in front matter. For example: + +{{< code-toggle file=content/math-examples.md fm=true >}} +title = 'Math examples' +date = 2024-01-24T18:09:49-08:00 +[params] +math = true +{{< /code-toggle >}} + +## Inline delimiters + +The configuration, JavaScript, and examples above use the `\(...\)` delimiter pair for inline equations. The `$...$` delimiter pair is a common alternative, but using it may result in unintended formatting if you use the `$` symbol outside of math contexts. + +If you add the `$...$` delimiter pair to your configuration and JavaScript, you must double-escape the `$` when outside of math contexts, regardless of whether mathematical rendering is enabled on the page. For example: + +```text +A \\$5 bill _saved_ is a \\$5 bill _earned_. +``` + +{{% note %}} +If you use the `$...$` delimiter pair for inline equations, and occasionally use the `$` symbol outside of math contexts, you must use MathJax instead of KaTeX to avoid unintended formatting caused by [this KaTeX limitation](https://github.com/KaTeX/KaTeX/issues/437). +{{% /note %}} + +## Engines + +MathJax and KaTeX are open-source JavaScript display engines. Both engines are fast, but at the time of this writing MathJax v3.2.2 is slightly faster than KaTeX v0.16.11. + +{{% note %}} +If you use the `$...$` delimiter pair for inline equations, and occasionally use the `$` symbol outside of math contexts, you must use MathJax instead of KaTeX to avoid unintended formatting caused by [this KaTeX limitation](https://github.com/KaTeX/KaTeX/issues/437). + +See the [inline delimiters](#inline-delimiters) section for details. +{{% /note %}} + +To use KaTeX instead of MathJax, replace the partial template from [Step 2] with this: + +{{< code file=layouts/partials/math.html copy=true >}} - - - ++ ++ ++ + +{{< /code >}} + +The delimiters above must match the delimiters in your site configuration. + +## Chemistry + +Both MathJax and KaTeX provide support for chemical equations. For example: + +```text +$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$ +``` + +$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$ + +As shown in [Step 2] above, MathJax supports chemical equations without additional configuration. To add chemistry support to KaTeX, enable the mhchem extension as described in the KaTeX [documentation](https://katex.org/docs/libs). + +[KaTeX]: https://katex.org/ +[LaTeX]: https://www.latex-project.org/ +[MathJax]: https://www.mathjax.org/ +[Step 1]: #step-1 +[Step 2]: #step-2 +[Step 3]: #step-3 +[passthrough extension]: /getting-started/configuration-markup/#passthrough diff --cc docs/content/en/content-management/multilingual.md index b37fbf94a,000000000..8233185d5 mode 100644,000000..100644 --- a/docs/content/en/content-management/multilingual.md +++ b/docs/content/en/content-management/multilingual.md @@@ -1,644 -1,0 +1,644 @@@ +--- +title: Multilingual mode +linkTitle: Multilingual +description: Localize your project for each language and region, including translations, images, dates, currencies, numbers, percentages, and collation sequence. Hugo's multilingual framework supports single-host and multihost configurations. +categories: [content management] +keywords: [multilingual,i18n,internationalization] +menu: + docs: + parent: content-management + weight: 230 +weight: 230 +toc: true +aliases: [/content/multilingual/,/tutorials/create-a-multilingual-site/] +--- + +## Configure languages + +This is the default language configuration: + +{{< code-toggle config=languages />}} + +In the above, `en` is the language key. + +Language keys must conform to the syntax described in [RFC 5646]. For example: + +- `en` +- `en-US` + +Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7] are also supported. Omit the `art-x-` prefix from the language key. For example: + +- `hugolang` + +{{% note %}} +Private use subtags must not exceed 8 alphanumeric characters. +{{% /note %}} + +[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1 +[RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7 + +This is an example of a site configuration for a multilingual project. Any key not defined in a `languages` object will fall back to the global value in the root of your site configuration. + +{{< code-toggle file=hugo >}} +defaultContentLanguage = 'de' +defaultContentLanguageInSubdir = true + +[languages.de] +contentDir = 'content/de' +disabled = false +languageCode = 'de-DE' +languageDirection = 'ltr' +languageName = 'Deutsch' +title = 'Projekt Dokumentation' +weight = 1 + +[languages.de.params] +subtitle = 'Referenz, Tutorials und Erklärungen' + +[languages.en] +contentDir = 'content/en' +disabled = false +languageCode = 'en-US' +languageDirection = 'ltr' +languageName = 'English' +title = 'Project Documentation' +weight = 2 + +[languages.en.params] +subtitle = 'Reference, Tutorials, and Explanations' +{{< /code-toggle >}} + +defaultContentLanguage +: (`string`) The project's default language key, conforming to the syntax described in [RFC 5646]. This value must match one of the defined language keys. Examples: + +- `en` +- `en-GB` +- `pt-BR` + +defaultContentLanguageInSubdir +: (`bool`) If `true`, Hugo renders the default language site in a subdirectory matching the `defaultContentLanguage`. Default is `false`. + +contentDir +: (`string`) The `content` directory for this language. Omit if [translating by file name]. + +disabled +: (`bool`) If `true`, Hugo will not render content for this language. Default is `false`. + +languageCode +: (`string`) The language tag as described in [RFC 5646]. This value does not affect localization or URLs. Hugo uses this value to populate the `language` element in the [built-in RSS template], and the `lang` attribute of the `html` element in the [built-in alias template]. Examples: + +- `en` +- `en-GB` +- `pt-BR` + +languageDirection +: (`string`) The language direction, either left-to-right (`ltr`) or right-to-left (`rtl`). Use this value in your templates with the global [`dir`] HTML attribute. + +languageName +: (`string`) The language name, typically used when rendering a language switcher. + +title +: (`string`) The site title for this language (optional). + +weight +: (`int`) The language weight. When set to a non-zero value, this is the primary sort criteria for this language. + +[`dir`]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir +[built-in RSS template]: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml +[built-in alias template]: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/alias.html +[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1 +[translating by file name]: #translation-by-file-name + +### Site parameters + +Set language-specific site parameters under each language's `params` key: + +{{< code-toggle file=hugo >}} +[params] +color = "red" + +[languages] + [languages.de] + languageCode = 'de-DE' + title = 'Projekt Dokumentation' + weight = 1 + [languages.de.params] + color = 'blue' + subtitle = 'Referenz, Tutorials und Erklärungen' + [languages.en] + languageCode = 'en-US' + title = 'Project Documentation' + weight = 2 + [languages.en.params] + subtitle = 'Reference, Tutorials, and Explanations' +{{< /code-toggle >}} + +When building the English site: + +```go-html-template +{{ site.Params.color }} --> red +{{ site.Params.subtitle }} --> Reference, Tutorials, and Explanations +``` + - When building the English site: ++When building the German site: + +```go-html-template +{{ site.Params.color }} --> blue +{{ site.Params.subtitle }} --> 'Referenz, Tutorials und Erklärungen' +``` + +### Disable a language + +To disable a language within a `languages` object in your site configuration: + +{{< code-toggle file=hugo >}} +[languages.es] +disabled = true +{{< /code-toggle >}} + +To disable one or more languages in the root of your site configuration: + +{{< code-toggle file=hugo >}} +disableLanguages = ["es", "fr"] +{{< /code-toggle >}} + +To disable one or more languages using an environment variable: + +```sh +HUGO_DISABLELANGUAGES="es fr" hugo +``` + +Note that you cannot disable the default content language. + +### Configure multilingual multihost + +Hugo supports multiple languages in a multihost configuration. This means you can configure a `baseURL` per `language`. + +{{% note %}} +If a `baseURL` is set on the `language` level, then all languages must have one and they must all be different. +{{% /note %}} + +Example: + +{{< code-toggle file=hugo >}} +[languages] + [languages.en] + baseURL = 'https://en.example.org/' + languageName = 'English' + title = 'In English' + weight = 2 + [languages.fr] + baseURL = 'https://fr.example.org' + languageName = 'Français' + title = 'En Français' + weight = 1 +{{}} + +With the above, the two sites will be generated into `public` with their own root: + +```text +public +├── en +└── fr +``` + +**All URLs (i.e `.Permalink` etc.) will be generated from that root. So the English home page above will have its `.Permalink` set to `https://example.org/`.** + +When you run `hugo server` we will start multiple HTTP servers. You will typically see something like this in the console: + +```text +Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1) fr +Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1) en +Press Ctrl+C to stop +``` + +Live reload and `--navigateToChanged` between the servers work as expected. + +## Translate your content + +There are two ways to manage your content translations. Both ensure each page is assigned a language and is linked to its counterpart translations. + +### Translation by file name + +Considering the following example: + +1. `/content/about.en.md` +1. `/content/about.fr.md` + +The first file is assigned the English language and is linked to the second. +The second file is assigned the French language and is linked to the first. + +Their language is __assigned__ according to the language code added as a __suffix to the file name__. + +By having the same **path and base file name**, the content pieces are __linked__ together as translated pages. + +{{% note %}} +If a file has no language code, it will be assigned the default language. +{{% /note %}} + +### Translation by content directory + +This system uses different content directories for each of the languages. Each language's `content` directory is set using the `contentDir` parameter. + +{{< code-toggle file=hugo >}} +languages: + en: + weight: 10 + languageName: "English" + contentDir: "content/english" + fr: + weight: 20 + languageName: "Français" + contentDir: "content/french" +{{< /code-toggle >}} + +The value of `contentDir` can be any valid path -- even absolute path references. The only restriction is that the content directories cannot overlap. + +Considering the following example in conjunction with the configuration above: + +1. `/content/english/about.md` +1. `/content/french/about.md` + +The first file is assigned the English language and is linked to the second. +The second file is assigned the French language and is linked to the first. + +Their language is __assigned__ according to the `content` directory they are __placed__ in. + +By having the same **path and basename** (relative to their language `content` directory), the content pieces are __linked__ together as translated pages. + +### Bypassing default linking + +Any pages sharing the same `translationKey` set in front matter will be linked as translated pages regardless of basename or location. + +Considering the following example: + +1. `/content/about-us.en.md` +1. `/content/om.nn.md` +1. `/content/presentation/a-propos.fr.md` + +{{< code-toggle >}} +translationKey: "about" +{{< /code-toggle >}} + +By setting the `translationKey` front matter parameter to `about` in all three pages, they will be __linked__ as translated pages. + +### Localizing permalinks + +Because paths and file names are used to handle linking, all translated pages will share the same URL (apart from the language subdirectory). + +To localize URLs: + +- For a regular page, set either [`slug`] or [`url`] in front matter +- For a section page, set [`url`] in front matter + +[`slug`]: /content-management/urls/#slug +[`url`]: /content-management/urls/#url + +For example, a French translation can have its own localized slug. + +{{< code-toggle file=content/about.fr.md fm=true >}} +title: A Propos +slug: "a-propos" +{{< /code-toggle >}} + +At render, Hugo will build both `/about/` and `/fr/a-propos/` without affecting the translation link. + +### Page bundles + +To avoid the burden of having to duplicate files, each Page Bundle inherits the resources of its linked translated pages' bundles except for the content files (Markdown files, HTML files etc...). + +Therefore, from within a template, the page will have access to the files from all linked pages' bundles. + +If, across the linked bundles, two or more files share the same basename, only one will be included and chosen as follows: + +* File from current language bundle, if present. +* First file found across bundles by order of language `Weight`. + +{{% note %}} +Page Bundle resources follow the same language assignment logic as content files, both by file name (`image.jpg`, `image.fr.jpg`) and by directory (`english/about/header.jpg`, `french/about/header.jpg`). +{{%/ note %}} + +## Reference translated content + +To create a list of links to translated content, use a template similar to the following: + +{{< code file=layouts/partials/i18nlist.html >}} +{{ if .IsTranslated }} +

{{ i18n "translations" }}

+ +{{ end }} +{{< /code >}} + +The above can be put in a `partial` (i.e., inside `layouts/partials/`) and included in any template. It will not print anything if there are no translations for a given page. + +The above also uses the [`i18n` function][i18func] described in the next section. + +### List all available languages + +`.AllTranslations` on a `Page` can be used to list all translations, including the page itself. On the home page it can be used to build a language navigator: + +{{< code file=layouts/partials/allLanguages.html >}} + +{{< /code >}} + +## Translation of strings + +See the [`lang.Translate`] template function. + +[`lang.Translate`]: /functions/lang/translate + +## Localization + +The following localization examples assume your site's primary language is English, with translations to French and German. + +{{< code-toggle file=hugo >}} +defaultContentLanguage = 'en' + +[languages] +[languages.en] +contentDir = 'content/en' +languageName = 'English' +weight = 1 +[languages.fr] +contentDir = 'content/fr' +languageName = 'Français' +weight = 2 +[languages.de] +contentDir = 'content/de' +languageName = 'Deutsch' +weight = 3 + +{{< /code-toggle >}} + +### Dates + +With this front matter: + +{{< code-toggle >}} +date = 2021-11-03T12:34:56+01:00 +{{< /code-toggle >}} + +And this template code: + +```go-html-template +{{ .Date | time.Format ":date_full" }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|Wednesday, November 3, 2021 +Français|mercredi 3 novembre 2021 +Deutsch|Mittwoch, 3. November 2021 + +See [`time.Format`] for details. + +### Currency + +With this template code: + +```go-html-template +{{ 512.5032 | lang.FormatCurrency 2 "USD" }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|$512.50 +Français|512,50 $US +Deutsch|512,50 $ + +See [lang.FormatCurrency] and [lang.FormatAccounting] for details. + +### Numbers + +With this template code: + +```go-html-template +{{ 512.5032 | lang.FormatNumber 2 }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|512.50 +Français|512,50 +Deutsch|512,50 + +See [lang.FormatNumber] and [lang.FormatNumberCustom] for details. + +### Percentages + +With this template code: + +```go-html-template +{{ 512.5032 | lang.FormatPercent 2 }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|512.50% +Français|512,50 % +Deutsch|512,50 % + +See [lang.FormatPercent] for details. + +## Menus + +Localization of menu entries depends on how you define them: + +- When you define menu entries [automatically] using the section pages menu, you must use translation tables to localize each entry. +- When you define menu entries [in front matter], they are already localized based on the front matter itself. If the front matter values are insufficient, use translation tables to localize each entry. +- When you define menu entries [in site configuration], you must create language-specific menu entries under each language key. If the names of the menu entries are insufficient, use translation tables to localize each entry. + +### Create language-specific menu entries + +#### Method 1 -- Use a single configuration file + +For a simple menu with a small number of entries, use a single configuration file. For example: + +{{< code-toggle file=hugo >}} +[languages.de] +languageCode = 'de-DE' +languageName = 'Deutsch' +weight = 1 + +[[languages.de.menus.main]] +name = 'Produkte' +pageRef = '/products' +weight = 10 + +[[languages.de.menus.main]] +name = 'Leistungen' +pageRef = '/services' +weight = 20 + +[languages.en] +languageCode = 'en-US' +languageName = 'English' +weight = 2 + +[[languages.en.menus.main]] +name = 'Products' +pageRef = '/products' +weight = 10 + +[[languages.en.menus.main]] +name = 'Services' +pageRef = '/services' +weight = 20 +{{< /code-toggle >}} + +#### Method 2 -- Use a configuration directory + +With a more complex menu structure, create a [configuration directory] and split the menu entries into multiple files, one file per language. For example: + +```text +config/ +└── _default/ + ├── menus.de.toml + ├── menus.en.toml + └── hugo.toml +``` + +{{< code-toggle file=config/_default/menus.de >}} +[[main]] +name = 'Produkte' +pageRef = '/products' +weight = 10 +[[main]] +name = 'Leistungen' +pageRef = '/services' +weight = 20 +{{< /code-toggle >}} + +{{< code-toggle file=config/_default/menus.en >}} +[[main]] +name = 'Products' +pageRef = '/products' +weight = 10 +[[main]] +name = 'Services' +pageRef = '/services' +weight = 20 +{{< /code-toggle >}} + +[configuration directory]: /getting-started/configuration/#configuration-directory + +### Use translation tables + +When rendering the text that appears in menu each entry, the [example menu template] does this: + +```go-html-template +{{ or (T .Identifier) .Name | safeHTML }} +``` + +It queries the translation table for the current language using the menu entry's `identifier` and returns the translated string. If the translation table does not exist, or if the `identifier` key is not present in the translation table, it falls back to `name`. + +The `identifier` depends on how you define menu entries: + +- If you define the menu entry [automatically] using the section pages menu, the `identifier` is the page's `.Section`. +- If you define the menu entry [in site configuration] or [in front matter], set the `identifier` property to the desired value. + +For example, if you define menu entries in site configuration: + +{{< code-toggle file=hugo >}} +[[menus.main]] + identifier = 'products' + name = 'Products' + pageRef = '/products' + weight = 10 +[[menus.main]] + identifier = 'services' + name = 'Services' + pageRef = '/services' + weight = 20 +{{< / code-toggle >}} + +Create corresponding entries in the translation tables: + +{{< code-toggle file=i18n/de >}} +products = 'Produkte' +services = 'Leistungen' +{{< / code-toggle >}} + +[example menu template]: /templates/menu/#example +[automatically]: /content-management/menus/#define-automatically +[in front matter]: /content-management/menus/#define-in-front-matter +[in site configuration]: /content-management/menus/#define-in-site-configuration + +## Missing translations + +If a string does not have a translation for the current language, Hugo will use the value from the default language. If no default value is set, an empty string will be shown. + +While translating a Hugo website, it can be handy to have a visual indicator of missing translations. The [`enableMissingTranslationPlaceholders` configuration option][config] will flag all untranslated strings with the placeholder `[i18n] identifier`, where `identifier` is the id of the missing translation. + +{{% note %}} +Hugo will generate your website with these missing translation placeholders. It might not be suitable for production environments. +{{% /note %}} + +For merging of content from other languages (i.e. missing content translations), see [lang.Merge]. + +To track down missing translation strings, run Hugo with the `--printI18nWarnings` flag: + +```sh +hugo --printI18nWarnings | grep i18n +i18n|MISSING_TRANSLATION|en|wordCount +``` + +## Multilingual themes support + +To support Multilingual mode in your themes, some considerations must be taken for the URLs in the templates. If there is more than one language, URLs must meet the following criteria: + +* Come from the built-in `.Permalink` or `.RelPermalink` +* Be constructed with the [`relLangURL`] or [`absLangURL`] template function, or be prefixed with `{{ .LanguagePrefix }}` + +If there is more than one language defined, the `LanguagePrefix` method will return `/en` (or whatever the current language is). If not enabled, it will be an empty string (and is therefore harmless for single-language Hugo websites). + +## Generate multilingual content with `hugo new content` + +If you organize content with translations in the same directory: + +```sh +hugo new content post/test.en.md +hugo new content post/test.de.md +``` + +If you organize content with translations in different directories: + +```sh +hugo new content content/en/post/test.md +hugo new content content/de/post/test.md +``` + +[`abslangurl`]: /functions/urls/abslangurl/ +[config]: /getting-started/configuration/ +[go-i18n-source]: https://github.com/nicksnyder/go-i18n +[go-i18n]: https://github.com/nicksnyder/go-i18n +[Hugo Multilingual Part 1: Content translation]: https://regisphilibert.com/blog/2018/08/hugo-multilingual-part-1-managing-content-translation/ +[i18func]: /functions/lang/translate/ +[lang.FormatAccounting]: /functions/lang/formataccounting/ +[lang.FormatCurrency]: /functions/lang/formatcurrency/ +[lang.FormatNumber]: /functions/lang/formatnumber/ +[lang.FormatNumberCustom]: /functions/lang/formatnumbercustom/ +[lang.FormatPercent]: /functions/lang/formatpercent/ +[lang.Merge]: /functions/lang/merge/ +[menus]: /content-management/menus/ +[OS environment]: /getting-started/configuration/#configure-with-environment-variables +[`rellangurl`]: /functions/urls/rellangurl/ +[`time.Format`]: /functions/time/format/ diff --cc docs/content/en/content-management/page-bundles.md index 3c5b3054b,000000000..3638f2fb5 mode 100644,000000..100644 --- a/docs/content/en/content-management/page-bundles.md +++ b/docs/content/en/content-management/page-bundles.md @@@ -1,155 -1,0 +1,155 @@@ +--- +title: Page bundles +description: Use page bundles to logically associate one or more resources with content. +categories: [content management] +keywords: [page,bundle,leaf,branch] +menu : + docs: + parent: content-management + weight: 30 +weight: 30 +toc: true +--- + +## Introduction + +A page bundle is a directory that encapsulates both content and associated resources. + +By way of example, this site has an "about" page and a "privacy" page: + +```text +content/ +├── about/ +│ ├── index.md +│ └── welcome.jpg +└── privacy.md +``` + +The "about" page is a page bundle. It logically associates a resource with content by bundling them together. Resources within a page bundle are [page resources], accessible with the [`Resources`] method on the `Page` object. + +Page bundles are either _leaf bundles_ or _branch bundles_. + +leaf bundle - : A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants. ++: A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants. + +branch bundle - : A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page. ++: A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page. + +{{% note %}} +In the definitions above and the examples below, the extension of the index file depends on the [content format](g). For example, use `index.md` for Markdown content, `index.html` for HTML content, `index.adoc` for AsciiDoc content, etc. +{{% /note %}} + +## Comparison + +Page bundle characteristics vary by bundle type. + +| | Leaf bundle | Branch bundle | +|---------------------|---------------------------------------------------------|---------------------------------------------------------| +| Index file | `index.md` | `_index.md` | +| Example | `content/about/index.md` | `content/posts/_index.md ` | +| [Page kinds](g) | `page` | `home`, `section`, `taxonomy`, or `term` | +| Template types | [single] | [home], [section], [taxonomy], or [term] | +| Descendant pages | None | Zero or more | +| Resource location | Adjacent to the index file or in a nested subdirectory | Same as a leaf bundles, but excludes descendant bundles | +| [Resource types](g) | `page`, `image`, `video`, etc. | all but `page` | + +[single]: /templates/types/#single +[home]: /templates/types/#home +[section]: /templates/types/#section +[taxonomy]: /templates/types/#taxonomy +[term]: /templates/types/#term + +Files with [resource type](g) `page` include content written in Markdown, HTML, AsciiDoc, Pandoc, reStructuredText, and Emacs Org Mode. In a leaf bundle, excluding the index file, these files are only accessible as page resources. In a branch bundle, these files are only accessible as content pages. + +## Leaf bundles + - A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants. ++A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants. + +```text +content/ +├── about +│ └── index.md +├── posts +│ ├── my-post +│ │ ├── content-1.md +│ │ ├── content-2.md +│ │ ├── image-1.jpg +│ │ ├── image-2.png +│ │ └── index.md +│ └── my-other-post +│ └── index.md +└── another-section + ├── foo.md + └── not-a-leaf-bundle + ├── bar.md + └── another-leaf-bundle + └── index.md +``` + +There are four leaf bundles in the example above: + +about +: This leaf bundle does not contain any page resources. + +my-post +: This leaf bundle contains an index file, two resources of [resource type](g) `page`, and two resources of resource type `image`. + +- content-1, content-2 + + These are resources of resource type `page`, accessible via the [`Resources`] method on the `Page` object. Hugo will not render these as individual pages. + +- image-1, image-2 + + These are resources of resource type `image`, accessible via the `Resources` method on the `Page` object + +my-other-post +: This leaf bundle does not contain any page resources. + +another-leaf-bundle +: This leaf bundle does not contain any page resources. + +{{% note %}} +Create leaf bundles at any depth within the `content` directory, but a leaf bundle may not contain another bundle. Leaf bundles do not have descendants. +{{% /note %}} + +## Branch bundles + - A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page. ++A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page. + +```text +content/ +├── branch-bundle-1/ +│ ├── _index.md +│ ├── content-1.md +│ ├── content-2.md +│ ├── image-1.jpg +│ └── image-2.png +├── branch-bundle-2/ +│ ├── a-leaf-bundle/ +│ │ └── index.md +│ └── _index.md +└── _index.md +``` + +There are three branch bundles in the example above: + +home page +: This branch bundle contains an index file, two descendant branch bundles, and no resources. + +branch-bundle-1 +: This branch bundle contains an index file, two resources of [resource type](g) `page`, and two resources of resource type `image`. + +branch-bundle-2 +: This branch bundle contains an index file and a leaf bundle. + +{{% note %}} - Create branch bundles at any depth within the `content` directory, but a leaf bundle may not contain another bundle. Leaf bundles do not have descendants. ++Create branch bundles at any depth within the `content` directory. Branch bundles may have descendants. +{{% /note %}} + +## Headless bundles + +Use [build options] in front matter to create an unpublished leaf or branch bundle whose content and resources you can include in other pages. + +[`Resources`]: /methods/page/resources/ +[build options]: /content-management/build-options/ +[page resources]: /content-management/page-resources/ diff --cc docs/content/en/content-management/page-resources.md index 4f902a67f,000000000..84c3309cd mode 100644,000000..100644 --- a/docs/content/en/content-management/page-resources.md +++ b/docs/content/en/content-management/page-resources.md @@@ -1,310 -1,0 +1,310 @@@ +--- +title: Page resources +description: Use page resources to logically associate assets with a page. +categories: [content management] +keywords: [bundle,content,resources] +menu: + docs: + parent: content-management + weight: 80 +weight: 80 +toc: true +--- + +Page resources are only accessible from [page bundles](/content-management/page-bundles), those directories with `index.md` or - `_index.md` files at their root. Page resources are only available to the ++`_index.md` files at their root. Page resources are only available to the +page with which they are bundled. + +In this example, `first-post` is a page bundle with access to 10 page resources including audio, data, documents, images, and video. Although `second-post` is also a page bundle, it has no page resources and is unable to directly access the page resources associated with `first-post`. + +```text +content +└── post + ├── first-post + │ ├── images + │ │ ├── a.jpg + │ │ ├── b.jpg + │ │ └── c.jpg + │ ├── index.md (root of page bundle) + │ ├── latest.html + │ ├── manual.json + │ ├── notice.md + │ ├── office.mp3 + │ ├── pocket.mp4 + │ ├── rating.pdf + │ └── safety.txt + └── second-post + └── index.md (root of page bundle) +``` + +## Examples + +Use any of these methods on a `Page` object to capture page resources: + + - [`Resources.ByType`] + - [`Resources.Get`] + - [`Resources.GetMatch`] + - [`Resources.Match`] + + Once you have captured a resource, use any of the applicable [`Resource`] methods to return a value or perform an action. + +[`Resource`]: /methods/resource +[`Resources.ByType`]: /methods/page/resources#bytype +[`Resources.GetMatch`]: /methods/page/resources#getmatch +[`Resources.Get`]: /methods/page/resources#get +[`Resources.Match`]: /methods/page/resources#match + +The following examples assume this content structure: + +```text +content/ +└── example/ + ├── data/ + │ └── books.json <-- page resource + ├── images/ + │ ├── a.jpg <-- page resource + │ └── b.jpg <-- page resource + ├── snippets/ + │ └── text.md <-- page resource + └── index.md +``` + +Render a single image, and throw an error if the file does not exist: + +```go-html-template +{{ $path := "images/a.jpg" }} +{{ with .Resources.Get $path }} + +{{ else }} + {{ errorf "Unable to get page resource %q" $path }} +{{ end }} +``` + +Render all images, resized to 300 px wide: + +```go-html-template +{{ range .Resources.ByType "image" }} + {{ with .Resize "300x" }} + + {{ end }} +{{ end }} +``` + +Render the markdown snippet: + +```go-html-template +{{ with .Resources.Get "snippets/text.md" }} + {{ .Content }} +{{ end }} +``` + +List the titles in the data file, and throw an error if the file does not exist. + +```go-html-template +{{ $path := "data/books.json" }} +{{ with .Resources.Get $path }} + {{ with . | transform.Unmarshal }} +

Books:

+ + {{ end }} +{{ else }} + {{ errorf "Unable to get page resource %q" $path }} +{{ end }} +``` + +## Metadata + +The page resources' metadata is managed from the corresponding page's front matter with an array/table parameter named `resources`. You can batch assign values using [wildcards](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm). + +{{% note %}} +Resources of type `page` get `Title` etc. from their own front matter. +{{% /note %}} + +name +: (`string`) Sets the value returned in `Name`. + +{{% note %}} +The methods `Match`, `Get` and `GetMatch` use `Name` to match the resources. +{{% /note %}} + +title +: (`string`) Sets the value returned in `Title` + +params +: (`map`) A map of custom key-value pairs. + +### Resources metadata example + +{{< code-toggle file=content/example.md fm=true >}} +title: Application +date : 2018-01-25 +resources : +- src : "images/sunset.jpg" + name : "header" +- src : "documents/photo_specs.pdf" + title : "Photo Specifications" + params: + icon : "photo" +- src : "documents/guide.pdf" + title : "Instruction Guide" +- src : "documents/checklist.pdf" + title : "Document Checklist" +- src : "documents/payment.docx" + title : "Proof of Payment" +- src : "**.pdf" + name : "pdf-file-:counter" + params : + icon : "pdf" +- src : "**.docx" + params : + icon : "word" +{{}} + +From the example above: + +- `sunset.jpg` will receive a new `Name` and can now be found with `.GetMatch "header"`. +- `documents/photo_specs.pdf` will get the `photo` icon. +- `documents/checklist.pdf`, `documents/guide.pdf` and `documents/payment.docx` will get `Title` as set by `title`. +- Every `PDF` in the bundle except `documents/photo_specs.pdf` will get the `pdf` icon. +- All `PDF` files will get a new `Name`. The `name` parameter contains a special placeholder [`:counter`](#the-counter-placeholder-in-name-and-title), so the `Name` will be `pdf-file-1`, `pdf-file-2`, `pdf-file-3`. +- Every docx in the bundle will receive the `word` icon. + +{{% note %}} +The order matters; only the first set values of the `title`, `name` and `params` keys will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule. +{{% /note %}} + +### The `:counter` placeholder in `name` and `title` + +The `:counter` is a special placeholder recognized in `name` and `title` parameters `resources`. + +The counter starts at 1 the first time they are used in either `name` or `title`. + +For example, if a bundle has the resources `photo_specs.pdf`, `other_specs.pdf`, `guide.pdf` and `checklist.pdf`, and the front matter has specified the `resources` as: + +{{< code-toggle file=content/inspections/engine/index.md fm=true >}} +title = 'Engine inspections' +[[resources]] + src = "*specs.pdf" + title = "Specification #:counter" +[[resources]] + src = "**.pdf" + name = "pdf-file-:counter" +{{}} + +the `Name` and `Title` will be assigned to the resource files as follows: + +| Resource file | `Name` | `Title` | +|-------------------|-------------------|-----------------------| +| checklist.pdf | `"pdf-file-1.pdf` | `"checklist.pdf"` | +| guide.pdf | `"pdf-file-2.pdf` | `"guide.pdf"` | +| other\_specs.pdf | `"pdf-file-3.pdf` | `"Specification #1"` | +| photo\_specs.pdf | `"pdf-file-4.pdf` | `"Specification #2"` | + +## Multilingual + - {{< new-in 0.123.0 >}} ++{{< new-in 0.123.0 />}} + +By default, with a multilingual single-host site, Hugo does not duplicate shared page resources when building the site. + +{{% note %}} +This behavior is limited to Markdown content. Shared page resources for other [content formats] are copied into each language bundle. + +[content formats]: /content-management/formats/ +{{% /note %}} + +Consider this site configuration: + +{{< code-toggle file=hugo >}} +defaultContentLanguage = 'de' +defaultContentLanguageInSubdir = true + +[languages.de] +languageCode = 'de-DE' +languageName = 'Deutsch' +weight = 1 + +[languages.en] +languageCode = 'en-US' +languageName = 'English' +weight = 2 +{{< /code-toggle >}} + +And this content: + +```text +content/ +└── my-bundle/ + ├── a.jpg <-- shared page resource + ├── b.jpg <-- shared page resource + ├── c.de.jpg + ├── c.en.jpg + ├── index.de.md + └── index.en.md +``` + +With v0.122.0 and earlier, Hugo duplicated the shared page resources, creating copies for each language: + +```text +public/ +├── de/ +│ ├── my-bundle/ +│ │ ├── a.jpg <-- shared page resource +│ │ ├── b.jpg <-- shared page resource +│ │ ├── c.de.jpg +│ │ └── index.html +│ └── index.html +├── en/ +│ ├── my-bundle/ +│ │ ├── a.jpg <-- shared page resource (duplicate) +│ │ ├── b.jpg <-- shared page resource (duplicate) +│ │ ├── c.en.jpg +│ │ └── index.html +│ └── index.html +└── index.html + +``` + +With v0.123.0 and later, Hugo places the shared resources in the page bundle for the default content language: + +```text +public/ +├── de/ +│ ├── my-bundle/ +│ │ ├── a.jpg <-- shared page resource +│ │ ├── b.jpg <-- shared page resource +│ │ ├── c.de.jpg +│ │ └── index.html +│ └── index.html +├── en/ +│ ├── my-bundle/ +│ │ ├── c.en.jpg +│ │ └── index.html +│ └── index.html +└── index.html +``` + +This approach reduces build times, storage requirements, bandwidth consumption, and deployment times, ultimately reducing cost. + +{{% note %}} +To resolve Markdown link and image destinations to the correct location, you must use link and image render hooks that capture the page resource with the [`Resources.Get`] method, and then invoke its [`RelPermalink`] method. + +By default, with multilingual single-host sites, Hugo enables its [embedded link render hook] and [embedded image render hook] to resolve Markdown link and image destinations. + +You may override the embedded render hooks as needed, provided they capture the resource as described above. + +[embedded link render hook]: /render-hooks/links/#default +[embedded image render hook]: /render-hooks/images/#default +[`Resources.Get`]: /methods/page/resources/#get +[`RelPermalink`]: /methods/resource/relpermalink/ +{{% /note %}} + +Although duplicating shared page resources is inefficient, you can enable this feature in your site configuration if desired: + +{{< code-toggle file=hugo >}} +[markup.goldmark] +duplicateResourceFiles = true +{{< /code-toggle >}} diff --cc docs/content/en/content-management/sections.md index c7954aade,000000000..ce6916fd3 mode 100644,000000..100644 --- a/docs/content/en/content-management/sections.md +++ b/docs/content/en/content-management/sections.md @@@ -1,164 -1,0 +1,164 @@@ +--- +title: Sections +description: Organize content into sections. + +categories: [content management] +keywords: [lists,sections,content types,organization] +menu: + docs: + parent: content-management + weight: 120 +weight: 120 +toc: true +aliases: [/content/sections/] +--- + +## Overview + - A section is a top-level content directory, or any content directory with an `_index.md` file. A content directory with an `_index.md` file is also known as a [branch bundle](g). Section templates receive one or more page [collections](g) in [context](g). ++A section is a top-level content directory, or any content directory with an `_index.md` file. A content directory with an `_index.md` file is also known as a [branch bundle](g). Section templates receive one or more page [collections](g) in [context](g). + +{{% note %}} - Although top-level directories without `_index.md` files are sections, we recommend creating `_index.md` files in _all_ sections. ++Although top-level directories without `_index.md` files are sections, we recommend creating `_index.md` files in _all_ sections. +{{% /note %}} + +A typical site consists of one or more sections. For example: + +```text +content/ +├── articles/ <-- section (top-level directory) +│ ├── 2022/ +│ │ ├── article-1/ +│ │ │ ├── cover.jpg +│ │ │ └── index.md +│ │ └── article-2.md +│ └── 2023/ +│ ├── article-3.md +│ └── article-4.md +├── products/ <-- section (top-level directory) +│ ├── product-1/ <-- section (has _index.md file) +│ │ ├── benefits/ <-- section (has _index.md file) +│ │ │ ├── _index.md +│ │ │ ├── benefit-1.md +│ │ │ └── benefit-2.md +│ │ ├── features/ <-- section (has _index.md file) +│ │ │ ├── _index.md +│ │ │ ├── feature-1.md +│ │ │ └── feature-2.md +│ │ └── _index.md +│ └── product-2/ <-- section (has _index.md file) +│ ├── benefits/ <-- section (has _index.md file) +│ │ ├── _index.md +│ │ ├── benefit-1.md +│ │ └── benefit-2.md +│ ├── features/ <-- section (has _index.md file) +│ │ ├── _index.md +│ │ ├── feature-1.md +│ │ └── feature-2.md +│ └── _index.md +├── _index.md +└── about.md +``` + +The example above has two top-level sections: articles and products. None of the directories under articles are sections, while all of the directories under products are sections. A section within a section is a known as a nested section or subsection. + +## Explanation + +Sections and non-sections behave differently. + +||Sections|Non-sections +:--|:-:|:-: +Directory names become URL segments|:heavy_check_mark:|:heavy_check_mark: +Have logical ancestors and descendants|:heavy_check_mark:|:x: +Have list pages|:heavy_check_mark:|:x: + +With the file structure from the [example above](#overview): + +1. The list page for the articles section includes all articles, regardless of directory structure; none of the subdirectories are sections. + +1. The articles/2022 and articles/2023 directories do not have list pages; they are not sections. + +1. The list page for the products section, by default, includes product-1 and product-2, but not their descendant pages. To include descendant pages, use the `RegularPagesRecursive` method instead of the `Pages` method in the list template. + +[`Pages`]: /methods/page/pages/ +[`RegularPagesRecursive`]: /methods/page/regularpagesrecursive/ + +1. All directories in the products section have list pages; each directory is a section. + +## Template selection + +Hugo has a defined [lookup order] to determine which template to use when rendering a page. The [lookup rules] consider the top-level section name; subsection names are not considered when selecting a template. + +With the file structure from the [example above](#overview): + +Content directory|Section template +:--|:-- +`content/products`|`layouts/products/list.html` +`content/products/product-1`|`layouts/products/list.html` +`content/products/product-1/benefits`|`layouts/products/list.html` + +Content directory|Single template +:--|:-- +`content/products`|`layouts/products/single.html` +`content/products/product-1`|`layouts/products/single.html` +`content/products/product-1/benefits`|`layouts/products/single.html` + +If you need to use a different template for a subsection, specify `type` and/or `layout` in front matter. + +[lookup rules]: /templates/lookup-order/#lookup-rules +[lookup order]: /templates/lookup-order/ + +## Ancestors and descendants + +A section has one or more ancestors (including the home page), and zero or more descendants. With the file structure from the [example above](#overview): + +```text +content/products/product-1/benefits/benefit-1.md +``` + +The content file (benefit-1.md) has four ancestors: benefits, product-1, products, and the home page. This logical relationship allows us to use the `.Parent` and `.Ancestors` methods to traverse the site structure. + +For example, use the `.Ancestors` method to render breadcrumb navigation. + +{{< code file=layouts/partials/breadcrumb.html >}} + +{{< /code >}} + +With this CSS: + +```css +.breadcrumb ol { + padding-left: 0; +} + +.breadcrumb li { + display: inline; +} + +.breadcrumb li:not(:last-child)::after { + content: "»"; +} +``` + +Hugo renders this, where each breadcrumb is a link to the corresponding page: + +```text +Home » Products » Product 1 » Benefits » Benefit 1 +``` + +[archetype]: /content-management/archetypes/ +[content type]: /content-management/types/ +[directory structure]: /getting-started/directory-structure/ +[section templates]: /templates/types/#section +[leaf bundles]: /content-management/page-bundles/#leaf-bundles +[branch bundles]: /content-management/page-bundles/#branch-bundles diff --cc docs/content/en/content-management/shortcodes.md index cd1f2cb43,000000000..1c5e2c99c mode 100644,000000..100644 --- a/docs/content/en/content-management/shortcodes.md +++ b/docs/content/en/content-management/shortcodes.md @@@ -1,91 -1,0 +1,241 @@@ +--- +title: Shortcodes - description: Shortcodes are simple snippets inside your content files calling built-in or custom templates. ++description: Use embedded, custom, or inline shortcodes to insert elements such as videos, images, and social media embeds into your content. +categories: [content management] - keywords: [markdown,content,shortcodes] ++keywords: [] +menu: + docs: + parent: content-management + weight: 100 +weight: 100 - toc: true +aliases: [/extras/shortcodes/] - testparam: "Hugo Rocks!" ++toc: true +--- + - ## What a shortcode is ++## Introduction ++ ++{{% glossary-term shortcode %}} ++ ++There are three types of shortcodes: embedded, custom, and inline. ++ ++## Embedded ++ ++Hugo's embedded shortcodes are pre-defined templates within the application. Refer to each shortcode's documentation for specific usage instructions and available arguments. ++ ++{{< list-pages-in-section path=/shortcodes >}} ++ ++## Custom ++ ++Create custom shortcodes to simplify and standardize content creation. For example, the following shortcode template generates an audio player using a [global resource](g): ++ ++{{< code file=layouts/shortcodes/audio.html >}} ++{{ with resources.Get (.Get "src") }} ++ ++{{ end }} ++{{< /code >}} ++ ++Then call the shortcode from within markup: ++ ++{{< code file=content/example.md >}} ++{{}} ++{{< /code >}} ++ ++Learn more about creating shortcodes in the [shortcode templates] section. ++ ++[shortcode templates]: /templates/shortcode/ ++ ++## Inline ++ ++An inline shortcode is a shortcode template defined within content. ++ ++Hugo's security model is based on the premise that template and configuration authors are trusted, but content authors are not. This model enables generation of HTML output safe against code injection. ++ ++To conform with this security model, creating shortcode templates within content is disabled by default. If you trust your content authors, you can enable this functionality in your site's configuration: ++ ++{{< code-toggle file=hugo >}} ++[security] ++enableInlineShortcodes = true ++{{< /code-toggle >}} ++ ++The following example demonstrates an inline shortcode, `date.inline`, that accepts a single positional argument: a date/time [layout string]. ++ ++[layout string]: /functions/time/format/#layout-string ++ ++{{< code file=content/example.md >}} ++Today is ++{{}} ++ {{- now | time.Format (.Get 0) -}} ++{{}}. ++ ++Today is {{}}. ++{{< /code >}} ++ ++In the example above, the inline shortcode is executed twice: once upon definition and again when subsequently called. Hugo renders this to: ++ ++```html ++

Today is Jan 30, 2025.

++

Today is Thursday, January 30, 2025

++``` ++ ++Inline shortcodes process their inner content within the same context as regular shortcode templates, allowing you to use any available [shortcode method]. ++ ++[shortcode method]: /templates/shortcode/#methods ++ ++{{% note %}} ++You cannot [nest](#nesting) inline shortcodes. ++{{% /note %}} ++ ++Learn more about creating shortcodes in the [shortcode templates] section. ++ ++## Calling + - Hugo loves Markdown because of its simple content format, but there are times when Markdown falls short. Often, content authors are forced to add raw HTML (e.g., video ` - ++{{< code file=content/example/index.md >}} ++{{}} +{{< /code >}} + - {{< code file=youtube-embed.html >}} -
- -
++{{< code file=layouts/shortcodes/image.html >}} ++{{- .Params.path }} → a.jpg ++{{- .Params.width }} → 300 ++{{- .Params.alt }} → A white kitten +{{< /code >}} + - ### Single named example: `image` - - Let's say you want to create your own `img` shortcode rather than use Hugo's built-in [`figure` shortcode][figure]. Your goal is to be able to call the shortcode as follows in your content files: ++ When using positional arguments, the `Params` method returns a slice: + - {{< code file=content-image.md >}} - {{}} ++{{< code file=content/example/index.md >}} ++{{}} +{{< /code >}} + - You have created the shortcode at `/layouts/shortcodes/img.html`, which loads the following shortcode template: - - {{< code file=layouts/shortcodes/img.html >}} - -
- {{ with .Get "link" }}{{ end }} - - {{ if .Get "link" }}{{ end }} - {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr") }} -
{{ if isset .Params "title" }} -

{{ .Get "title" }}

{{ end }} - {{ if or (.Get "caption") (.Get "attr") }}

- {{ .Get "caption" }} - {{ with .Get "attrlink" }} {{ end }} - {{ .Get "attr" }} - {{ if .Get "attrlink" }} {{ end }} -

{{ end }} -
- {{ end }} -
- ++{{< code file=layouts/shortcodes/image.html >}} ++{{- index .Params 0 }} → a.jpg ++{{- index .Params 1 }} → 300 ++{{- index .Params 1 }} → A white kitten +{{< /code >}} + - Would be rendered as: ++Combine the `Params` method with the [`collections.IsSet`] function to determine if a parameter is set, even if its value is falsy. + - {{< code file=img-output.html >}} -
- -
-

Steve Francia

-
-
- {{< /code >}} ++[`collections.IsSet`]: /functions/collections/isset/ + - ### Single flexible example: `vimeo` ++### Inner content + - ```go-html-template - {{}} - {{}} - ``` ++Extract the content enclosed within shortcode tags using the [`Inner`] method. This example demonstrates how to pass both content and a title to a shortcode. The shortcode then generates a `div` element containing an `h2` element (displaying the title) and the provided content. + - Would load the template found at `/layouts/shortcodes/vimeo.html`: ++[`Inner`]: /methods/shortcode/inner/ + - {{< code file=layouts/shortcodes/vimeo.html >}} - {{ if .IsNamedParams }} -
- -
- {{ else }} -
- -
- {{ end }} ++{{< code file=content/example.md >}} ++{{}} ++This is a **bold** word, and this is an _emphasized_ word. ++{{}} +{{< /code >}} + - Would be rendered as: - - {{< code file=vimeo-iframes.html >}} -
- -
-
- ++{{< code file=layouts/shortcodes/contrived.html >}} ++
++

{{ .Get "title" }}

++ {{ .Inner | .Page.RenderString }} +
+{{< /code >}} + - ### Paired example: `highlight` ++The preceding example called the shortcode using [standard notation], requiring us to process the inner content with the [`RenderString`] method to convert the Markdown to HTML. This conversion is unnecessary when calling a shortcode using [Markdown notation]. + - The following is taken from `highlight`, which is a [built-in shortcode] that ships with Hugo. ++[`RenderString`]: /methods/page/renderstring/ ++[markdown notation]: /content-management/shortcodes/#markdown-notation ++[standard notation]: /content-management/shortcodes/#standard-notation + - {{< code file=highlight-example.md >}} - {{}} - - This HTML - - {{}} - {{< /code >}} - - The template for the `highlight` shortcode uses the following code, which is already included in Hugo: - - ```go-html-template - {{ .Get 0 | highlight .Inner }} - ``` - - The rendered output of the HTML example code block will be as follows: ++### Nesting + - {{< code file=syntax-highlighted.html >}} -
<html>
-     <body> This HTML </body>
- </html>
- 
- {{< /code >}} - - ### Nested shortcode: image gallery ++The [`Parent`] method provides access to the parent shortcode context when the shortcode in question is called within the context of a parent shortcode. This provides an inheritance model. + - Hugo's [`.Parent`] shortcode method provides access to the parent shortcode context when the shortcode in question is called within the context of a parent shortcode. This provides an inheritance model. ++[`Parent`]: /methods/shortcode/parent/ + +The following example is contrived but demonstrates the concept. Assume you have a `gallery` shortcode that expects one named `class` argument: + +{{< code file=layouts/shortcodes/gallery.html >}} +
+ {{ .Inner }} +
+{{< /code >}} + +You also have an `img` shortcode with a single named `src` argument that you want to call inside of `gallery` and other shortcodes, so that the parent defines the context of each `img`: + +{{< code file=layouts/shortcodes/img.html >}} - {{- $src := .Get "src" -}} - {{- with .Parent -}} ++{{ $src := .Get "src" }} ++{{ with .Parent }} + - {{- else -}} ++{{ else }} + - {{- end -}} ++{{ end }} +{{< /code >}} + +You can then call your shortcode in your content as follows: + - ```go-html-template ++{{< code file=content/example.md >}} +{{}} + {{}} + {{}} +{{}} +{{}} - ``` ++{{< /code >}} ++ + +This will output the following HTML. Note how the first two `img` shortcodes inherit the `class` value of `content-gallery` set with the call to the parent `gallery`, whereas the third `img` only uses `src`: + +```html + + +``` + - ## Error handling in shortcodes - - Use the [`errorf`] template function with the [`Name`] and [`Position`] shortcode methods to generate useful error messages: - - {{< code file=layouts/shortcodes/greeting.html >}} - {{ with .Get "name" }} -

Hello, my name is {{ . }}.

- {{ else }} - {{ errorf "The %q shortcode requires a 'name' argument. See %s" .Name .Position }} - {{ end }} - {{< /code >}} - - When the above fails, you will see an `ERROR` message such as: - - ```sh - ERROR The "greeting" shortcode requires a 'name' argument. See "/home/user/project/content/_index.md:12:1" - ``` - - ## Inline shortcodes - - You can also implement your shortcodes inline -- e.g. where you use them in the content file. This can be useful for scripting that you only need in one place. - - This feature is disabled by default, but can be enabled in your site configuration: - - {{< code-toggle file=hugo >}} - [security] - enableInlineShortcodes = true - {{< /code-toggle >}} ++### Other examples + - It is disabled by default for security reasons. The security model used by Hugo's template handling assumes that template authors are trusted, but that the content files are not, so the templates are injection-safe from malformed input data. But in most situations you have full control over the content, too, and then `enableInlineShortcodes = true` would be considered safe. But it's something to be aware of: It allows ad-hoc [Go Text templates](https://golang.org/pkg/text/template/) to be executed from the content files. ++For guidance, consider examining Hugo's embedded shortcodes. The source code, available on [GitHub], can provide a useful model. + - And once enabled, you can do this in your content files: ++[GitHub]: https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates/shortcodes + - ```go-html-template - {{}}{{ now }}{{}} - ``` ++## Detection + - The above will print the current date and time. ++The [`HasShortcode`] method allows you to check if a specific shortcode has been called on a page. For example, consider a custom audio shortcode: + - Note that an inline shortcode's inner content is parsed and executed as a Go text template with the same context as a regular shortcode template. - - This means that the current page can be accessed via `.Page.Title` etc. This also means that there are no concept of "nested inline shortcodes". ++{{< code file=content/example.md >}} ++{{}} ++{{< /code >}} + - The same inline shortcode can be reused later in the same content file, with different arguments if needed, using the self-closing syntax: ++You can use the `HasShortcode` method in your base template to conditionally load CSS if the audio shortcode was used on the page: + - ```go-html-template - {{}} - ``` ++{{< code file=layouts/_default/baseof.html >}} ++ ++ ... ++ {{ if .HasShortcode "audio" }} ++ ++ {{ end }} ++ ... ++ ++{{< /code >}} + - [`.Parent`]: /methods/shortcode/parent/ - [`errorf`]: /functions/fmt/errorf/ - [`Name`]: /methods/shortcode/name/ - [`Position`]: /methods/shortcode/position/ - [built-in shortcode]: /content-management/shortcodes/ - [figure]: /shortcodes/figure/ - [lookup order]: /templates/lookup-order/ - [source organization]: /getting-started/directory-structure/ - [vimeoexample]: #single-flexible-example-vimeo - [youtubeshortcode]: /shortcodes/youtube/ ++[`HasShortcode`]: /methods/page/hasshortcode/ diff --cc docs/content/en/templates/sitemap.md index 166f54933,000000000..b21372040 mode 100644,000000..100644 --- a/docs/content/en/templates/sitemap.md +++ b/docs/content/en/templates/sitemap.md @@@ -1,82 -1,0 +1,82 @@@ +--- +title: Sitemap templates +description: Hugo provides built-in sitemap templates. +categories: [templates] +keywords: [] +menu: + docs: + parent: templates + weight: 140 +weight: 140 +toc: true +aliases: [/layout/sitemap/,/templates/sitemap-template/] +--- + +## Overview + +Hugo's embedded sitemap templates conform to v0.9 of the [sitemap protocol]. + +With a monolingual project, Hugo generates a sitemap.xml file in the root of the [`publishDir`] using the [embedded sitemap template]. + +With a multilingual project, Hugo generates: + +- A sitemap.xml file in the root of each site (language) using the [embedded sitemap template] +- A sitemap.xml file in the root of the [`publishDir`] using the [embedded sitemapindex template] + +[embedded sitemap template]: {{% eturl sitemap %}} +[embedded sitemapindex template]: {{% eturl sitemapindex %}} + +## Configuration + +These are the default sitemap configuration values. They apply to all pages unless overridden in front matter. + +{{< code-toggle config=sitemap />}} + +changefreq - : (`string`) How frequently a page is likely to change. Valid values are `always`, `hourly`, `daily`, `weekly`, `monthly`, `yearly`, and `never`. With the default value of `""` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#changefreqdef). ++: (`string`) How frequently a page is likely to change. Valid values are `always`, `hourly`, `daily`, `weekly`, `monthly`, `yearly`, and `never`. With the default value of `""` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#changefreqdef). + - disable {{< new-in 0.125.0 >}} ++disable {{< new-in 0.125.0 />}} +: (`bool`) Whether to disable page inclusion. Default is `false`. Set to `true` in front matter to exclude the page. + +filename +: (`string`) The name of the generated file. Default is `sitemap.xml`. + +priority - : (`float`) The priority of a page relative to any other page on the site. Valid values range from 0.0 to 1.0. With the default value of `-1` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#priority). ++: (`float`) The priority of a page relative to any other page on the site. Valid values range from 0.0 to 1.0. With the default value of `-1` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#priority). + +## Override default values + +Override the default values for a given page in front matter. + +{{< code-toggle file=news.md fm=true >}} +title = 'News' +[sitemap] + changefreq = 'weekly' + disable = true + priority = 0.8 +{{}} + +## Override built-in templates + +To override the built-in sitemap.xml template, create a new file in either of these locations: + +- `layouts/sitemap.xml` +- `layouts/_default/sitemap.xml` + +When ranging through the page collection, access the _change frequency_ and _priority_ with `.Sitemap.ChangeFreq` and `.Sitemap.Priority` respectively. + +To override the built-in sitemapindex.xml template, create a new file in either of these locations: + +- `layouts/sitemapindex.xml` +- `layouts/_default/sitemapindex.xml` + +## Disable sitemap generation + +You may disable sitemap generation in your site configuration: + +{{< code-toggle file=hugo >}} +disableKinds = ['sitemap'] +{{}} + +[`publishDir`]: /getting-started/configuration#publishdir +[sitemap protocol]: https://www.sitemaps.org/protocol.html diff --cc docs/content/en/templates/types/index.md index 0bd72ccc4,000000000..8369917bf mode 100644,000000..100644 --- a/docs/content/en/templates/types/index.md +++ b/docs/content/en/templates/types/index.md @@@ -1,278 -1,0 +1,274 @@@ +--- +title: Template types +linkTitle: Template types +description: Create templates of different types to render your content, resources, and data. +categories: [templates] +keywords: [] +menu: + docs: + parent: templates + weight: 30 +weight: 30 +toc: true +aliases: ['/templates/lists/'] +--- + +[![structural diagram of a website](site-hierarchy.svg)](site-hierarchy.svg) + +## Structure + +Create templates in the `layouts` directory in the root of your project. + +Although your site may not require each of these templates, the example below is typical for a site of medium complexity. + +```text +layouts/ +├── _default/ +│ ├── _markup/ +│ │ ├── render-image.html <-- render hook +│ │ └── render-link.html <-- render hook +│ ├── baseof.html +│ ├── home.html +│ ├── section.html +│ ├── single.html +│ ├── taxonomy.html +│ └── term.html +├── articles/ +│ └── card.html <-- content view +├── partials/ +│ ├── footer.html +│ └── header.html +└── shortcodes/ + ├── audio.html + └── video.html +``` + +Hugo's [template lookup order] determines the template path, allowing you to create unique templates for any page. + +[template lookup order]: /templates/lookup-order/ + +{{% note %}} - You must have thorough understanding of the [template lookup order] when creating templates. Template selection is based on template type, page kind, content type, section, language, and output format. - - [template lookup order]: /templates/lookup-order/ ++You must have thorough understanding of the template lookup order when creating templates. Template selection is based on template type, page kind, content type, section, language, and output format. +{{% /note %}} + +The purpose of each template type is described below. + +## Base + +Base templates reduce duplicate code by wrapping other templates within a shell. + +For example, the base template below calls the [partial] function to include partial templates for the `head`, `header`, and `footer` elements of each page, and it uses the [block] function to include `home`, `single`, `section`, `taxonomy`, and `term` templates within the `main` element of each page. + +[block]: /functions/go-template/block/ +[partial]: /functions/partials/include/ + +{{< code file=layouts/_default/baseof.html >}} + + + + {{ partial "head.html" . }} + + +
+ {{ partial "header.html" . }} +
+
+ {{ block "main" . }}{{ end }} +
+
+ {{ partial "footer.html" . }} +
+ + +{{< /code >}} + +Learn more about [base templates](/templates/base/). + +## Home + - A home template renders your site's home page. For a single page site this is the only required template. - - For example, the home template below inherits the site's shell from the base template, and renders the home page content with a list of pages. ++A home page template is used to render your site's home page, and is the only template required for a single-page website. For example, the home page template below inherits the site's shell from the base template and renders the home page content, such as a list of other pages. + +{{< code file=layouts/_default/home.html >}} +{{ define "main" }} + {{ .Content }} + {{ range site.RegularPages }} +

{{ .LinkTitle }}

+ {{ end }} +{{ end }} +{{< /code >}} + +{{% include "templates/_common/filter-sort-group.md" %}} + - Learn more about [home templates](/templates/home/). ++Learn more about [home page templates](/templates/home/). + +## Single + +A single template renders a single page. + +For example, the single template below inherits the site's shell from the base template, and renders the title and content of each page. + +{{< code file=layouts/_default/single.html >}} +{{ define "main" }} +

{{ .Title }}

+ {{ .Content }} +{{ end }} +{{< /code >}} + +Learn more about [single templates](/templates/single/). + +## Section + +A section template typically renders a list of pages within a section. + +For example, the section template below inherits the site's shell from the base template, and renders a list of pages in the current section. + +{{< code file=layouts/_default/section.html >}} +{{ define "main" }} +

{{ .Title }}

+ {{ .Content }} + {{ range .Pages }} +

{{ .LinkTitle }}

+ {{ end }} +{{ end }} +{{< /code >}} + +{{% include "templates/_common/filter-sort-group.md" %}} + +Learn more about [section templates](/templates/section/). + +## Taxonomy + +A taxonomy template renders a list of terms in a [taxonomy](g). + +For example, the taxonomy template below inherits the site's shell from the base template, and renders a list of terms in the current taxonomy. + +{{< code file=layouts/_default/taxonomy.html >}} +{{ define "main" }} +

{{ .Title }}

+ {{ .Content }} + {{ range .Pages }} +

{{ .LinkTitle }}

+ {{ end }} +{{ end }} +{{< /code >}} + +{{% include "templates/_common/filter-sort-group.md" %}} + +Learn more about [taxonomy templates](/templates/taxonomy/). + +## Term + +A term template renders a list of pages associated with a [term](g). + +For example, the term template below inherits the site's shell from the base template, and renders a list of pages associated with the current term. + +{{< code file=layouts/_default/term.html >}} +{{ define "main" }} +

{{ .Title }}

+ {{ .Content }} + {{ range .Pages }} +

{{ .LinkTitle }}

+ {{ end }} +{{ end }} +{{< /code >}} + +{{% include "templates/_common/filter-sort-group.md" %}} + +Learn more about [term templates](/templates/term/). + +## Partial + +A partial template is typically used to render a component of your site, though you may also create partial templates that return values. + +{{% note %}} +Unlike other template types, you cannot create partial templates to target a particular page kind, content type, section, language, or output format. Partial templates do not follow Hugo's [template lookup order]. + +[template lookup order]: /templates/lookup-order/ +{{% /note %}} + +For example, the partial template below renders copyright information. + +{{< code file=layouts/partials/footer.html >}} +

Copyright {{ now.Year }}. All rights reserved.

+{{< /code >}} + +Learn more about [partial templates](/templates/partial/). + +## Content view + +A content view template is similar to a partial template, invoked by calling the [`Render`] method on a `Page` object. Unlike partial templates, content view templates: + +- Automatically inherit the context of the current page +- Follow a lookup order allowing you to target a given content type or section + +[`Render`]: /methods/page/render/ + +For example, the home template below inherits the site's shell from the base template, and renders a card component for each page within the "articles" section of your site. + +{{< code file=layouts/_default/home.html >}} +{{ define "main" }} + {{ .Content }} +
    + {{ range where site.RegularPages "Section" "articles" }} + {{ .Render "card" }} + {{ end }} +
+{{ end }} +{{< /code >}} + +{{< code file=layouts/articles/card.html >}} +
+

{{ .LinkTitle }}

+ {{ .Summary }} +
+{{< /code >}} + +Learn more about [content view templates](/templates/content-view/). + +## Render hook + +A render hook template overrides the conversion of Markdown to HTML. + +For example, the render hook template below adds a `rel` attribute to external links. + +{{< code file=layouts/_default/_markup/render-link.html >}} +{{- $u := urls.Parse .Destination -}} + - {{- with .Text | safeHTML }}{{ . }}{{ end -}} ++ {{- with .Text }}{{ . }}{{ end -}} + +{{- /* chomp trailing newline */ -}} +{{< /code >}} + +Learn more about [render hook templates](/render-hooks/). + +## Shortcode + +A shortcode template is used to render a component of your site. Unlike partial templates, shortcode templates are called from content pages. + +For example, the shortcode template below renders an audio element from a [global resource](g). + +{{< code file=layouts/shortcodes/audio.html >}} +{{ with resources.Get (.Get "src") }} + +{{ end }} +{{< /code >}} + - Call the shortcode from your content page: ++Then call the shortcode from within markup: + +{{< code file=content/example.md >}} - {{}} ++{{}} +{{< /code >}} + +Learn more about [shortcode templates](/templates/shortcode/). + +## Other + +Use other specialized templates to create: + +- [Sitemaps](/templates/sitemap) +- [RSS feeds](/templates/rss/) +- [404 error pages](/templates/404/) +- [robots.txt files](/templates/robots/) diff --cc docs/content/en/tools/_index.md index 9cd72853a,000000000..a4df23800 mode 100644,000000..100644 --- a/docs/content/en/tools/_index.md +++ b/docs/content/en/tools/_index.md @@@ -1,20 -1,0 +1,20 @@@ +--- +title: Developer tools - linkTitle: In this section - description: In addition to Hugo's powerful CLI, there is a large number of community-developed tool chains for Hugo developers. ++ ++description: Third-party tools to help you create and manage sites. +categories: [] +keywords: [] +menu: + docs: + identifier: developer-tools-in-this-section + parent: developer-tools + weight: 10 +weight: 10 +--- + +One of Hugo's greatest strengths is its passionate---and always evolving---developer community. With the exception of the `highlight` shortcode mentioned in [Syntax Highlighting][syntax], the tools and other projects featured in this section are offerings from both commercial services and open-source projects, many of which are developed by Hugo developers just like you. + +[See the popularity of Hugo compared with other static site generators.][staticgen] + +[staticgen]: https://staticgen.com +[syntax]: /content-management/syntax-highlighting/ diff --cc docs/content/en/tools/search.md index 73aea7ce4,000000000..152774304 mode 100644,000000..100644 --- a/docs/content/en/tools/search.md +++ b/docs/content/en/tools/search.md @@@ -1,58 -1,0 +1,58 @@@ +--- +title: Search tools +linkTitle: Search +description: See some of the open-source and commercial search options for your newly created Hugo website. +categories: [developer tools] +keywords: [search] +menu: + docs: + parent: developer-tools + weight: 40 +weight: 40 +toc: true +--- + +A static website with a dynamic search function? Yes, Hugo provides an alternative to embeddable scripts from Google or other search engines for static websites. Hugo allows you to provide your visitors with a custom search function by indexing your content files directly. + +## Open-source + +[Pagefind](https://github.com/cloudcannon/pagefind) +: A fully static search library that aims to perform well on large sites, while using as little of your users' bandwidth as possible. + +[GitHub Gist for Hugo Workflow](https://gist.github.com/sebz/efddfc8fdcb6b480f567) +: This gist contains a simple workflow to create a search index for your static website. It uses a simple Grunt script to index all your content files and [lunr.js](https://lunrjs.com/) to serve the search results. + +[hugo-lunr](https://www.npmjs.com/package/hugo-lunr) +: A simple way to add site search to your static Hugo site using [lunr.js](https://lunrjs.com/). Hugo-lunr will create an index file of any HTML and Markdown documents in your Hugo project. + +[hugo-lunr-zh](https://www.npmjs.com/package/hugo-lunr-zh) +: A bit like Hugo-lunr, but Hugo-lunr-zh can help you separate the Chinese keywords. + +[GitHub Gist for Fuse.js integration](https://gist.github.com/eddiewebb/735feb48f50f0ddd65ae5606a1cb41ae) - : This gist demonstrates how to leverage Hugo's existing build time processing to generate a searchable JSON index used by [Fuse.js](https://fusejs.io/) on the client-side. Although this gist uses Fuse.js for fuzzy matching, any client-side search tool capable of reading JSON indexes will work. Does not require npm, grunt, or other build-time tools except Hugo! ++: This gist demonstrates how to leverage Hugo's existing build time processing to generate a searchable JSON index used by [Fuse.js](https://fusejs.io/) on the client side. Although this gist uses Fuse.js for fuzzy matching, any client-side search tool capable of reading JSON indexes will work. Does not require npm, grunt, or other build-time tools except Hugo! + +[hugo-search-index](https://www.npmjs.com/package/hugo-search-index) +: A library containing Gulp tasks and a prebuilt browser script that implements search. Gulp generates a search index from project Markdown files. + +[hugofastsearch](https://gist.github.com/cmod/5410eae147e4318164258742dd053993) +: A usability and speed update to "GitHub Gist for Fuse.js integration" — global, keyboard-optimized search. + +[JS & Fuse.js tutorial](https://makewithhugo.com/add-search-to-a-hugo-site/) +: A simple client-side search solution, using FuseJS (does not require jQuery). + +[Hugo Lyra](https://github.com/paolomainardi/hugo-lyra) +: Hugo-Lyra is a JavaScript module to integrate [Lyra](https://github.com/LyraSearch/lyra) into a Hugo website. It contains the server-side part to generate the index and the client-side library (optional) to bootstrap the search engine easily. + +[INFINI Pizza for WebAssembly](https://github.com/infinilabs/pizza-docsearch) +: Pizza is a super-lightweight yet fully featured search engine written in Rust. You can quickly add offline search functionality to your Hugo website in just five minutes with only three lines of code. For a step-by-step guide on integrating it with Hugo, check out [this blog tutorial](https://dev.to/medcl/adding-search-functionality-to-a-hugo-static-site-based-on-infini-pizza-for-webassembly-4h5e). + +## Commercial + +[Algolia](https://www.algolia.com/) +: Algolia's Search API makes it easy to deliver a great search experience in your apps and websites. Algolia Search provides hosted full-text, numerical, faceted, and geolocalized search. + +[Bonsai](https://www.bonsai.io) +: Bonsai is a fully-managed hosted Elasticsearch service that is fast, reliable, and simple to set up. Easily ingest your docs from Hugo into Elasticsearch following [this guide from the docs](https://bonsai.io/docs/hugo). + +[ExpertRec](https://www.expertrec.com/) +: ExpertRec is a hosted search-as-a-service solution that is fast and scalable. Set-up and integration is extremely easy and takes only a few minutes. The search settings can be modified without coding using a dashboard. diff --cc docs/content/en/troubleshooting/_index.md index 92ba6bc6d,000000000..a113fa9cf mode 100644,000000..100644 --- a/docs/content/en/troubleshooting/_index.md +++ b/docs/content/en/troubleshooting/_index.md @@@ -1,16 -1,0 +1,16 @@@ +--- +title: Troubleshooting - linkTitle: In this section ++ +description: Use these techniques when troubleshooting your site. +categories: [] +keywords: [] +menu: + docs: + identifier: troubleshooting-in-this-section + parent: troubleshooting + weight: 10 +weight: 10 +aliases: [/templates/template-debugging/] +--- + +Use these techniques when troubleshooting your site. diff --cc docs/content/en/troubleshooting/deprecation.md index 81f2724a3,000000000..5dd9f3fa6 mode 100644,000000..100644 --- a/docs/content/en/troubleshooting/deprecation.md +++ b/docs/content/en/troubleshooting/deprecation.md @@@ -1,50 -1,0 +1,56 @@@ +--- +title: Deprecation +description: The Hugo project follows a formal and consistent process to deprecate functions, methods, and configuration settings. +categories: [troubleshooting] +keywords: [] +menu: + docs: + parent: troubleshooting + weight: 50 +weight: 50 +--- + +When a project _deprecates_ something, they are telling its users: + +1. Don't use Thing One anymore. +1. Use Thing Two instead. +1. We're going to remove Thing One at some point in the future. + +[reasons for deprecation]: https://en.wikipedia.org/wiki/Deprecation + +Common [reasons for deprecation]: + +- A feature has been replaced by a more powerful alternative. +- A feature contains a design flaw. +- A feature is considered extraneous, and will be removed in the future in order to simplify the system as a whole. +- A future version of the software will make major structural changes, making it impossible or impractical to support older features. +- Standardization or increased consistency in naming. +- A feature that once was available only independently is now combined with its co-feature. + +After the project team deprecates something in code, Hugo will: + - 1. Log an INFO message for 6 minor releases[^1] - 1. Log a WARN message for another 6 minor releases ++1. Log an INFO message for 3 minor releases[^1] ++1. Log a WARN message for another 12 minor releases +1. Log an ERROR message and fail the build thereafter + ++The project team will: ++ ++1. On the deprecation date, update the documentation with a note describing the deprecation and any relevant alternatives. ++1. Remove the code six or more minor releases after Hugo begins logging ERROR messages and failing the build. At that point, Hugo will throw an error, but the error message will no longer mention the deprecation. ++1. Remove the corresponding documentation two years after the deprecation date. ++ +To see the INFO messages, you must use the `--logLevel` command line flag: + +```text +hugo --logLevel info +``` + +To limit the output to deprecation notices: + +```text +hugo --logLevel info | grep deprecate +``` + +Run the above command every time you upgrade Hugo. + +[^1]: For example, v0.1.1 => v0.2.0 is a minor release. diff --cc docs/content/en/troubleshooting/faq.md index 4891c566b,000000000..2edb309be mode 100644,000000..100644 --- a/docs/content/en/troubleshooting/faq.md +++ b/docs/content/en/troubleshooting/faq.md @@@ -1,134 -1,0 +1,134 @@@ +--- +title: Frequently asked questions +linkTitle: FAQs +description: These questions are frequently asked by new users. +categories: [troubleshooting] +keywords: [faq] +menu: + docs: + parent: troubleshooting + weight: 70 +weight: 70 +--- + +Hugo’s [forum] is an active community of users and developers who answer questions, share knowledge, and provide examples. A quick search of over 20,000 topics will often answer your question. Please be sure to read about [requesting help] before asking your first question. + +These are just a few of the questions most frequently asked by new users. + +###### An error message indicates that a feature is not available. Why? {#feature-not-available} + +{{% include "installation/_common/01-editions.md" %}} + +When you attempt to use a feature that is not available in the edition that you installed, Hugo throws this error: + +```go-html-template +this feature is not available in this edition of Hugo +``` + +To resolve, install a different edition based on the feature table above. See the [installation] section for details. + +###### Why do I see "Page Not Found" when visiting the home page? + +In the `content/_index.md` file: + + - Is `draft` set to `true`? + - Is the `date` in the future? + - Is the `publishDate` in the future? + - Is the `expiryDate` in the past? + +If the answer to any of these questions is yes, either change the field values, or use one of these command line flags: `--buildDrafts`, `--buildFuture`, or `--buildExpired`. + +###### Why is a given page not published? + +In the `content/section/page.md` file, or in the `content/section/page/index.md` file: + +- Is `draft` set to `true`? +- Is the `date` in the future? +- Is the `publishDate` in the future? +- Is the `expiryDate` in the past? + +If the answer to any of these questions is yes, either change the field values, or use one of these command line flags: `--buildDrafts`, `--buildFuture`, or `--buildExpired`. + +###### Why can't I see any of a page's descendants? + - You may have an `index.md` file instead of an `_index.md` file. See [details](/content-management/page-bundles/). ++You may have an `index.md` file instead of an `_index.md` file. See [details](/content-management/page-bundles/). + - ###### What is the difference between an index.md file and an _index.md file? ++###### What is the difference between an `index.md` file and an `_index.md` file? + - A directory with an `index.md file` is a [leaf bundle](g). A directory with an `_index.md` file is a [branch bundle](g). See [details](/content-management/page-bundles/). ++A directory with an `index.md file` is a [leaf bundle](g). A directory with an `_index.md` file is a [branch bundle](g). See [details](/content-management/page-bundles/). + +###### Why is my partial template not rendered as expected? + +You may have neglected to pass the required [context](g) when calling the partial. For example: + +```go-html-template +{{/* incorrect */}} +{{ partial "_internal/pagination.html" }} + +{{/* correct */}} +{{ partial "_internal/pagination.html" . }} +``` + +###### In a template, what's the difference between `:=` and `=` when assigning values to variables? + +Use `:=` to initialize a variable, and use `=` to assign a value to a variable that has been previously initialized. See [details](https://pkg.go.dev/text/template#hdr-Variables). + +###### When I paginate a list page, why is the page collection not filtered as specified? + +You are probably invoking the [`Paginate`] or [`Paginator`] method more than once on the same page. See [details](/templates/pagination/). + +###### Why are there two ways to call a shortcode? + +Use the `{{%/* shortcode */%}}` notation if the shortcode template, or the content between the opening and closing shortcode tags, contains Markdown. Otherwise use the\ +`{{}}` notation. See [details](/content-management/shortcodes/). + +###### Can I use environment variables to control configuration? + +Yes. See [details](/getting-started/configuration/#configure-with-environment-variables). + +###### Why am I seeing inconsistent output from one build to the next? + +The most common causes are page collisions (publishing two pages to the same path) and the effects of concurrency. Use the `--printPathWarnings` command line flag to check for page collisions, and create a topic on the [forum] if you suspect concurrency problems. + +###### Why isn't Hugo's development server detecting file changes? + +In its default configuration, Hugo's file watcher may not be able detect file changes when: + +- Running Hugo within Windows Subsystem for Linux (WSL/WSL2) with project files on a Windows partition +- Running Hugo locally with project files on a removable drive +- Running Hugo locally with project files on a storage server accessed via the NFS, SMB, or CIFS protocols + +In these cases, instead of monitoring native file system events, use the `--poll` command line flag. For example, to poll the project files every 700 milliseconds, use `--poll 700ms`. + +###### Why is my page Scratch or Store missing a value? + +The [`Scratch`] and [`Store`] methods on a `Page` object allow you to create a [scratch pad](g) on the given page to store and manipulate data. Values are often set within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are not determinate until Hugo renders the page content. + +If you need to access a scratch pad value from a parent template, and the parent template has not yet rendered the page content, you can trigger content rendering by assigning the returned value to a [noop](g) variable: + +```go-html-template +{{ $noop := .Content }} +{{ .Store.Get "mykey" }} +``` + +You can trigger content rendering with other methods as well. See next FAQ. + +[`Scratch`]: /methods/page/scratch +[`Store`]: /methods/page/store + +###### Which page methods trigger content rendering? + +The following methods on a `Page` object trigger content rendering: `Content`, `ContentWithoutSummary`, `FuzzyWordCount`, `Len`, `Plain`, `PlainWords`, `ReadingTime`, `Summary`, `Truncated`, and `WordCount`. + +{{% note %}} +For other questions please visit the [forum]. A quick search of over 20,000 topics will often answer your question. Please be sure to read about [requesting help] before asking your first question. + +[forum]: https://discourse.gohugo.io +[requesting help]: https://discourse.gohugo.io/t/requesting-help/9132 +{{% /note %}} + +[`Paginate`]: /methods/page/paginate/ +[`Paginator`]: /methods/page/paginator/ +[forum]: https://discourse.gohugo.io +[installation]: /installation/ +[requesting help]: https://discourse.gohugo.io/t/requesting-help/9132 diff --cc docs/data/sponsors.toml index 000000000,000000000..705ca9746 new file mode 100644 --- /dev/null +++ b/docs/data/sponsors.toml @@@ -1,0 -1,0 +1,22 @@@ ++[[banners]] ++ name = "Linode" ++ link = "https://www.linode.com/" ++ logo = "images/sponsors/linode-logo.svg" ++ utm_campaign = "hugosponsor" ++ bgcolor = "#ffffff" ++ ++[[banners]] ++ name = "GoLand" ++ title = "The complete IDE crafted for professional Go developers." ++ no_query_params = true ++ 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'" diff --cc docs/go.mod index 56a48deac,000000000..4b9e0a369 mode 100644,000000..100644 --- a/docs/go.mod +++ b/docs/go.mod @@@ -1,5 -1,0 +1,3 @@@ +module github.com/gohugoio/hugoDocs + +go 1.22.0 - - require github.com/gohugoio/gohugoioTheme v0.0.0-20250116152525-2d382cae7743 // indirect diff --cc docs/hugo.toml index 2a271b6e3,000000000..c0094725f mode 100644,000000..100644 --- a/docs/hugo.toml +++ b/docs/hugo.toml @@@ -1,102 -1,0 +1,174 @@@ - # This his the main configuration file. There are also environment specific configuration stored in the /config directory. - +baseURL = "https://gohugo.io/" +defaultContentLanguage = "en" +enableEmoji = true - ignoreErrors = ["error-remote-getjson", "error-missing-instagram-accesstoken"] ++ignoreLogs = ["error-missing-instagram-accesstoken"] +languageCode = "en-us" +pluralizeListTitles = false +timeZone = "Europe/Oslo" +title = "Hugo" + +# We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below). +disableAliases = true + +[pagination] - pagerSize = 100 ++ pagerSize = 100 + +[services.googleAnalytics] - ID = 'G-MBZGKNMDWC' ++ ID = 'G-MBZGKNMDWC' + - [minify] - [minify.tdewolff] - [minify.tdewolff.html] - keepWhitespace = true ++[outputs] ++ home = ["html", "rss", "redir", "headers"] ++ section = ["html"] ++ page = ["html"] ++ taxonomy = ["html"] ++ term = ["html"] + - [module] - [module.hugoVersion] - min = "0.56.0" - [[module.imports]] - path = "github.com/gohugoio/gohugoioTheme" ++[params] ++ description = "The world’s fastest framework for building websites" ++ ghrepo = "https://github.com/gohugoio/hugoDocs/" + - [outputs] - home = ["HTML", "RSS", "REDIR", "HEADERS"] - section = ["HTML"] ++ [params.render_hooks.link] ++ errorLevel = 'warning' # ignore (default), warning, or error (fails the build) + - [mediaTypes] - [mediaTypes."text/netlify"] - delimiter = "" ++[languages] ++ [languages.en] ++ languageName = "English" ++ weight = 1 ++ ++[security] ++ enableInlineShortcodes = false ++ [security.funcs] ++ getenv = ['^HUGO_', '^REPOSITORY_URL$', '^BRANCH$'] ++ [security.http] ++ methods = ['(?i)GET|POST'] ++ urls = ['.*'] + +[outputFormats] - [outputFormats.REDIR] - mediatype = "text/netlify" - baseName = "_redirects" - isPlainText = true - notAlternative = true - [outputFormats.HEADERS] - mediatype = "text/netlify" - baseName = "_headers" - isPlainText = true - notAlternative = true - - [caches] - [caches.getjson] - dir = ":cacheDir/:project" - maxAge = -1 - [caches.getcsv] - dir = ":cacheDir/:project" - maxAge = -1 - [caches.images] - dir = ":cacheDir/images" - maxAge = "1440h" - [caches.assets] - dir = ":resourceDir/_gen" - maxAge = -1 - [caches.getresource] - dir = ":cacheDir/:project" - maxage = '1h' - - [related] - threshold = 80 - includeNewer = true - toLower = false - [[related.indices]] - name = "keywords" - weight = 60 - [[related.indices]] - # Can be used as a front matter slice to link to other page fragments (headings) using their ID. - # This isn't particular useful in the current docs, but we're planning on getting a auto generated - # reference section with a better ID setup. - # For now, we just use it to give pages with same headings some similarity score. - name = "fragmentrefs" - type = "fragments" - applyFilter = false - weight = 60 - cardinalityThreshold = 50 - - [imaging] - # See https://github.com/disintegration/imaging - # CatmullRom is a sharp bicubic filter which should fit the docs site well with its many screenshots. - # Note that you can also set this per image processing. - resampleFilter = "CatmullRom" - # Default JPEG quality setting. Default is 75. - quality = 75 - anchor = "smart" - - [taxonomies] - category = "categories" - - [[cascade]] - categories = ['commands'] - [cascade._target] - path = '/commands/**' ++ [outputFormats.redir] ++ mediatype = "text/netlify" ++ baseName = "_redirects" ++ isPlainText = true ++ [outputFormats.headers] ++ mediatype = "text/netlify" ++ baseName = "_headers" ++ isPlainText = true ++ notAlternative = true ++ ++[markup] ++ [markup.highlight] ++ style = 'solarized-dark' ++ lineNumbersInTable = true ++ noClasses = false ++ wrapperClass = 'highlight not-prose' ++ ++ [markup.goldmark.renderer] ++ hardWraps = false ++ unsafe = false ++ xhtml = false ++ ++ [markup.goldmark.extensions] ++ definitionList = true ++ footnote = true ++ linkify = true ++ strikethrough = true ++ table = true ++ taskList = true ++ typographer = true ++ ++ [markup.goldmark.extensions.passthrough] ++ enable = true ++ ++ [markup.goldmark.extensions.passthrough.delimiters] ++ block = [['\[', '\]'], ['$$', '$$']] ++ inline = [['\(', '\)']] ++ ++ [markup.goldmark.parser] ++ autoHeadingID = true ++ autoHeadingIDType = "github" ++ ++ [markup.goldmark.parser.attribute] ++ block = true ++ title = true ++ ++[mediaTypes] ++ [mediaTypes."text/netlify"] ++ delimiter = "" ++ ++[module] ++ [module.hugoVersion] ++ min = "0.141.0" ++ [[module.mounts]] ++ source = "assets" ++ target = "assets" ++ [[module.mounts]] ++ lang = 'en' ++ source = 'content/en' ++ target = 'content' ++ [[module.mounts]] ++ source = "hugo_stats.json" ++ target = "assets/notwatching/hugo_stats.json" ++ disableWatch = true ++ ++[build] ++ [build.buildStats] ++ disableIDs = true ++ enable = true ++ [[build.cachebusters]] ++ source = "assets/notwatching/hugo_stats\\.json" ++ target = "css" ++ [[build.cachebusters]] ++ source = "(postcss|tailwind)\\.config\\.js" ++ target = "css" ++ ++[server] ++ [[server.headers]] ++ for = "/*" ++ ++ [server.headers.values] ++ X-Frame-Options = "DENY" ++ X-XSS-Protection = "1; mode=block" ++ X-Content-Type-Options = "nosniff" ++ Referrer-Policy = "no-referrer" ++ ++ [[server.headers]] ++ for = "/**.{css,js}" ++ ++[minify] ++ [minify.tdewolff] ++ [minify.tdewolff.html] ++ keepSpecialComments = true ++ keepWhitespace = false ++ ++######## GLOBAL ITEMS TO BE SHARED WITH THE HUGO SITES ######## ++[menus] ++ [[menus.global]] ++ name = 'News' ++ weight = 1 ++ identifier = 'news' ++ pageRef = '/news/' ++ ++ [[menus.global]] ++ name = 'Docs' ++ weight = 5 ++ identifier = 'docs' ++ url = '/documentation/' ++ ++ [[menus.global]] ++ name = 'Themes' ++ weight = 10 ++ identifier = 'themes' ++ url = 'https://themes.gohugo.io/' ++ ++ [[menus.global]] ++ name = 'Community' ++ weight = 150 ++ identifier = 'community' ++ post = 'external' ++ url = 'https://discourse.gohugo.io/' ++ ++ [[menus.global]] ++ name = 'GitHub' ++ weight = 200 ++ identifier = 'github' ++ post = 'external' ++ url = 'https://github.com/gohugoio/hugo' diff --cc docs/hugo.work index b2ae38c07,000000000..02c0ba91f mode 100644,000000..100644 --- a/docs/hugo.work +++ b/docs/hugo.work @@@ -1,4 -1,0 +1,4 @@@ +go 1.22.0 + +use . - use ../gohugoioTheme ++ diff --cc docs/layouts/404.html index 000000000,000000000..bb92ea160 new file mode 100644 --- /dev/null +++ b/docs/layouts/404.html @@@ -1,0 -1,0 +1,22 @@@ ++{{ define "main" }} ++
++
++

++ Page not found ++ gopher ++

++ ++
++ Go back home ++
++
++
++{{ end }} diff --cc docs/layouts/_default/_markup/render-heading.html index 000000000,000000000..c0e6c63ec new file mode 100644 --- /dev/null +++ b/docs/layouts/_default/_markup/render-heading.html @@@ -1,0 -1,0 +1,10 @@@ ++{{ .Text | safeHTML }} ++ {{- if in (slice 2 3 4 6) .Level }}{{" " -}} ++ ++ ++ ++ ++ ++ ++{{- end -}} ++ diff --cc docs/layouts/_default/_markup/render-link.html index a0ee6b190,000000000..726610258 mode 100644,000000..100644 --- a/docs/layouts/_default/_markup/render-link.html +++ b/docs/layouts/_default/_markup/render-link.html @@@ -1,317 -1,0 +1,317 @@@ +{{- /* Last modified: 2025-01-19T14:44:56-08:00 */}} + +{{- /* +Copyright 2025 Veriphor LLC + +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 + +https://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. +*/}} + +{{- /* +This render hook resolves internal destinations by looking for a matching: + + 1. Content page + 2. Page resource (a file in the current page bundle) + 3. Section resource (a file in the current section) + 4. Global resource (a file in the assets directory) + +It skips the section resource lookup if the current page is a leaf bundle. + +External destinations are not modified. + +You must place global resources in the assets directory. If you have placed +your resources in the static directory, and you are unable or unwilling to move +them, you must mount the static directory to the assets directory by including +both of these entries in your site configuration: + + [[module.mounts]] + source = 'assets' + target = 'assets' + + [[module.mounts]] + source = 'static' + target = 'assets' + +By default, if this render hook is unable to resolve a destination, including a +fragment if present, it passes the destination through without modification. To +emit a warning or error, set the error level in your site configuration: + + [params.render_hooks.link] + errorLevel = 'warning' # ignore (default), warning, or error (fails the build) + +When you set the error level to warning, and you are in a development +environment, you can visually highlight broken internal links: + + [params.render_hooks.link] + errorLevel = 'warning' # ignore (default), warning, or error (fails the build) + highlightBroken = true # true or false (default) + +This will add a "broken" class to anchor elements with invalid src attributes. +Add a rule to your CSS targeting the broken links: + + a.broken { + background: #ff0; + border: 2px solid #f00; + padding: 0.1em 0.2em; + } + +This render hook may be unable to resolve destinations created with the ref and +relref shortcodes. Unless you set the error level to ignore you should not use +either of these shortcodes in conjunction with this render hook. + +@context {string} Destination The link destination. +@context {page} Page A reference to the page containing the link. +@context {string} PlainText The link description as plain text. +@context {string} Text The link description. +@context {string} Title The link title. + +@returns {template.html} +*/}} + +{{- /* Initialize. */}} +{{- $renderHookName := "link" }} + +{{- /* Verify minimum required version. */}} +{{- $minHugoVersion := "0.141.0" }} +{{- if lt hugo.Version $minHugoVersion }} + {{- errorf "The %q render hook requires Hugo v%s or later." $renderHookName $minHugoVersion }} +{{- end }} + +{{- /* Error level when unable to resolve destination: ignore, warning, or error. */}} +{{- $errorLevel := or site.Params.render_hooks.link.errorLevel "ignore" | lower }} + +{{- /* If true, adds "broken" class to broken links. Applicable in development environment when errorLevel is warning. */}} +{{- $highlightBrokenLinks := or site.Params.render_hooks.link.highlightBroken false }} + +{{- /* Validate error level. */}} +{{- if not (in (slice "ignore" "warning" "error") $errorLevel) }} + {{- errorf "The %q render hook is misconfigured. The errorLevel %q is invalid. Please check your site configuration." $renderHookName $errorLevel }} +{{- end }} + +{{- /* Determine content path for warning and error messages. */}} +{{- $contentPath := .Page.String }} + +{{- /* Parse destination. */}} +{{- $u := urls.Parse .Destination }} + +{{- /* Set common message. */}} +{{- $msg := printf "The %q render hook was unable to resolve the destination %q in %s" $renderHookName $u.String $contentPath }} + +{{- /* Set attributes for anchor element. */}} +{{- $attrs := dict "href" $u.String }} +{{- if eq $u.String "g" }} + {{- /* Destination is a glossary term. */}} + {{- $ctx := dict + "contentPath" $contentPath + "errorLevel" $errorLevel + "renderHookName" $renderHookName + "text" .Text + }} + {{- $attrs = partial "inline/h-rh-l/get-glossary-link-attributes.html" $ctx }} +{{- else if $u.IsAbs }} + {{- /* Destination is a remote resource. */}} + {{- $attrs = merge $attrs (dict "rel" "external") }} +{{- else }} + {{- with $u.Path }} + {{- with $p := or ($.PageInner.GetPage .) ($.PageInner.GetPage (strings.TrimRight "/" .)) }} + {{- /* Destination is a page. */}} + {{- $href := .RelPermalink }} + {{- with $u.RawQuery }} + {{- $href = printf "%s?%s" $href . }} + {{- end }} + {{- with $u.Fragment }} + {{- $ctx := dict + "contentPath" $contentPath + "errorLevel" $errorLevel + "page" $p + "parsedURL" $u + "renderHookName" $renderHookName + }} + {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }} + {{- $href = printf "%s#%s" $href . }} + {{- end }} + {{- $attrs = dict "href" $href }} + {{- else with $.PageInner.Resources.Get $u.Path }} + {{- /* Destination is a page resource; drop query and fragment. */}} + {{- $attrs = dict "href" .RelPermalink }} + {{- else with (and (ne $.Page.BundleType "leaf") ($.Page.CurrentSection.Resources.Get $u.Path)) }} + {{- /* Destination is a section resource, and current page is not a leaf bundle. */}} + {{- $attrs = dict "href" .RelPermalink }} + {{- else with resources.Get $u.Path }} + {{- /* Destination is a global resource; drop query and fragment. */}} + {{- $attrs = dict "href" .RelPermalink }} + {{- else }} + {{- if eq $errorLevel "warning" }} + {{- warnf $msg }} + {{- if and $highlightBrokenLinks hugo.IsDevelopment }} + {{- $attrs = merge $attrs (dict "class" "broken") }} + {{- end }} + {{- else if eq $errorLevel "error" }} + {{- errorf $msg }} + {{- end }} + {{- end }} + {{- else }} + {{- with $u.Fragment }} + {{- /* Destination is on the same page; prepend relative permalink. */}} + {{- $ctx := dict + "contentPath" $contentPath + "errorLevel" $errorLevel + "page" $.Page + "parsedURL" $u + "renderHookName" $renderHookName + }} + {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }} + {{- $attrs = dict "href" (printf "%s#%s" $.Page.RelPermalink .) }} + {{- else }} + {{- if eq $errorLevel "warning" }} + {{- warnf $msg }} + {{- if and $highlightBrokenLinks hugo.IsDevelopment }} + {{- $attrs = merge $attrs (dict "class" "broken") }} + {{- end }} + {{- else if eq $errorLevel "error" }} + {{- errorf $msg }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- /* Render anchor element. */ -}} - {{ .Text }} + +{{- define "partials/inline/h-rh-l/validate-fragment.html" }} + {{- /* + Validates the fragment portion of a link destination. + + @context {string} contentPath The page containing the link. + @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error. + @context {page} page The page corresponding to the link destination + @context {struct} parsedURL The link destination parsed by urls.Parse. + @context {string} renderHookName The name of the render hook. + */}} + + {{- /* Initialize. */}} + {{- $contentPath := .contentPath }} + {{- $errorLevel := .errorLevel }} + {{- $p := .page }} + {{- $u := .parsedURL }} + {{- $renderHookName := .renderHookName }} + + {{- /* Validate. */}} + {{- with $u.Fragment }} + {{- if $p.Fragments.Identifiers.Contains . }} + {{- if gt ($p.Fragments.Identifiers.Count .) 1 }} + {{- $msg := printf "The %q render hook detected duplicate heading IDs %q in %s" $renderHookName . $contentPath }} + {{- if eq $errorLevel "warning" }} + {{- warnf $msg }} + {{- else if eq $errorLevel "error" }} + {{- errorf $msg }} + {{- end }} + {{- end }} + {{- else }} + {{- /* Determine target path for warning and error message. */}} + {{- $targetPath := "" }} + {{- with $p.File }} + {{- $targetPath = .Path }} + {{- else }} + {{- $targetPath = .Path }} + {{- end }} + {{- /* Set common message. */}} + {{- $msg := printf "The %q render hook was unable to find heading ID %q in %s. See %s" $renderHookName . $targetPath $contentPath }} + {{- if eq $targetPath $contentPath }} + {{- $msg = printf "The %q render hook was unable to find heading ID %q in %s" $renderHookName . $targetPath }} + {{- end }} + {{- /* Throw warning or error. */}} + {{- if eq $errorLevel "warning" }} + {{- warnf $msg }} + {{- else if eq $errorLevel "error" }} + {{- errorf $msg }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "partials/inline/h-rh-l/get-glossary-link-attributes.html" }} + {{- /* + Returns the anchor element attributes for a link to the given glossary term. + + It first checks for the existence of a glossary page for the given term. If + no page is found, it then checks for a glossary page for the singular form of + the term. If neither page exists it throws a warning or error dependent on + the errorLevel setting + + The returned href attribute does not point to the glossary term page. + Instead, via its fragment, it points to an entry on the glossary page. + + @context {string} contentPath The page containing the link. + @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error. + @context {string} renderHookName The name of the render hook. + @context {string} text The link text. + */}} + + {{- /* Get context.. */}} + {{- $contentPath := .contentPath }} + {{- $errorLevel := .errorLevel }} + {{- $renderHookName := .renderHookName }} + {{- $text := .text | transform.Plainify | strings.ToLower }} + + {{- /* Initialize. */}} - {{- $glossaryPath := "/getting-started/glossary" }} ++ {{- $glossaryPath := "/quick-reference/glossary" }} + {{- $termGiven := $text }} + {{- $termActual := "" }} + {{- $termSingular := inflect.Singularize $termGiven }} + + {{- /* Verify that the glossary page exists. */}} + {{- $glossaryPage := site.GetPage $glossaryPath }} + {{- if not $glossaryPage }} + {{- errorf "The %q render hook was unable to find %s: see %s" $renderHookName $glossaryPath $contentPath }} + {{- end }} + - {{- /* Theres a better way to handle this, but it works for now. */}} ++ {{- /* There's a better way to handle this, but it works for now. */}} + {{- $cheating := dict + "chaining" "chain" + "localize" "localization" + "localized" "localization" + "paginating" "paginate" + "walking" "walk" + }} + + {{- /* Verify that a glossary term page exists for the given term. */}} + {{- if site.GetPage (urls.JoinPath $glossaryPath ($termGiven | urlize)) }} + {{- $termActual = $termGiven }} + {{- else if site.GetPage (urls.JoinPath $glossaryPath ($termSingular | urlize)) }} + {{- $termActual = $termSingular }} + {{- else }} + {{- $termToTest := index $cheating $termGiven }} + {{- if site.GetPage (urls.JoinPath $glossaryPath ($termToTest | urlize)) }} + {{- $termActual = $termToTest }} + {{- end }} + {{- end }} + + {{- if not $termActual }} + {{- errorf "The %q render hook was unable to find a glossary page for either the singular or plural form of the term %q: see %s" $renderHookName $termGiven $contentPath }} + {{- end }} + + {{- /* Create the href attribute. */}} + {{- $href := ""}} + {{- if $termActual }} + {{- $href = fmt.Printf "%s#%s" $glossaryPage.RelPermalink (anchorize $termActual) }} + {{- end }} + + {{- return (dict "href" $href) }} +{{- end -}} diff --cc docs/layouts/_default/baseof.html index 000000000,000000000..f6e281455 new file mode 100644 --- /dev/null +++ b/docs/layouts/_default/baseof.html @@@ -1,0 -1,0 +1,67 @@@ ++ ++ ++ ++ ++ ++ {{ .Title }} ++ ++ ++ ++ {{ partial "layouts/head/head-js.html" . }} ++ {{ with (templates.Defer (dict "key" "global")) }} ++ {{ $t := debug.Timer "tailwindcss" }} ++ {{ with resources.Get "css/styles.css" }} ++ {{ $opts := dict ++ "inlineImports" true ++ "minify" (not hugo.IsDevelopment) ++ }} ++ {{ with . | css.TailwindCSS $opts }} ++ {{ partial "helpers/linkcss.html" (dict "r" .) }} ++ {{ end }} ++ {{ end }} ++ {{ $t.Stop }} ++ {{ end }} ++ {{ partial "layouts/head/head.html" . }} ++ ++ ++ {{ partial "layouts/hooks/body-start.html" . }} ++ {{/* Layout. */}} ++ {{ block "header" . }} ++ {{ partial "layouts/header/header.html" . }} ++ {{ end }} ++ {{ block "hero" . }} ++ {{ end }} ++
++
++ {{ block "main" . }}{{ end }} ++
++ {{ block "rightsidebar" . }} ++ ++ {{ end }} ++
++ {{/* Common icons. */}} ++ {{ partial "layouts/icons.html" . }} ++ {{/* Footer. */}} ++ {{ block "footer" . }} ++ {{ partial "layouts/footer.html" . }} ++ {{ end }} ++ {{ partial "layouts/hooks/body-end.html" . }} ++ ++ diff --cc docs/layouts/_default/list.html index 000000000,000000000..76513788f new file mode 100644 --- /dev/null +++ b/docs/layouts/_default/list.html @@@ -1,0 -1,0 +1,67 @@@ ++{{ define "main" }} ++ {{ $pages := "" }} ++ {{ $showDate := false }} ++ {{ if .IsPage }} ++ {{/* We currently have a slightly odd content structure with no top level /docs section. */}} ++ {{ $pages = .CurrentSection.Pages }} ++ {{ else }} ++ {{ if eq .Section "news" }} ++ {{ $pages = partial "news/get-news-items.html" . }} ++ {{ $showDate = true }} ++ {{ else }} ++ {{ $pages = .Pages }} ++ {{ end }} ++ {{ end }} ++ ++ ++
++ {{ partial "layouts/docsheader.html" . }} ++ ++
++{{ end }} ++ ++{{ define "rightsidebar" }} ++ {{ printf "%c" '\u00A0' }} ++{{ end }} diff --cc docs/layouts/_default/single.html index 000000000,000000000..b6587633b new file mode 100644 --- /dev/null +++ b/docs/layouts/_default/single.html @@@ -1,0 -1,0 +1,71 @@@ ++{{ define "main" }} ++ {{ $ttop := debug.Timer "single" }} ++
++ {{ partial "layouts/docsheader.html" . }} ++
++ {{ with .Params.description }} ++
++ {{ . | markdownify }} ++
++ {{ end }} ++ ++ {{ $t := debug.Timer "single.categories" }} ++ {{ $categories := .GetTerms "categories" }} ++ {{ with $categories }} ++
++ {{ range . }} ++ {{ $text := .LinkTitle }} ++ {{ $class := "" }} ++ {{ range (slice true false ) }} ++ {{ $color := partial "helpers/funcs/color-from-string.html" (dict "text" $text "dark" . "--single" "green" ) }} ++ ++ {{ $prefix := "" }} ++ {{ if . }} ++ {{ $prefix = "dark:" }} ++ {{ end }} ++ {{ $class = printf "%sbg-%s-%d %stext-%s-%d border %sborder-%s-%d" ++ $prefix $color.color $color.shade1 ++ $prefix $color.color $color.shade2 ++ $prefix $color.color $color.shade3 ++ }} ++ {{ end }} ++ ++ ++ ++ {{ .LinkTitle }} ++ ++ {{ end }} ++
++ {{ end }} ++ {{ $t.Stop }} ++ ++ {{ if .Params.action.signatures }} ++
++ {{- partial "docs/functions-signatures.html" . -}} ++ {{- partial "docs/functions-return-type.html" . -}} ++ {{- partial "docs/functions-aliases.html" . -}} ++
++ {{ end }} ++ {{ $t := debug.Timer "single.content" }} ++ {{ .Content }} ++ {{ $t.Stop }} ++ {{ $t := debug.Timer "single.page-edit" }} ++ {{ partial "layouts/page-edit.html" . }} ++ {{ $t.Stop }} ++
++
++ {{ $ttop.Stop }} ++{{ end }} ++ ++{{ define "rightsidebar_content" }} ++ {{/* in-this-section.html depends on these being reneredc first. */}} ++ {{ $related := partial "layouts/related.html" . }} ++ {{ $toc := partial "layouts/toc.html" . }} ++ {{ if not .Params.hide_in_this_section }} ++ {{ partial "layouts/in-this-section.html" . }} ++ {{ end }} ++ {{ $related }} ++ {{ $toc }} ++{{ end }} diff --cc docs/layouts/index.headers index 000000000,000000000..1216e42d4 new file mode 100644 --- /dev/null +++ b/docs/layouts/index.headers @@@ -1,0 -1,0 +1,5 @@@ ++/* ++ X-Frame-Options: DENY ++ X-XSS-Protection: 1; mode=block ++ X-Content-Type-Options: nosniff ++ Referrer-Policy: origin-when-cross-origin diff --cc docs/layouts/index.html index 000000000,000000000..50dc2fbf3 new file mode 100644 --- /dev/null +++ b/docs/layouts/index.html @@@ -1,0 -1,0 +1,52 @@@ ++{{ define "main" }} ++
++ {{ partial "layouts/home/opensource.html" . }} ++
++ {{ partial "layouts/home/sponsors.html" (dict "ctx" . "gtag" "home" ) }} ++
++ {{ partial "layouts/home/features.html" . }} ++
++{{ end }} ++ ++{{ define "hero" }} ++
++
++
++ Hugo Logo ++

++ The world’s fastest framework for building websites ++

++
++ Hugo is one of the most popular open-source static site generators. ++ With its amazing speed and flexibility, Hugo makes building websites ++ fun again. ++
++
++ {{ with site.GetPage "/getting-started" }} ++ {{ .LinkTitle }} ++ {{ end }} ++
++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" true) }} ++
++
++
++
++
++{{ end }} ++ ++{{ define "rightsidebar" }} ++ {{ printf "%c" '\u00A0' }} ++{{ end }} ++ ++{{ define "leftsidebar" }} ++ {{ printf "%c" '\u00A0' }} ++{{ end }} diff --cc docs/layouts/index.redir index 000000000,000000000..2dfd2bc0f new file mode 100644 --- /dev/null +++ b/docs/layouts/index.redir @@@ -1,0 -1,0 +1,6 @@@ ++# Netlify redirects. See https://www.netlify.com/docs/redirects/ ++{{ range $p := .Site.Pages -}} ++{{ range .Aliases }} ++{{ . | printf "%-35s" }} {{ $p.RelPermalink -}} ++{{ end -}} ++{{- end -}} diff --cc docs/layouts/index.rss.xml index 000000000,000000000..460c4d30e new file mode 100644 --- /dev/null +++ b/docs/layouts/index.rss.xml @@@ -1,0 -1,0 +1,68 @@@ ++{{- printf "" | safeHTML }} ++ ++ ++ Hugo News ++ Recent news about Hugo, a static site generator written in Go, optimized for speed and designed for flexibility. ++ {{ .Permalink }} ++ Hugo {{ hugo.Version }} ++ {{ or site.Language.LanguageCode site.Language.Lang }} ++ {{- with site.Copyright }} ++ {{ . }} ++ {{- end }} ++ {{- with .OutputFormats.Get "rss" }} ++ {{ printf "" .Permalink .MediaType | safeHTML }} ++ {{- end }} ++ ++ {{- $news_items := slice }} ++ ++ {{- /* Get releases from GitHub. */}} ++ {{- $u := "https://api.github.com/repos/gohugoio/hugo/releases" }} ++ {{- $releases := partial "helpers/funcs/get-remote-data.html" $u }} ++ {{- $releases = where $releases "draft" false }} ++ {{- $releases = where $releases "prerelease" false }} ++ {{- range $releases | first 20 }} ++ {{- $summary := printf ++ "Hugo %s was released on %s. See [release notes](%s) for details." ++ .tag_name ++ (.published_at | time.AsTime | time.Format "2 Jan 2006") ++ .html_url ++ }} ++ {{- $ctx := dict ++ "PublishDate" (.published_at | time.AsTime) ++ "Title" (printf "Release %s" .name) ++ "Permalink" .html_url ++ "Section" "news" ++ "Summary" ($summary | $.Page.RenderString) ++ }} ++ {{- $news_items = $news_items | append $ctx }} ++ {{- end }} ++ ++ {{- /* Get content pages from news section. */}} ++ {{- range where site.RegularPages "Section" "news" }} ++ {{- $ctx := dict ++ "PublishDate" .PublishDate ++ "Title" .Title ++ "RelPermalink" .RelPermalink ++ "Section" "news" ++ "Summary" .Summary ++ "Params" (dict "description" .Description) ++ }} ++ {{- $news_items = $news_items | append $ctx }} ++ {{- end }} ++ {{- /* Sort, limit, and render lastBuildDate. */}} ++ {{- $limit := cond (gt site.Config.Services.RSS.Limit 1) site.Config.Services.RSS.Limit 999 }} ++ {{- $news_items = sort $news_items "PublishDate" "desc" | first $limit }} ++ {{ (index $news_items 0).PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }} ++ ++ {{- /* Render items. */}} ++ {{- range $news_items }} ++ ++ {{ .Title }} ++ {{ .Permalink }} ++ {{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }} ++ {{ .Permalink }} ++ {{ .Summary | transform.XMLEscape | safeHTML }} ++ ++ {{- end }} ++ ++ diff --cc docs/layouts/partials/docs/functions-aliases.html index 000000000,000000000..dc562307a new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/docs/functions-aliases.html @@@ -1,0 -1,0 +1,12 @@@ ++{{- with .Params.action.aliases }} ++ {{- $label := "Alias" }} ++ {{- if gt (len .) 1 }} ++ {{- $label = "Aliases" }} ++ {{- end }} ++

{{ $label }}

++ {{- range . }} ++
++ {{- . -}} ++
++ {{- end }} ++{{- end -}} diff --cc docs/layouts/partials/docs/functions-return-type.html index 000000000,000000000..13c8c96f4 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/docs/functions-return-type.html @@@ -1,0 -1,0 +1,6 @@@ ++{{- with .Params.action.returnType }} ++

Returns

++
++ {{- . -}} ++
++{{- end -}} diff --cc docs/layouts/partials/docs/functions-signatures.html index 000000000,000000000..35d950265 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/docs/functions-signatures.html @@@ -1,0 -1,0 +1,12 @@@ ++{{- with .Params.action.signatures }} ++

Syntax

++ {{- range . }} ++ {{- $signature := . }} ++ {{- if $.Params.function.returnType }} ++ {{- $signature = printf "%s ⟼ %s" . $.Params.function.returnType }} ++ {{- end }} ++
++ {{- $signature -}} ++
++ {{- end }} ++{{- end -}} diff --cc docs/layouts/partials/helpers/funcs/color-from-string.html index 000000000,000000000..cd599530b new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/helpers/funcs/color-from-string.html @@@ -1,0 -1,0 +1,25 @@@ ++{{ $colors := slice "slate" "green" "cyan" "blue" }} ++{{ with .single }} ++ {{ $colors = slice . }} ++{{ end }} ++ ++{{ $shades := slice 300 400 500 }} ++{{ if not .dark }} ++ {{ $shades = slice 700 800 }} ++{{ end }} ++{{ $hash := (hash.FNV32a .text) }} ++{{ $i := mod $hash (len $colors) }} ++{{ $j := mod $hash (len $shades) }} ++{{ $color := index $colors $i }} ++{{ $shade1 := index $shades $j }} ++{{ $shade2 := 0 }} ++{{ $shade3 := 0 }} ++{{ if gt $shade1 500 }} ++ {{ $shade2 = math.Min (sub $shade1 500) 100 | int }} ++ {{ $shade3 = sub $shade1 100 }} ++{{ else }} ++ {{ $shade2 = math.Max (add $shade1 500) 700 | int }} ++ {{ $shade3 = add $shade1 200 }} ++{{ end }} ++{{ $res := dict "color" $color "shade1" $shade1 "shade2" $shade2 "shade3" $shade3 }} ++{{ return $res }} diff --cc docs/layouts/partials/helpers/funcs/get-github-info.html index 000000000,000000000..7e2dc89fa new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/helpers/funcs/get-github-info.html @@@ -1,0 -1,0 +1,28 @@@ ++{{ $url := "https://api.github.com/repos/gohugoio/hugo" }} ++{{ $cacheKey := print $url (now.Format "2006-01-02") }} ++{{ $headers := dict }} ++{{ with os.Getenv "HUGO_GH_TOKEN" }} ++ {{ $headers = dict "Authorization" (printf "Bearer %s" .) }} ++{{ end }} ++{{ $opts := dict "headers" $headers "key" $cacheKey }} ++{{ $githubRepoInfo := dict }} ++{{ with try (resources.GetRemote $url $opts) }} ++ {{ with .Err }} ++ {{ warnf "Failed to get GitHub repo info: %s" . }} ++ {{ else with (.Value | transform.Unmarshal) }} ++ {{ $githubRepoInfo = dict ++ "html_url" .html_url ++ "stargazers_url" .stargazers_url ++ "watchers_count" .watchers_count ++ "stargazers_count" .stargazers_count ++ "forks_count" .forks_count ++ "contributors_url" .contributors_url ++ "releases_url" .releases_url ++ "forks_count" .forks_count ++ }} ++ {{ else }} ++ {{ errorf "Unable to get remote resource %q" $url }} ++ {{ end }} ++{{ end }} ++ ++{{ return $githubRepoInfo }} diff --cc docs/layouts/partials/helpers/funcs/get-remote-data.html index 000000000,000000000..78b2ba06e new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/helpers/funcs/get-remote-data.html @@@ -1,0 -1,0 +1,23 @@@ ++{{/* ++Parses the serialized data from the given URL and returns a map or an array. ++ ++Supports CSV, JSON, TOML, YAML, and XML. ++ ++@param {string} . The URL from which to retrieve the serialized data. ++@returns {any} ++ ++@example {{ partial "get-remote-data.html" "https://example.org/foo.json" }} ++*/}} ++ ++{{ $url := . }} ++{{ $data := dict }} ++{{ with try (resources.GetRemote $url) }} ++ {{ with .Err }} ++ {{ errorf "%s" . }} ++ {{ else with .Value }} ++ {{ $data = .Content | transform.Unmarshal }} ++ {{ else }} ++ {{ errorf "Unable to get remote resource %q" $url }} ++ {{ end }} ++{{ end }} ++{{ return $data }} diff --cc docs/layouts/partials/helpers/gtag.html index 000000000,000000000..59bf36ba2 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/helpers/gtag.html @@@ -1,0 -1,0 +1,27 @@@ ++{{ with site.Config.Services.GoogleAnalytics.ID }} ++ ++ ++{{ end }} diff --cc docs/layouts/partials/helpers/linkcss.html index 000000000,000000000..c12406757 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/helpers/linkcss.html @@@ -1,0 -1,0 +1,28 @@@ ++{{ $r := .r }} ++{{ $attr := .attributes | default dict }} ++ ++{{ if hugo.IsDevelopment }} ++ ++{{ else }} ++ {{ with $r | minify | fingerprint }} ++ ++ {{ end }} ++{{ end }} ++ ++{{ define "render-attributes" }} ++ {{- range $k, $v := . -}} ++ {{- if $v -}} ++ {{- printf ` %s=%q` $k $v | safeHTMLAttr -}} ++ {{- else -}} ++ {{- printf ` %s` $k | safeHTMLAttr -}} ++ {{- end -}} ++ {{- end -}} ++{{ end }} diff --cc docs/layouts/partials/helpers/linkjs.html index 000000000,000000000..00129ad38 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/helpers/linkjs.html @@@ -1,0 -1,0 +1,15 @@@ ++{{ $r := .r }} ++{{ $attr := .attributes | default dict }} ++{{ if hugo.IsDevelopment }} ++ ++{{ else }} ++ {{ with $r | fingerprint }} ++ ++ {{ end }} ++{{ end }} diff --cc docs/layouts/partials/helpers/picture.html index 000000000,000000000..7f30f1437 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/helpers/picture.html @@@ -1,0 -1,0 +1,25 @@@ ++{{ $image := .image }} ++{{ $width := .width | default 1000 }} ++{{ $width1x := div $width 2 }} ++{{ $imageWebp := $image.Resize (printf "%dx webp" $width) }} ++{{ $image1x := $image.Resize (printf "%dx" $width1x) }} ++{{ $image1xWebp := $image.Resize (printf "%dx webp" $width1x) }} ++{{ $class := .class | default "h-64 tablet:h-96 lg:h-full w-full object-cover lg:absolute" }} ++ ++ ++ ++ ++ ++ ++ diff --cc docs/layouts/partials/layouts/blocks/alert.html index 000000000,000000000..705ce0e7e new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/blocks/alert.html @@@ -1,0 -1,0 +1,27 @@@ ++{{ $title := .title | default "" }} ++{{ $color := .color | default "yellow" }} ++{{ $icon := .icon | default "exclamation" }} ++{{ $text := .text | default "" }} ++{{ $class := .class | default "mt-6 mb-8" }} ++
++
++
++ ++ ++ ++
++
++ {{ with $title }} ++

++ {{ . }} ++

++ {{ end }} ++
++

++ {{ $text }} ++

++
++
++
++
diff --cc docs/layouts/partials/layouts/blocks/modal.html index 000000000,000000000..7d825c06e new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/blocks/modal.html @@@ -1,0 -1,0 +1,30 @@@ ++
++
++ {{ .modal_button }} ++
++ ++
diff --cc docs/layouts/partials/layouts/breadcrumbs.html index 000000000,000000000..d0628c7ee new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/breadcrumbs.html @@@ -1,0 -1,0 +1,44 @@@ ++{{ $documentation := site.GetPage "/documentation" }} ++ ++ ++ ++ ++{{ define "breadcrumbs-arrow" }} ++ ++ ++ ++{{ end }} diff --cc docs/layouts/partials/layouts/docsheader.html index 000000000,000000000..7e8e950f3 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/docsheader.html @@@ -1,0 -1,0 +1,9 @@@ ++
++ {{ partial "layouts/breadcrumbs.html" . }} ++ {{ if and .IsPage (not (eq .Layout "list")) }} ++

++ {{ .Title }} ++

++ {{ end }} ++
diff --cc docs/layouts/partials/layouts/explorer.html index 000000000,000000000..bb6f8e96a new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/explorer.html @@@ -1,0 -1,0 +1,47 @@@ ++{{/* This is currently not in use, but kept in case I change my mind. */}} ++ ++ ++{{ define "docs-explorer-section" }} ++ {{ $p := .p }} ++ {{ $level := .level }} ++ {{ $pleft := $level }} ++ {{ if gt $level 0 }} ++ {{ $pleft = add $level 1 }} ++ {{ end }} ++ {{ $pl := printf "pl-%d" $pleft }} ++ {{ $pages := $p.Sections }} ++ ++ {{ range $pages }} ++ {{ $hasChildren := gt (len .Pages) 0 }} ++ {{ $class := cond (eq $level 0) "text-primary hover:text-primary/70" "text-gray-900 dark:text-gray-400 hover:dark:text-gray-300" }} ++
  • ++ ++ {{ .LinkTitle }} ++ ++ {{ if $hasChildren }} ++
      ++ {{ template "docs-explorer-section" (dict "p" . "level" (add $level 1)) }} ++
    ++ {{ end }} ++
  • ++ {{ end }} ++ ++{{ end }} diff --cc docs/layouts/partials/layouts/footer.html index 000000000,000000000..99a856f7e new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/footer.html @@@ -1,0 -1,0 +1,72 @@@ ++
    ++
    ++
    ++ {{/* Column 1 */}} ++
    ++
    ++ By the ++ Hugo Authors
    ++
    ++ ++ Hugo Logo ++ ++ ++
    ++ ++ {{/* Sponsors */}} ++
    ++ {{ partial "layouts/home/sponsors.html" (dict ++ "ctx" . ++ "gtag" "footer" ++ ++ ) ++ }} ++
    ++
    ++
    ++

    ++ The Hugo logos are copyright © Steve Francia 2013–{{ now.Year }}. The ++ Hugo Gopher is based on an original work by Renée French. ++

    ++
    ++
    ++
    diff --cc docs/layouts/partials/layouts/head/head-js.html index 000000000,000000000..d83efcd0f new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/head/head-js.html @@@ -1,0 -1,0 +1,11 @@@ ++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }} ++{{ $opts := dict "minify" true }} ++{{ with resources.Get "js/head-early.js" | js.Build $opts }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "async" "")) }} ++{{ end }} ++{{ with resources.Get "js/main.js" | js.Build $opts }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }} ++{{ end }} ++{{ with resources.Get "js/turbo.js" | js.Build $opts }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }} ++{{ end }} diff --cc docs/layouts/partials/layouts/head/head.html index 000000000,000000000..391e80dca new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/head/head.html @@@ -1,0 -1,0 +1,52 @@@ ++ ++ ++ ++ ++{{ hugo.Generator }} ++ ++{{ if hugo.IsProduction }} ++ ++{{ else }} ++ ++{{ end }} ++ ++ ++ {{ with .Title }}{{ . }} |{{ end }} ++ {{ .Site.Title }} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{{ range .AlternativeOutputFormats -}} ++ ++{{ end -}} ++ ++ ++ ++ ++ ++ ++{{ partial "opengraph/opengraph.html" . }} ++{{- template "_internal/schema.html" . -}} ++{{- template "_internal/twitter_cards.html" . -}} ++ ++{{ if hugo.IsProduction }} ++ {{ partial "helpers/gtag.html" . }} ++{{ end }} diff --cc docs/layouts/partials/layouts/header/githubstars.html index 000000000,000000000..75db5682a new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/header/githubstars.html @@@ -1,0 -1,0 +1,16 @@@ ++{{ with partialCached "helpers/funcs/get-github-info.html" . "-" }} ++ ++ ++ ++ ++ ++ ++ ++ {{ printf "%0.1fk" (div .stargazers_count 1000) }} ++ ++ ++{{ end }} diff --cc docs/layouts/partials/layouts/header/header.html index 000000000,000000000..079c40bae new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/header/header.html @@@ -1,0 -1,0 +1,44 @@@ ++
    ++
    ++ {{ with site.Home }} ++ HUGO ++ {{ end }} ++
    ++
    ++ {{ range .Site.Menus.global }} ++ {{ .Name }} ++ {{ end }} ++ ++
    ++ ++
    ++ {{/* Search. */}} ++ {{ partial "layouts/search/input.html" . }} ++
    ++
    ++ {{/* QR code. */}} ++ {{ partial "layouts/header/qr.html" . }} ++ {{/* Theme selector. */}} ++ {{ partial "layouts/header/theme.html" . }} ++ ++ {{/* Social. */}} ++ ++
    ++
    diff --cc docs/layouts/partials/layouts/header/qr.html index 000000000,000000000..3d3f62e17 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/header/qr.html @@@ -1,0 -1,0 +1,25 @@@ ++{{ $t := debug.Timer "qr" }} ++{{ $qr := partial "partials/_inline/qr" (dict ++ "page" $ ++ "img_class" "w-10 bg-white view-transition-qr" ) ++}} ++{{ $qrBig := partial "partials/_inline/qr" (dict "page" $ "img_class" "w-64 p-4") }} ++{{ $t.Stop }} ++ ++ ++{{ define "partials/_inline/qr" }} ++ {{ $img_class := .img_class | default "w-10" }} ++ {{ with images.QR $.page.Permalink (dict "targetDir" "images/qr") }} ++ ++ QR code linking to {{ $.page.Permalink }} ++ {{ end }} ++{{ end }} diff --cc docs/layouts/partials/layouts/header/theme.html index 000000000,000000000..e0b356d1d new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/header/theme.html @@@ -1,0 -1,0 +1,35 @@@ ++
    ++ ++
    diff --cc docs/layouts/partials/layouts/home/features.html index 000000000,000000000..527c98cb1 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/home/features.html @@@ -1,0 -1,0 +1,56 @@@ ++{{/* icons source: https://heroicons.com/ */}} ++{{ $dataTOML := ` ++ [[features]] ++ heading = "Optimized for speed" ++ copy = "Written in Go, optimized for speed and designed for flexibility. With its advanced templating system and fast asset pipelines, Hugo renders a large site in seconds, often less." ++ icon = """ ++ ++ ++ """ ++ [[features]] ++ heading = "Flexible framework" ++ copy = "With its multilingual support, and powerful taxonomy system, Hugo is widely used to create documentation sites, landing pages, corporate, government, nonprofit, education, news, event, and project sites." ++ icon = """ ++ ++ ++ """ ++ [[features]] ++ heading = "Fast assets pipeline" ++ copy = "Image processing (convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data), JavaScript bundling (tree shake, code splitting), Sass processing, great TailwindCSS support." ++ icon = """ ++ ++ ++ """ ++ [[features]] ++ heading = "Embedded web server" ++ copy = "Use Hugo's embedded web server during development to instantly see changes to content, structure, behavior, and presentation. " ++ icon = """ ++ ++ ++ """ ++ ` ++}} ++{{ $data := $dataTOML | transform.Unmarshal }} ++
    ++
    ++
    ++ {{ range $data.features }} ++
    ++
    ++
    ++ {{ .icon | safeHTML }} ++
    ++ {{ .heading }} ++
    ++
    ++ {{ .copy }} ++
    ++
    ++ {{ end }} ++ ++
    ++
    ++
    diff --cc docs/layouts/partials/layouts/home/opensource.html index 000000000,000000000..b64bdd22b new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/home/opensource.html @@@ -1,0 -1,0 +1,110 @@@ ++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }} ++
    ++
    ++
    ++
    ++

    ++ Open source ++

    ++

    ++ Hugo is open source and free to use. It is distributed under the ++ Apache 2.0 License. ++

    ++
    ++
    ++
    ++ ++ ++ ++ Popular. ++
    ++
    ++ As of writing this, Hugo has ++ {{ $githubInfo.stargazers_count }} ++ stars on GitHub. Join the crowd and hit the ++ Star button. ++
    ++
    ++
    ++
    ++ ++ ++ ++ Active. ++
    ++
    ++ Hugo has a large and active community. If you have questions or ++ need help, you can ask in the ++ Hugo forums. ++
    ++
    ++
    ++
    ++ ++ ++ ++ Frequent releases. ++
    ++
    ++ Hugo has a fast ++ release ++ cycle. The project is actively maintained and new features are ++ added regularly. ++
    ++
    ++
    ++
    ++
    ++ {{ partial "helpers/picture.html" (dict ++ "image" (resources.Get "images/hugo-github-screenshot.png") ++ "alt" "Hugo GitHub Repository" ++ "width" 640 ++ "class" "w-full max-w-[38rem] ring-1 shadow-xl dark:shadow-gray-500 ring-gray-400/10") ++ }} ++
    ++
    diff --cc docs/layouts/partials/layouts/home/sponsors.html index 000000000,000000000..1f92e1174 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/home/sponsors.html @@@ -1,0 -1,0 +1,43 @@@ ++{{ $gtag := .gtag | default "unknown" }} ++{{ $gtag := .gtag | default "unknown" }} ++{{ $isFooter := (eq $gtag "footer") }} ++{{ $utmSource := cond $isFooter "hugofooter" "hugohome" }} ++{{ $containerClass := .containerClass | default "mx-auto max-w-7xl px-6 lg:px-8" }} ++{{/* TODO1 prod: onclick="trackOutboundLink({{ printf "'%s', '%s'" $gtagID $url | safeJS }});" ++*/}} ++{{ with .ctx.Site.Data.sponsors }} ++
    ++

    Hugo Sponsors

    ++
    ++ {{ range .banners }} ++
    ++ {{ $query_params := .query_params | default "" }} ++ {{ $url := .link }} ++ {{ if not .no_query_params }} ++ {{ $url = printf "%s?%s%s" .link $query_params (querify "utm_source" (.utm_source | default $utmSource ) "utm_medium" (.utm_medium | default "banner") "utm_campaign" (.utm_campaign | default "hugosponsor") "utm_content" (.utm_content | default "gohugoio")) | safeURL }} ++ {{ end }} ++ {{ $logo := resources.Get .logo }} ++ {{ $gtagID := printf "Sponsor %s %s" .name $gtag | title }} ++ ++ ++ ++
    ++ {{ end }} ++
    ++
    ++{{ end }} diff --cc docs/layouts/partials/layouts/hooks/body-end.html index 000000000,000000000..ba4a81300 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/hooks/body-end.html @@@ -1,0 -1,0 +1,1 @@@ ++{{/* Empty for now */}} diff --cc docs/layouts/partials/layouts/hooks/body-start.html index 000000000,000000000..3430bd846 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/hooks/body-start.html @@@ -1,0 -1,0 +1,3 @@@ ++{{ with resources.Get "js/body-start.js" | js.Build (dict "minify" true) }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "" "")) }} ++{{ end }} diff --cc docs/layouts/partials/layouts/icons.html index 000000000,000000000..c7194bc03 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/icons.html @@@ -1,0 -1,0 +1,53 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --cc docs/layouts/partials/layouts/in-this-section.html index 000000000,000000000..8be8cff8b new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/in-this-section.html @@@ -1,0 -1,0 +1,32 @@@ ++{{- with .CurrentSection.RegularPages }} ++ {{ $hasTocOrRelated := or ($.Store.Get "hasToc") ($.Store.Get "hasRelated") }} ++
    ++

    ++ In this section ++

    ++ ++ ++
    ++{{- end }} diff --cc docs/layouts/partials/layouts/page-edit.html index 000000000,000000000..b6f76a560 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/page-edit.html @@@ -1,0 -1,0 +1,24 @@@ ++
    ++
    ++ ++
    ++ Last updated: ++ {{ .Lastmod.Format "January 2, 2006" }}{{ with .GitInfo }} ++ : ++ {{ .Subject }} ({{ .AbbreviatedHash }}) ++ {{ end }} ++
    ++ ++ {{ with .File }} ++ {{ $href := printf "%sedit/master/content/%s/%s" site.Params.ghrepo $.Lang .Path }} ++ ++ Improve this page ++ ++ {{ end }} ++
    diff --cc docs/layouts/partials/layouts/related.html index 000000000,000000000..16a04dce1 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/related.html @@@ -1,0 -1,0 +1,37 @@@ ++{{- $heading := "See also" }} ++{{- $related := slice }} ++ ++{{- if .Params.action.related }} ++ {{- $related = slice }} ++ {{- range .Params.action.related }} ++ {{- $path := . | lower }} ++ {{- with or (site.GetPage $path) ($.GetPage $path) }} ++ {{- $related = $related | append . }} ++ {{- else }} ++ {{/* TODO1 make error */}} ++ {{- warnf "The 'related' partial was unable to get page %s" . }} ++ {{- end }} ++ {{- end }} ++{{- else }} ++ {{- $related = site.RegularPages.Related . }} ++{{- end }} ++{{/* Avoid repeating pages that's listed in In this section. */}} ++{{- $related = $related | complement .CurrentSection.RegularPages | first 7 }} ++{{- with $related }} ++ {{ $.Store.Set "hasRelated" true }} ++

    ++ {{ $heading }} ++

    ++ ++{{- end }} diff --cc docs/layouts/partials/layouts/search/button.html index 000000000,000000000..3dcb1eb9d new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/search/button.html @@@ -1,0 -1,0 +1,19 @@@ ++ diff --cc docs/layouts/partials/layouts/search/input.html index 000000000,000000000..5f5ff07b9 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/search/input.html @@@ -1,0 -1,0 +1,4 @@@ ++
    ++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" false) }} ++ {{ partial "layouts/search/results.html" . }} ++
    diff --cc docs/layouts/partials/layouts/search/results.html index 000000000,000000000..6ef519615 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/search/results.html @@@ -1,0 -1,0 +1,82 @@@ ++ diff --cc docs/layouts/partials/layouts/toc.html index 000000000,000000000..06946d885 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/layouts/toc.html @@@ -1,0 -1,0 +1,42 @@@ ++{{ with .Fragments.Headings }} ++ {{ $.Store.Set "hasToc" true }} ++
    ++

    ++ On this page ++

    ++ ++
    ++{{ end }} ++ ++{{ define "render-toc-level" }} ++ {{ range . }} ++ {{ if and .ID (or (ge .Level 2) (lt .Level 4)) }} ++
  • ++ ++ {{ .Title | safeHTML }} ++ ++
  • ++ {{ end }} ++ {{ with .Headings }} ++
      ++ {{ template "render-toc-level" . }} ++
    ++ {{ end }} ++ {{ end }} ++{{ end }} diff --cc docs/layouts/partials/news/get-news-items.html index 000000000,000000000..cb1a930d3 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/news/get-news-items.html @@@ -1,0 -1,0 +1,45 @@@ ++{{ $news_items := slice }} ++ ++{{/* Get releases from GitHub. */}} ++{{ $u := "https://api.github.com/repos/gohugoio/hugo/releases" }} ++{{ $releases := partial "helpers/funcs/get-remote-data.html" $u }} ++{{ $releases = where $releases "draft" false }} ++{{ $releases = where $releases "prerelease" false }} ++{{ range $releases | first 20 }} ++ {{ $publishDate := .published_at | time.AsTime }} ++ ++ {{/* Correct the v0.138.0 release date. See https://github.com/gohugoio/hugo/issues/13066. */}} ++ {{ if eq .name "v0.138.0" }} ++ {{ $publishDate = "2024-11-06T11:22:34Z" | time.AsTime }} ++ {{ end }} ++ ++ {{ $ctx := dict ++ "Date" $publishDate ++ "Title" (printf "Release %s" .name) ++ "LinkTitle" (printf "Release %s" .name) ++ "Permalink" .html_url ++ "RelPermalink" .html_url ++ "Section" "news" ++ "Summary" "" ++ }} ++ {{ $news_items = $news_items | append $ctx }} ++{{ end }} ++ ++{{/* Get content pages from news section. */}} ++{{ range .Pages }} ++ {{ $ctx := dict ++ "Date" .Date ++ "Title" .Title ++ "LinkTitle" .Title ++ "RelPermalink" .RelPermalink ++ "Section" "news" ++ "Summary" .Summary ++ "Params" (dict "description" .Description) ++ }} ++ {{ $news_items = $news_items | append $ctx }} ++{{ end }} ++ ++{{/* Sort by date (descending) and render. */}} ++{{ $news_items = sort $news_items "Date" "desc" }} ++ ++{{ return $news_items }} diff --cc docs/layouts/partials/opengraph/get-featured-image.html index 000000000,000000000..50ee2a44d new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/opengraph/get-featured-image.html @@@ -1,0 -1,0 +1,26 @@@ ++{{ $images := $.Resources.ByType "image" }} ++{{ $featured := $images.GetMatch "*feature*" }} ++{{ if not $featured }} ++ {{ $featured = $images.GetMatch "{*cover*,*thumbnail*}" }} ++{{ end }} ++{{ if not $featured }} ++ {{ $featured = resources.Get "/opengraph/gohugoio-card-base-1.png" }} ++ {{ $size := 80 }} ++ {{ $title := $.LinkTitle }} ++ {{ if gt (len $title) 20 }} ++ {{ $size = 70 }} ++ {{ end }} ++ ++ {{ $text := $title }} ++ {{ $textOptions := dict ++ "color" "#FFF" ++ "size" $size ++ "lineSpacing" 10 ++ "x" 65 "y" 80 ++ "font" (resources.Get "/opengraph/mulish-black.ttf") ++ }} ++ ++ {{ $featured = $featured | images.Filter (images.Text $text $textOptions) }} ++{{ end }} ++ ++{{ return $featured }} diff --cc docs/layouts/partials/opengraph/opengraph.html index 000000000,000000000..1c89b0814 new file mode 100644 --- /dev/null +++ b/docs/layouts/partials/opengraph/opengraph.html @@@ -1,0 -1,0 +1,84 @@@ ++ ++ ++ ++ ++ ++{{- with $.Params.images -}} ++ {{- range first 6 . }} ++ ++ {{ end -}} ++{{- else -}} ++ {{- $featured := partial "opengraph/get-featured-image.html" . }} ++ {{- with $featured -}} ++ ++ {{- else -}} ++ {{- with $.Site.Params.images }} ++ ++ {{ end -}} ++ {{- end -}} ++{{- end -}} ++ ++{{- if .IsPage }} ++ {{- $iso8601 := "2006-01-02T15:04:05-07:00" -}} ++ ++ {{ with .PublishDate }} ++ ++ {{ end }} ++ {{ with .Lastmod }} ++ ++ {{ end }} ++{{- end -}} ++ ++{{- with .Params.audio }}{{ end }} ++{{- with .Params.locale }} ++ ++{{ end }} ++{{- with .Site.Params.title }} ++ ++{{ end }} ++{{- with .Params.videos }} ++ {{- range . }} ++ ++ {{ end }} ++ ++{{ end }} ++ ++{{- /* If it is part of a series, link to related articles */}} ++{{- $permalink := .Permalink }} ++{{- $siteSeries := .Site.Taxonomies.series }} ++{{ with .Params.series }} ++ {{- range $name := . }} ++ {{- $series := index $siteSeries ($name | urlize) }} ++ {{- range $page := first 6 $series.Pages }} ++ {{- if ne $page.Permalink $permalink }} ++ ++ {{ end }} ++ {{- end }} ++ {{ end }} ++ ++{{ end }} ++ ++{{- /* Facebook Page Admin ID for Domain Insights */}} ++{{- with site.Params.social.facebook_admin }} ++ ++{{ end }} diff --cc docs/layouts/shortcodes/chroma-lexers.html index 000000000,000000000..38241be33 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/chroma-lexers.html @@@ -1,0 -1,0 +1,7 @@@ ++
    ++ {{ range .Site.Data.docs.chroma.lexers }} ++
    {{ .Name }}
    ++
    {{ with .Aliases }}{{ delimit . ", " }}{{ end }}
    ++ {{ end }} ++
    ++ diff --cc docs/layouts/shortcodes/code-toggle.html index 000000000,000000000..4e64fded0 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/code-toggle.html @@@ -1,0 -1,0 +1,109 @@@ ++{{- /* ++ Renders syntax-highlighted configuration data in JSON, TOML, and YAML formats. ++ ++ @param {string} [config] The section of site.Data.docs.config to render. ++ @param {bool} [copy=false] If true, display a copy to clipboard button. ++ @param {string} [file] The file name to display above the rendered code. ++ @param {bool} [fm=false] If true, render the code as front matter. ++ @param {bool} [skipHeader=false] If false, omit top level key(s) when rendering a section of site.Data.docs.config. ++ ++ @returns {template.HTML} ++*/}} ++ ++{{- /* Initialize. */}} ++{{- $config := "" }} ++{{- $dataKey := "" }} ++{{- $copy := false }} ++{{- $file := "" }} ++{{- $fm := false }} ++{{- $skipHeader := false }} ++ ++{{- /* Get parameters. */}} ++{{- $config = .Get "config" }} ++{{- $dataKey = .Get "dataKey" }} ++{{- $file = .Get "file" }} ++{{- if in (slice "false" false 0) (.Get "copy") }} ++ {{- $copy = false }} ++{{- else if in (slice "true" true 1) (.Get "copy") }} ++ {{- $copy = true }} ++{{- end }} ++{{- if in (slice "false" false 0) (.Get "fm") }} ++ {{- $fm = false }} ++{{- else if in (slice "true" true 1) (.Get "fm") }} ++ {{- $fm = true }} ++{{- end }} ++{{- if in (slice "false" false 0) (.Get "skipHeader") }} ++ {{- $skipHeader = false }} ++{{- else if in (slice "true" true 1) (.Get "skipHeader") }} ++ {{- $skipHeader = true }} ++{{- end }} ++ ++{{- /* Define constants. */}} ++{{- $delimiters := dict "toml" "+++" "yaml" "---" }} ++{{- $langs := slice "yaml" "toml" "json" }} ++{{- $placeHolder := "#-hugo-placeholder-#" }} ++ ++{{- /* Render. */}} ++{{- $code := "" }} ++{{- if $config }} ++ {{- $file = $file | default "hugo" }} ++ {{- $sections := (split $config ".") }} ++ {{- $configSection := index $.Site.Data.docs.config $sections }} ++ {{- $code = dict $sections $configSection }} ++ {{- if $skipHeader }} ++ {{- $code = $configSection }} ++ {{- end }} ++{{- else if $dataKey }} ++ {{- $file = $file | default $dataKey }} ++ {{- $sections := (split $dataKey ".") }} ++ {{- $code = index $.Site.Data.docs $sections }} ++{{- else }} ++ {{- $code = $.Inner }} ++{{- end }} ++
    ++ ++ ++ ++ ++ {{ if $code }} ++ {{ range $i, $lang := $langs }} ++
    ++ {{- $hCode := $code | transform.Remarshal . }} ++ {{- if and $fm (in (slice "toml" "yaml") .) }} ++ {{- $hCode = printf "%s\n%s\n%s" $placeHolder $hCode $placeHolder }} ++ {{- end }} ++ {{- $hCode = $hCode | replaceRE `\n+` "\n" }} ++ {{ highlight $hCode . "" | replaceRE $placeHolder (index $delimiters .) | safeHTML }} ++
    ++ {{ end }} ++ {{ end }} ++
    diff --cc docs/layouts/shortcodes/code.html index 000000000,000000000..1ccb44b7d new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/code.html @@@ -1,0 -1,0 +1,38 @@@ ++{{- $codeLang := or (.Get "lang") "" }} ++
    ++ {{ if (.Get "copy") }} ++ ++ ++ ++ {{ end }} ++ {{- with .Get "file" -}} ++ {{- if not $codeLang }} ++ {{- $ext := strings.TrimPrefix "." (path.Ext .) }} ++ {{- $codeLang = cond (eq $ext "html") "go-html-template" $ext }} ++ {{- end }} ++
    ++ {{ . }} ++
    ++ {{- end -}} ++ ++ ++
    ++ {{ $inner := trim .Inner "\n" | safeHTML }} ++ {{ if .Get "nocode" }} ++ {{ $inner }} ++ {{ else }} ++ {{ with $codeLang }} ++ {{ highlight $inner . "" }} ++ {{ else }} ++
    {{ $inner }}
    ++        
    ++ {{ end }} ++ {{ end }} ++
    ++
    diff --cc docs/layouts/shortcodes/datatable-filtered.html index 000000000,000000000..ff3f299bd new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/datatable-filtered.html @@@ -1,0 -1,0 +1,39 @@@ ++{{ $package := (index .Params 0) }} ++{{ $listname := (index .Params 1) }} ++{{ $filter := split (index .Params 2) " " }} ++{{ $filter1 := index $filter 0 }} ++{{ $filter2 := index $filter 1 }} ++{{ $filter3 := index $filter 2 }} ++ ++{{ $list := (index (index .Site.Data.docs $package) $listname) }} ++{{ $fields := after 3 .Params }} ++{{ $list := where $list $filter1 $filter2 $filter3 }} ++ ++ ++ ++ {{ range $fields }} ++ ++ {{ end }} ++ ++ {{ range $list }} ++ ++ {{ range $k, $v := . }} ++ {{ $.Scratch.Set $k $v }} ++ {{ end }} ++ {{ range $k, $v := $fields }} ++ ++ {{ end }} ++ ++ {{ end }} ++
    {{ . }}
    ++ {{ $tdContent := $.Scratch.Get . }} ++ {{ if eq $k 3 }} ++ {{ printf "%v" $tdContent | ++ strings.ReplaceRE `\[` "
    1. " | ++ strings.ReplaceRE `\s` "
    2. " | ++ strings.ReplaceRE `\]` "
    " | ++ safeHTML }} ++ {{ else }} ++ {{ $tdContent }} ++ {{ end}} ++
    diff --cc docs/layouts/shortcodes/datatable.html index 000000000,000000000..12054f89d new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/datatable.html @@@ -1,0 -1,0 +1,33 @@@ ++{{ $package := (index .Params 0) }} ++{{ $listname := (index .Params 1) }} ++{{ $list := (index (index .Site.Data.docs $package) $listname) }} ++{{ $fields := after 2 .Params }} ++ ++ ++ ++ ++ {{ range $fields }} ++ {{ $s := . }} ++ {{ if eq $s "_key" }} ++ {{ $s = "Type" }} ++ {{ end }} ++ ++ {{ end }} ++ ++ {{ range $k1, $v1 := $list }} ++ ++ {{ range $k2, $v2 := . }} ++ {{ $.Scratch.Set $k2 $v2 }} ++ {{ end }} ++ {{ range $fields }} ++ {{ $s := "" }} ++ {{ if eq . "_key" }} ++ {{ $s = $k1 }} ++ {{ else }} ++ {{ $s = $.Scratch.Get . }} ++ {{ end }} ++ ++ {{ end }} ++ ++ {{ end }} ++
    {{ $s }}
    {{ $s }}
    diff --cc docs/layouts/shortcodes/deprecated-in.html index 000000000,000000000..0272ea4a6 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/deprecated-in.html @@@ -1,0 -1,0 +1,17 @@@ ++{{ $_hugo_config := `{ "version": 1 }` }} ++ ++{{ with .Get 0 }} ++ {{ $version := printf "v%v" (strings.TrimLeft "vV" .) }} ++ {{ $href := printf "https://github.com/gohugoio/hugo/releases/tag/%s" $version }} ++ {{ $text := (printf `Deprecated in %s. ++%s` $href $version $.Inner) | safeHTML }} ++ ++ {{ partial "layouts/blocks/alert.html" (dict ++ "text" $text ++ "color" "orange" ++ "icon" "exclamation" ++ ) ++}} ++{{ else }} ++ {{ errorf "The %q shortcode requires a single positional parameter indicating version. See %s" .Name .Position }} ++{{ end }} diff --cc docs/layouts/shortcodes/eturl.html index 000000000,000000000..c0cf30aec new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/eturl.html @@@ -1,0 -1,0 +1,36 @@@ ++{{- /* ++Renders an absolute URL to the source code for an embedded template. ++ ++Accepts either positional or named parameters, and depends on the ++embedded_templates.toml file in the data directory. ++ ++@param {string} filename The embedded template's file name, excluding extension. ++ ++@returns template.HTML ++ ++@example {{% et robots.txt %}} ++@example {{% et filename=robots.txt %}} ++*/}} ++ ++{{- /* Get parameters. */}} ++{{- $filename := "" -}} ++{{- if .IsNamedParams -}} ++ {{- $filename = .Get "filename" -}} ++{{- else -}} ++ {{- $filename = .Get 0 -}} ++{{- end -}} ++ ++{{- /* Render. */}} ++{{- with $filename -}} ++ {{- with site.Data.embedded_template_urls -}} ++ {{- with index . $filename -}} ++ {{- urls.JoinPath site.Data.embedded_template_urls.base_url . -}} ++ {{- else -}} ++ {{- errorf "The %q shortcode was unable to find a URL for the embedded template named %q. Check the name. See %s" $.Name $filename $.Position -}} ++ {{- end -}} ++ {{- else -}} ++ {{- errorf "The %q shortcode was unable to find the embedded_template_urls data file in the site's data directory. See %s" $.Name $.Position -}} ++ {{- end -}} ++{{- else -}} ++ {{- errorf "The %q shortcodes requires a named or positional parameter, the file name of the embedded template, excluding its extension. See %s" .Name .Position -}} ++{{- end -}} diff --cc docs/layouts/shortcodes/glossary-term.html index 92ad93340,000000000..7aace730e mode 100644,000000..100644 --- a/docs/layouts/shortcodes/glossary-term.html +++ b/docs/layouts/shortcodes/glossary-term.html @@@ -1,20 -1,0 +1,20 @@@ +{{- /* +Renders the definition of the given glossary term. + +@param {string} (.Get 0) The glossary term. +@returns {template.HTML} + +@example {{% glossary-term float %}} +@example {{% glossary-term "floating point" %}} +*/}} + +{{- with .Get 0 }} - {{- $path := printf "/getting-started/glossary/%s" (urlize .) }} ++ {{- $path := printf "/quick-reference/glossary/%s" (urlize .) }} + {{- with site.GetPage $path }} - {{ .RenderShortcodes }}{{/* Do not indent. */}} ++{{ .RenderShortcodes }} {{/* Do not indent. Do not remove non-breaking space. */}} + {{- else }} + {{- errorf "The glossary term (%s) shortcode was unable to find %s: see %s" $.Name $path $.Position }} + {{- end }} +{{- else }} + {{- errorf "The glossary term (%s) shortcode requires one positional parameter: see %s" $.Name $.Position }} - {{- end }} ++{{- end -}} diff --cc docs/layouts/shortcodes/glossary.html index 3273efd8c,000000000..e91be32ce mode 100644,000000..100644 --- a/docs/layouts/shortcodes/glossary.html +++ b/docs/layouts/shortcodes/glossary.html @@@ -1,43 -1,0 +1,56 @@@ +{{- /* +Renders the glossary of terms. + +When you call this shortcode using the {{% %}} notation, the glossary terms are +Markdown headings (level 6) which means they are members of .Page.Fragments. +This allows the link render hook to verify links to glossary terms. + +Yes, the terms themselves are pages, but we don't want to link to the pages, at +least not right now. Instead, we want to link to the fragments rendered by this +shortcode. + +@returns {template.HTML} + +@example {{% glossary %}} +*/}} - {{- $path := "/getting-started/glossary" }} ++{{- $path := "/quick-reference/glossary" }} +{{- with site.GetPage $path }} - {{- with $p := .Pages.ByTitle }} + + {{- /* Build and render alphabetical index. */}} + {{- $m := dict }} - {{- range $p }} ++ {{- range $p := .Pages.ByTitle }} + {{- $k := substr .Title 0 1 | strings.ToUpper }} + {{- if index $m $k }} + {{- continue }} + {{- end }} + {{- $anchor := path.BaseName .Path | anchorize }} + {{- $m = merge $m (dict $k $anchor) }} + {{- end }} + {{- range $k, $v := $m }} +[{{ $k }}](#{{ $v }}) {{/* Do not indent. */}} + {{- end }} + + {{- /* Render glossary terms. */}} - {{- range $p }} ++ {{- range $p := .Pages.ByTitle }} +###### {{ .Title }}{{/* Do not indent. */}} +{{ .RenderShortcodes }}{{/* Do not indent. */}} ++ {{- with .Params.reference }} ++ {{- $destination := "" }} ++ {{- with $u := urls.Parse . }} ++ {{- if $u.IsAbs }} ++ {{- $destination = $u.String }} ++ {{- else }} ++ {{- with site.GetPage $u.Path -}} ++ {{- $destination = .RelPermalink }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find the reference link %s: see %s" $.Name . $p.String }} ++ {{- end }} ++ {{- end }} ++ {{- end -}} ++ See [details]({{ $destination }}).{{/* Do not indent. */}} ++ {{- end }} + {{- end }} + - {{- end }} +{{- else }} + {{- errorf "The %q shortcode was unable to get %s: see %s" .Name $path .Position}} +{{- end }} diff --cc docs/layouts/shortcodes/gomodules-info.html index 000000000,000000000..126d846c0 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/gomodules-info.html @@@ -1,0 -1,0 +1,12 @@@ ++{{ $text := ` ++ Most of the commands for **Hugo Modules** require a newer version (>= 1.18) of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ). ++ If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.19 or newer in your Environment settings. ++ ++ For more information about Go Modules, see: ++ ++ * https://go.dev/wiki/Modules ++ * https://blog.golang.org/using-go-modules ++ ` ++}} ++ ++{{ partial "layouts/blocks/alert.html" (dict "title" "Go Modules" "text" ($text | markdownify) "color" "orange" "icon" "exclamation") }} diff --cc docs/layouts/shortcodes/hl.html index 000000000,000000000..1a5b4e1ec new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/hl.html @@@ -1,0 -1,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 }} diff --cc docs/layouts/shortcodes/img.html index 000000000,000000000..7c2d805d2 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/img.html @@@ -1,0 -1,0 +1,391 @@@ ++{{- /* ++Renders the given image using the given filter, if any. ++ ++@param {string} src The path to the image which must be a remote, page, or global resource. ++@param {string} [filter] The filter to apply to the image (case-insensitive). ++@param {string} [filterArgs] A comma-delimited list of arguments to pass to the filter. ++@param {bool} [example=false] If true, renders a before/after example. ++@param {int} [exampleWidth=384] Image width, in pixels, when rendering a before/after example. ++ ++@returns {template.HTML} ++ ++@examples ++ ++ {{< img src="zion-national-park.jpg" >}} ++ ++ {{< img src="zion-national-park.jpg" alt="Zion National Park" >}} ++ ++ {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="grayscale" ++ >}} ++ ++ {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="process" ++ filterArgs="resize 400x webp" ++ >}} ++ ++ {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="colorize" ++ filterArgs="180,50,20" ++ >}} ++ ++ {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="grayscale" ++ example=true ++ >}} ++ ++ {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="grayscale" ++ example=true ++ exampleWidth=400 ++ >}} ++ ++ When using the text filter, provide the arguments in this order: ++ ++ 0. The text ++ 1. The horizontal offset, in pixels, relative to the left of the image (default 20) ++ 2. The vertical offset, in pixels, relative to the top of the image (default 20) ++ 3. The font size in pixels (default 64) ++ 4. The line height (default 1.2) ++ 5. The font color (default #ffffff) ++ ++ {{< img ++ src="images/examples/zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="Text" ++ filterArgs="Zion National Park,25,250,56" ++ example=true ++ >}} ++ ++ When using the padding filter, provide all arguments in this order: ++ ++ 0. Padding top ++ 1. Padding right ++ 2. Padding bottom ++ 3. Padding right ++ 4. Canvas color ++ ++ {{< img ++ src="images/examples/zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="Padding" ++ filterArgs="20,50,20,50,#0705" ++ example=true ++ >}} ++ ++*/}} ++ ++{{- /* Initialize. */}} ++{{- $alt := "" }} ++{{- $src := "" }} ++{{- $filter := "" }} ++{{- $filterArgs := slice }} ++{{- $example := false }} ++{{- $exampleWidth := 384 }} ++ ++{{- /* Default values to use with the text filter. */}} ++{{ $textFilterOpts := dict ++ "xOffset" 20 ++ "yOffset" 20 ++ "fontSize" 64 ++ "lineHeight" 1.2 ++ "fontColor" "#ffffff" ++ "fontPath" "https://github.com/google/fonts/raw/main/ofl/lato/Lato-Regular.ttf" ++}} ++ ++{{- /* Get and validate parameters. */}} ++{{- with .Get "alt" }} ++ {{- $alt = .}} ++{{- end }} ++ ++{{- with .Get "src" }} ++ {{- $src = . }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a file parameter. See %s" .Name .Position }} ++{{- end }} ++ ++{{- with .Get "filter" }} ++ {{- $filter = . | lower }} ++{{- end }} ++ ++{{- $validFilters := slice ++ "autoorient" "brightness" "colorbalance" "colorize" "contrast" "dither" ++ "gamma" "gaussianblur" "grayscale" "hue" "invert" "mask" "none" "opacity" ++ "overlay" "padding" "pixelate" "process" "saturation" "sepia" "sigmoid" "text" ++ "unsharpmask" ++}} ++ ++{{- with $filter }} ++ {{- if not (in $validFilters .) }} ++ {{- errorf "The filter passed to the %q shortcode is invalid. The filter must be one of %s. See %s" $.Name (delimit $validFilters ", " ", or ") $.Position }} ++ {{- end }} ++{{- end }} ++ ++{{- with .Get "filterArgs" }} ++ {{- $filterArgs = split . "," }} ++ {{- $filterArgs = apply $filterArgs "trim" "." " " }} ++{{- end }} ++ ++{{- if in (slice "false" false 0) (.Get "example") }} ++ {{- $example = false }} ++{{- else if in (slice "true" true 1) (.Get "example")}} ++ {{- $example = true }} ++{{- end }} ++ ++{{- with .Get "exampleWidth" }} ++ {{- $exampleWidth = . | int }} ++{{- end }} ++ ++{{- /* Get image. */}} ++{{- $ctx := dict "page" .Page "src" $src "name" .Name "position" .Position }} ++{{- $i := partial "inline/get-resource.html" $ctx }} ++ ++{{- /* Resize if rendering before/after examples. */}} ++{{- if $example }} ++ {{- $i = $i.Resize (printf "%dx" $exampleWidth) }} ++{{- end }} ++ ++{{- /* Create filter. */}} ++{{- $f := "" }} ++{{- $ctx := dict "filter" $filter "args" $filterArgs "name" .Name "position" .Position }} ++{{- if eq $filter "autoorient" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.AutoOrient }} ++{{- else if eq $filter "brightness" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Brightness (index $filterArgs 0) }} ++{{- else if eq $filter "colorbalance" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage red" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage green" "argValue" (index $filterArgs 1) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage blue" "argValue" (index $filterArgs 2) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.ColorBalance (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }} ++{{- else if eq $filter "colorize" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "hue" "argValue" (index $filterArgs 0) "min" 0 "max" 360) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "saturation" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 2) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Colorize (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }} ++{{- else if eq $filter "contrast" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Contrast (index $filterArgs 0) }} ++{{- else if eq $filter "dither" }} ++ {{- $f = images.Dither }} ++{{- else if eq $filter "gamma" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "gamma" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Gamma (index $filterArgs 0) }} ++{{- else if eq $filter "gaussianblur" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.GaussianBlur (index $filterArgs 0) }} ++{{- else if eq $filter "grayscale" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.Grayscale }} ++{{- else if eq $filter "hue" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "shift" "argValue" (index $filterArgs 0) "min" -180 "max" 180) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Hue (index $filterArgs 0) }} ++{{- else if eq $filter "invert" }} ++ {{- $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 }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "opacity" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Opacity (index $filterArgs 0) }} ++{{- else if eq $filter "overlay" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }} ++ {{- $overlayImg := partial "inline/get-resource.html" $ctx }} ++ {{- $f = images.Overlay $overlayImg (index $filterArgs 1 | float ) (index $filterArgs 2 | float) }} ++{{- else if eq $filter "padding" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 5) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.Padding ++ (index $filterArgs 0 | int) ++ (index $filterArgs 1 | int) ++ (index $filterArgs 2 | int) ++ (index $filterArgs 3 | int) ++ (index $filterArgs 4) ++ }} ++{{- else if eq $filter "pixelate" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "size" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Pixelate (index $filterArgs 0) }} ++{{- else if eq $filter "process" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.Process (index $filterArgs 0) }} ++{{- else if eq $filter "saturation" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Saturation (index $filterArgs 0) }} ++{{- else if eq $filter "sepia" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Sepia (index $filterArgs 0) }} ++{{- else if eq $filter "sigmoid" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 2) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "midpoint" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "factor" "argValue" (index $filterArgs 1) "min" -10 "max" 10) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Sigmoid (index $filterArgs 0) (index $filterArgs 1) }} ++{{- else if eq $filter "text" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $ctx := dict "src" $textFilterOpts.fontPath "name" .Name "position" .Position }} ++ {{- $font := or (partial "inline/get-resource.html" $ctx) }} ++ {{- $fontSize := or (index $filterArgs 3 | int) $textFilterOpts.fontSize }} ++ {{- $lineHeight := math.Max (or (index $filterArgs 4 | float) $textFilterOpts.lineHeight) 1 }} ++ {{- $opts := dict ++ "x" (or (index $filterArgs 1 | int) $textFilterOpts.xOffset) ++ "y" (or (index $filterArgs 2 | int) $textFilterOpts.yOffset) ++ "size" $fontSize ++ "linespacing" (mul (sub $lineHeight 1) $fontSize) ++ "color" (or (index $filterArgs 5) $textFilterOpts.fontColor) ++ "font" $font ++ }} ++ {{- $f = images.Text (index $filterArgs 0) $opts }} ++{{- else if eq $filter "unsharpmask" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "amount" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "threshold" "argValue" (index $filterArgs 2) "min" 0 "max" 1) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.UnsharpMask (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }} ++{{- end }} ++ ++{{- /* Apply filter. */}} ++{{- $fi := $i }} ++{{- with $f }} ++ {{- $fi = $i.Filter . }} ++{{- end }} ++ ++{{- /* Render. */}} ++{{- $class := "di va b--black-20" }} ++{{- if eq $filter "mask" }} ++ {{- $class = "di va" }} ++{{- end }} ++{{- if $example }} ++

    Original

    ++ {{ $alt }} ++

    Processed

    ++ {{ $alt }} ++{{- else -}} ++ {{ $alt }} ++{{- end }} ++ ++{{- define "validate-arg-count" }} ++ {{- $msg := "When using the %q filter, the %q shortcode requires an args parameter with %d %s. See %s" }} ++ {{- if lt (len .args) .argsRequired }} ++ {{- $text := "values" }} ++ {{- if eq 1 .argsRequired }} ++ {{- $text = "value" }} ++ {{- end }} ++ {{- errorf $msg .filter .name .argsRequired $text .position }} ++ {{- end }} ++{{- end }} ++ ++{{- define "validate-arg-value" }} ++ {{- $msg := "The %q argument passed to the %q shortcode is invalid. Expected a value in the range [%v,%v], but received %v. See %s" }} ++ {{- if or (lt .argValue .min) (gt .argValue .max) }} ++ {{- errorf $msg .argName .name .min .max .argValue .position }} ++ {{- end }} ++{{- end }} ++ ++{{- define "partials/inline/get-resource.html" }} ++ {{- $r := "" }} ++ {{- $u := urls.Parse .src }} ++ {{- $msg := "The %q shortcode was unable to resolve %s. See %s" }} ++ {{- if $u.IsAbs }} ++ {{- with try (resources.GetRemote $u.String) }} ++ {{- with .Err }} ++ {{- errorf "%s" . }} ++ {{- else with .Value }} ++ {{- /* This is a remote resource. */}} ++ {{- $r = . }} ++ {{- else }} ++ {{- errorf $msg $.name $u.String $.position }} ++ {{- end }} ++ {{- end }} ++ {{- else }} ++ {{- with .page.Resources.Get (strings.TrimPrefix "./" $u.Path) }} ++ {{- /* This is a page resource. */}} ++ {{- $r = . }} ++ {{- else }} ++ {{- with resources.Get $u.Path }} ++ {{- /* This is a global resource. */}} ++ {{- $r = . }} ++ {{- else }} ++ {{- errorf $msg $.name $u.Path $.position }} ++ {{- end }} ++ {{- end }} ++ {{- end }} ++ {{- return $r}} ++{{- end -}} diff --cc docs/layouts/shortcodes/imgproc.html index 000000000,000000000..c09133ba8 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/imgproc.html @@@ -1,0 -1,0 +1,37 @@@ ++{{- /* ++Renders the given image using the given process specification. ++ ++@param {string} (positional parameter 0) The path to the image, relative to the current page. The image must be a page resource. ++@param {string}} (positional parameter 1) The image processing specification. ++ ++@returns template.HTML ++ ++@example {{< imgproc "sunset.jpg" "resize 300x" />}} ++*/}} ++ ++{{- with $.Get 0 }} ++ {{- with $i := $.Page.Resources.Get . }} ++ {{- with $spec := $.Get 1 }} ++ {{- with $i.Process . }} ++
    ++ ++
    ++ ++ {{- with $.Inner }} ++ {{ . }} ++ {{- else }} ++ {{ $spec }} ++ {{- end }} ++ ++
    ++
    ++ {{- end }} ++ {{- else }} ++ {{- errorf "The %q shortcode requires a positional parameter (1) containing the image processing specification. See %s" $.Name $.Position }} ++ {{- end }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a positional parameter (0) indicating the image path, relative to the current page. See %s" $.Name $.Position }} ++{{- end }} diff --cc docs/layouts/shortcodes/include.html index 000000000,000000000..b4a20cd72 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/include.html @@@ -1,0 -1,0 +1,21 @@@ ++{{- /* ++Renders the page using the RenderShortcode method on the Page object. ++ ++You must call this shortcode using the {{% %}} notation. ++ ++@param {string} (positional parameter 0) The path to the page, relative to the content directory. ++@returns template.HTML ++ ++@example {{% include "functions/_common/glob-patterns" %}} ++*/}} ++ ++{{- with .Get 0 }} ++ {{- with or ($.Page.GetPage .) (site.GetPage .) }} ++ {{- .RenderShortcodes }} ++ {{- else }} ++ {{/* TODO1 make error */}} ++ {{- warnf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a positional parameter indicating the path of the file to include. See %s" .Name .Position }} ++{{- end }} diff --cc docs/layouts/shortcodes/list-pages-in-section.html index 000000000,000000000..73e7f85a9 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/list-pages-in-section.html @@@ -1,0 -1,0 +1,96 @@@ ++{{- /* ++Renders a description list of the pages in the given section. ++ ++Render a subset of the pages in the section by specifying a predefined filter, ++and whether to include those pages. ++ ++Filters are defined in the data directory, in the file named page_filters. Each ++filter is an array of paths to a file, relative to the root of the content ++directory. Hugo will throw an error if the specified filter does not exist, or ++if any of the pages in the filter do not exist. ++ ++The definition term elements (dt) have an id attribute derived from the title ++of the page. This is probably unique, because pages of the same title in the ++same section is unlikely. ++ ++If you render a complete list on a page, then call the shortcode again to ++render a subset, you will generate duplicate element ids. In this case, set ++omitElementIDs to true for the subset. ++ ++@param {string} path The path to the section. ++@param {string} [filter=""] The name of filter list. ++@param {string} [filterType=""] The type of filter, either include or exclude. ++@param {string} [omitElementIDs=false] Whether to omit dt element ids. ++@param {string} [titlePrefix=""] The string to prepend to the link title. ++ ++@returns template.HTML ++ ++@example {{< list-pages-in-section path=/methods/resources >}} ++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude >}} ++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude titlePrefix=foo >}} ++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude titlePrefix=foo omitElementIDs=true >}} ++*/}} ++ ++{{- /* Initialize. */}} ++{{- $filter := or "" (.Get "filter" | lower)}} ++{{- $filterType := or (.Get "filterType") "none" | lower }} ++{{- $filteredPages := slice }} ++{{- $titlePrefix := or (.Get "titlePrefix") "" }} ++{{- $omitElementIDs := false }} ++ ++{{- /* Get boolean parameters. */}} ++{{- if in (slice "false" false 0) (.Get "omitElementIDs") }} ++ {{- $omitElementIDs = false }} ++{{- else if in (slice "true" true 1) (.Get "omitElementIDs")}} ++ {{- $omitElementIDs = true }} ++{{- end }} ++ ++{{- /* Build slice of filtered pages. */}} ++{{- with $filter }} ++ {{- with index site.Data.page_filters . }} ++ {{- range . }} ++ {{- with site.GetPage . }} ++ {{- $filteredPages = $filteredPages | append . }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find %q as specified in the page_filters data file. See %s" $.Name . $.Position }} ++ {{- end }} ++ {{- end }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find the %q filter in the page_filters data file. See %s" $.Name . $.Position }} ++ {{- end }} ++{{- end }} ++ ++{{- /* Render */}} ++{{- with $sectionPath := .Get "path" }} ++ {{- with site.GetPage . }} ++ {{- with .RegularPages }} ++
    ++ {{- range $page := .ByTitle }} ++ {{- if or ++ (and (eq $filterType "include") (in $filteredPages $page)) ++ (and (eq $filterType "exclude") (not (in $filteredPages $page))) ++ (eq $filterType "none") ++ }} ++ {{- $linkTitle := .LinkTitle }} ++ {{- with $titlePrefix }} ++ {{- $linkTitle = printf "%s%s" . $linkTitle }} ++ {{- end }} ++ {{- $idAttribute := "" }} ++ {{- if not $omitElementIDs }} ++ {{- $id := path.Join .File.Dir .File.ContentBaseName | replaceRE `[\|/]` ":" | lower }} ++ {{- $idAttribute = printf " id=%q" $id }} ++ {{- end }} ++
    {{ $linkTitle }}
    ++
    {{- $page.Description | $page.RenderString }}
    ++ {{- end }} ++ {{- end }} ++
    ++ {{- else }} ++ {{- warnf "The %q shortcode found no pages in the %q section. See %s" $.Name $sectionPath $.Position }} ++ {{- end }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name $sectionPath $.Position }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a 'path' parameter indicating the path to the section. See %s" $.Name $.Position }} ++{{- end }} diff --cc docs/layouts/shortcodes/module-mounts-note.html index 000000000,000000000..c1c67991e new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/module-mounts-note.html @@@ -1,0 -1,0 +1,1 @@@ ++Also see [Module Mounts Config](/hugo-modules/configuration/#module-configuration-mounts) for an alternative way to configure this directory. diff --cc docs/layouts/shortcodes/new-in.html index 000000000,000000000..e99cc7bcf new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/new-in.html @@@ -1,0 -1,0 +1,66 @@@ ++{{- /* ++ Renders a "new in" button indicating the version in which a feature was added. ++ ++ When comparing the current version to the specified version, the "new in" ++ button will be hidden if any of the following conditions is true: ++ ++ - The major version difference exceeds the majorVersionDiffThreshold ++ - The minor version difference exceeds the minorVersionDiffThreshold ++ ++ @param {string} version The semantic version string, with or without a leading v. ++ @returns {template.HTML} ++ ++ @examples {{< new-in 0.100.0 / ++>}} ++ ++{{< new-in 0.100.0 >}} ++Some descriptive text here. ++{{< /new-in >}} ++*/}} ++{{ $_hugo_config := `{ "version": 1 }` }} ++ ++{{- /* Set defaults. */}} ++{{- $majorVersionDiffThreshold := 0 }} ++{{- $minorVersionDiffThreshold := 30 }} ++{{- $displayExpirationWarning := true }} ++ ++{{- /* Render. */}} ++{{- with $version := .Get 0 | strings.TrimPrefix "v" }} ++ {{- $majorVersionDiff := sub (index (split hugo.Version ".") 0 | int) (index (split $version ".") 0 | int) }} ++ {{- $minorVersionDiff := sub (index (split hugo.Version ".") 1 | int) (index (split $version ".") 1 | int) }} ++ {{- if or (gt $majorVersionDiff $majorVersionDiffThreshold) (gt $minorVersionDiff $minorVersionDiffThreshold) }} ++ {{- if $displayExpirationWarning }} ++ {{- warnf "This call to the %q shortcode should be removed: %s. The button is now hidden because the specified version (%s) is older than the display threshold." $.Name $.Position $version }} ++ {{- end }} ++ {{- else }} ++ {{- $href := printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }} ++ {{- with $.Inner }} ++ {{ $text := printf `

    New in v%s.

    %s` ++ $href $version (. | $.Page.RenderString (dict "display" "block")) ++ }} ++ ++ {{ partial "layouts/blocks/alert.html" (dict ++ "text" ($text | safeHTML) ++ "color" "green" ++ "icon" "exclamation" ++ ) ++ }} ++ {{- else }} ++ ++ ++ ++ ++ ++ New in ++ v{{ $version }} ++ ++ ++ {{- end }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a positional parameter (version). See %s" .Name .Position }} ++{{- end -}} diff --cc docs/layouts/shortcodes/note.html index 000000000,000000000..b18d53bc7 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/note.html @@@ -1,0 -1,0 +1,7 @@@ ++{{ $_hugo_config := `{ "version": 1 }` }} ++{{ partial "layouts/blocks/alert.html" (dict ++ "text" .Inner ++ "color" "blue" ++ "icon" "exclamation" ++ ) ++}} diff --cc docs/layouts/shortcodes/quick-reference.html index 000000000,000000000..fc53c93bd new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/quick-reference.html @@@ -1,0 -1,0 +1,39 @@@ ++{{/* ++Renders the child sections of the given top-level section, listing each child's immediate descendants. ++ ++@param {string} section The top-level section to render. ++@returns template.HTML ++ ++@example {{% quick-reference section="functions" %}} ++*/}} ++ ++{{ $section := "" }} ++{{ with .Get "section" }} ++ {{ $section = . }} ++{{ else }} ++ {{ errorf "The %q shortcodes requires a 'section' parameter. See %s" .Name .Position }} ++{{ end }} ++ ++{{/* Do not change the markdown indentation, and do not remove blank lines. */}} ++{{ with site.GetPage $section }} ++ {{ range .Sections }} ++ ++## {{ .LinkTitle }} ++{{ .RawContent }} ++ ++ {{ range .Pages }} ++ {{ $aliases := "" }} ++ {{ if eq .Section "functions" }} ++ {{ with .Params.action.aliases }} ++ {{ $aliases = delimit . " or " }} ++ {{ end }} ++ {{ end }} ++ ++[{{ .LinkTitle }}]({{ .RelPermalink }}) {{ with $aliases }}({{ . }}){{ end }} ++: {{ .Description }} ++ ++ {{ end }} ++ {{ end }} ++{{ else }} ++ {{ errorf "The %q shortcodes was unable to find the %q section. See %s" .Name $section .Position }} ++{{ end }} diff --cc docs/layouts/shortcodes/readfile.html index 000000000,000000000..1a7d6a320 new file mode 100644 --- /dev/null +++ b/docs/layouts/shortcodes/readfile.html @@@ -1,0 -1,0 +1,1 @@@ ++TODO readfile.html diff --cc docs/netlify.toml index 52699de3a,000000000..0cd557e7c mode 100644,000000..100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@@ -1,30 -1,0 +1,55 @@@ +[build] + publish = "public" + command = "hugo --gc --minify" + + [build.environment] - HUGO_VERSION = "0.142.0" ++ HUGO_VERSION = "0.143.1" + +[context.production.environment] + HUGO_ENV = "production" + HUGO_ENABLEGITINFO = "true" + +[context.split1] + command = "hugo --gc --minify --enableGitInfo" + + [context.split1.environment] + HUGO_ENV = "production" + +[context.deploy-preview] - command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL" ++ command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL --enableGitInfo" + +[context.branch-deploy] + command = "hugo --gc --minify -b $DEPLOY_PRIME_URL" + +[context.next.environment] + HUGO_ENABLEGITINFO = "true" + - [[redirects]] - from = "/npmjs/*" - to = "/npmjs/" - status = 200 ++[[headers]] ++ for = "/*.jpg" ++ ++ [headers.values] ++ Cache-Control = "public, max-age=31536000" ++ ++[[headers]] ++ for = "/*.png" ++ ++ [headers.values] ++ Cache-Control = "public, max-age=31536000" ++ ++[[headers]] ++ for = "/*.css" ++ ++ [headers.values] ++ Cache-Control = "public, max-age=31536000" ++ ++[[headers]] ++ for = "/*.js" ++ ++ [headers.values] ++ Cache-Control = "public, max-age=31536000" ++ ++[[headers]] ++ for = "/*.ttf" ++ ++ [headers.values] ++ Cache-Control = "public, max-age=31536000" diff --cc docs/package.json index 000000000,000000000..92339ba25 new file mode 100644 --- /dev/null +++ b/docs/package.json @@@ -1,0 -1,0 +1,22 @@@ ++{ ++ "name": "hugoDocs", ++ "version": "1.0.0", ++ "description": "", ++ "main": "index.js", ++ "scripts": { ++ "test": "echo \"Error: no test specified\" && exit 1" ++ }, ++ "author": "", ++ "license": "", ++ "devDependencies": { ++ "@tailwindcss/cli": "^4.0.0", ++ "@tailwindcss/typography": "^0.5.15", ++ "tailwindcss": "^4.0.0" ++ }, ++ "dependencies": { ++ "@alpinejs/focus": "^3.14.8", ++ "@alpinejs/persist": "^3.14.8", ++ "@hotwired/turbo": "^8.0.12", ++ "alpinejs": "^3.14.8" ++ } ++} diff --cc docs/static/android-chrome-144x144.png index 000000000,000000000..975cb33ba new file mode 100644 Binary files differ diff --cc docs/static/android-chrome-192x192.png index 000000000,000000000..7ab6c3849 new file mode 100644 Binary files differ diff --cc docs/static/android-chrome-256x256.png index 000000000,000000000..ed88a2224 new file mode 100644 Binary files differ diff --cc docs/static/android-chrome-36x36.png index 000000000,000000000..3695eb088 new file mode 100644 Binary files differ diff --cc docs/static/android-chrome-48x48.png index 000000000,000000000..ca275dad6 new file mode 100644 Binary files differ diff --cc docs/static/android-chrome-72x72.png index 000000000,000000000..966891f25 new file mode 100644 Binary files differ diff --cc docs/static/android-chrome-96x96.png index 000000000,000000000..feb1d3ebf new file mode 100644 Binary files differ diff --cc docs/static/apple-touch-icon.png index 50e23ce1d,000000000..ecf1fc020 mode 100644,000000..100644 Binary files differ diff --cc docs/static/browserconfig.xml index 000000000,000000000..62400c5f2 new file mode 100644 --- /dev/null +++ b/docs/static/browserconfig.xml @@@ -1,0 -1,0 +1,10 @@@ ++ ++ ++ ++ ++ ++ ++ #2d89ef ++ ++ ++ diff --cc docs/static/favicon-16x16.png index 000000000,000000000..c62ce6fb2 new file mode 100644 Binary files differ diff --cc docs/static/favicon-32x32.png index 000000000,000000000..57a018e35 new file mode 100644 Binary files differ diff --cc docs/static/favicon.ico index 36693330b,000000000..dc007a99e mode 100644,000000..100644 Binary files differ diff --cc docs/static/fonts/Mulish-Italic-VariableFont_wght.ttf index 000000000,000000000..e5425c75e new file mode 100644 Binary files differ diff --cc docs/static/fonts/Mulish-VariableFont_wght.ttf index 000000000,000000000..410f7aa63 new file mode 100644 Binary files differ diff --cc docs/static/images/gopher-hero.svg index 000000000,000000000..36d9f1c41 new file mode 100644 --- /dev/null +++ b/docs/static/images/gopher-hero.svg @@@ -1,0 -1,0 +1,58 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --cc docs/static/images/gopher-side_color.svg index 000000000,000000000..85f949783 new file mode 100644 --- /dev/null +++ b/docs/static/images/gopher-side_color.svg @@@ -1,0 -1,0 +1,31 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --cc docs/static/images/hugo-logo-wide.svg index 000000000,000000000..1f6a79ea6 new file mode 100644 --- /dev/null +++ b/docs/static/images/hugo-logo-wide.svg @@@ -1,0 -1,0 +1,7 @@@ ++ ++ ++ ++ ++ ++ ++ diff --cc docs/static/manifest.json index 000000000,000000000..e671ac45a new file mode 100644 --- /dev/null +++ b/docs/static/manifest.json @@@ -1,0 -1,0 +1,45 @@@ ++{ ++ "name": "Hugo", ++ "short_name": "Hugo", ++ "icons": [ ++ { ++ "src": "/android-chrome-36x36.png", ++ "sizes": "36x36", ++ "type": "image/png" ++ }, ++ { ++ "src": "/android-chrome-48x48.png", ++ "sizes": "48x48", ++ "type": "image/png" ++ }, ++ { ++ "src": "/android-chrome-72x72.png", ++ "sizes": "72x72", ++ "type": "image/png" ++ }, ++ { ++ "src": "/android-chrome-96x96.png", ++ "sizes": "96x96", ++ "type": "image/png" ++ }, ++ { ++ "src": "/android-chrome-144x144.png", ++ "sizes": "144x144", ++ "type": "image/png" ++ }, ++ { ++ "src": "/android-chrome-192x192.png", ++ "sizes": "192x192", ++ "type": "image/png" ++ }, ++ { ++ "src": "/android-chrome-256x256.png", ++ "sizes": "256x256", ++ "type": "image/png" ++ } ++ ], ++ "start_url": "./?utm_source=web_app_manifest", ++ "theme_color": "#0A1922", ++ "background_color": "#FFF", ++ "display": "standalone" ++} diff --cc docs/static/mstile-144x144.png index 000000000,000000000..e54b4bd75 new file mode 100644 Binary files differ diff --cc docs/static/mstile-150x150.png index 000000000,000000000..c7b84c690 new file mode 100644 Binary files differ diff --cc docs/static/mstile-310x310.png index 000000000,000000000..2cde5c08c new file mode 100644 Binary files differ diff --cc docs/static/safari-pinned-tab.svg index 000000000,000000000..80ff2dae3 new file mode 100644 --- /dev/null +++ b/docs/static/safari-pinned-tab.svg @@@ -1,0 -1,0 +1,22 @@@ ++ ++ ++ ++ ++Created by potrace 1.11, written by Peter Selinger 2001-2013 ++ ++ ++ ++ ++ diff --cc docs/tailwind.config.js index 000000000,000000000..9d3c29050 new file mode 100644 --- /dev/null +++ b/docs/tailwind.config.js @@@ -1,0 -1,0 +1,1 @@@ ++/* Empty for now. */