only blank lines here {{ define "main" }} Go Template code and comments here {{ end }} only blank lines here
2021-March-27 In this article, created 9. get-assets-text, which is about a shortcode that is similar to the one discussed in 8. get-leaf-text.
2021-March-21 Hugo v0.82.0 released. To keep up with Hugo releases, see discourse.gohugo.io/c/announcements, github.com/gohugoio/hugo/releases, gohugo.io/news, old.reddit.com/r/gohugo/, or twitter.com/@GoHugoIO.
2021-February-1
As of today, this evolving[1]
article
has been on the web for
Commenting is useful for writing notes to yourself and for holding fragments that you have used in the past or may use in the future. To learn about the comment syntax of many languages, see Infinite Ink’s Commenting Code Cheatsheet.
‼ | In a
child
block layout file,
do not put a comment — or anything other than blank lines — outside
a only blank lines here {{ define "main" }} Go Template code and comments here {{ end }} only blank lines here |
In the Go Template language, which is also known as Go HTML, you can comment out[2] executable code with the following single- or multi-line comment syntax.
{{/* Go HTML single-line comment */}} {{/* Go HTML multi-line comment */}}
The following also work.
{{- /* Go HTML single-line comment */ -}} {{- /* Go HTML multi-line comment */ -}}
Note that in this second style of Go Template comment syntax, a space is required between each
dash (-
)[3]
and
its corresponding
slash (/
).
💡 | To learn how to denature a Hugo shortcode, which is how you put executable code inside a content file, see fragment 14. Escaping and commenting out Hugo shortcodes below. |
In a layout file or a Markdown content file, you can comment out text (such as an English-language note to yourself) or non-executable code with the following single- or multi-line comment syntax.
<!-- HTML or Markdown single-line comment --> <!-- HTML or Markdown multi-line comment -->
‼ | Do not use these HTML-style comments to comment out Go Template code in a Hugo layout file. If you do, Hugo will process the code and potentially generate error messages or change the layout logic. |
Hugo
shortcodes
are a way to use Go Template code within
a
content file.
Reusable and one-off shortcodes
usually live in the layouts/shortcodes/
directory
but,
starting with Hugo
v0.52, you
have the option to put a shortcode directly into
a content file
by using
an
“inline
shortcode.”
This is especially useful for one-off shortcodes
such as
the ones discussed in
fragment
3
and fragment
4
below.
To use inline shortcodes
you need to
set
enableInlineShortcodes
to true
in your Hugo config file by
putting this in your
config.yaml
:
enableInlineShortcodes: true
Or
this
in your
config.toml
:
enableInlineShortcodes = true
Infinite Ink’s I Use This (www.ii.com/uses/) page displays this:
hugo v0.82.0/extended
Each time
Hugo
builds the Infinite Ink website,
the part after
the string
“hugo ”
is generated
by the following
fragment in
Infinite Ink’s
uses.asciidoc
[4]
content
source
file.
v{{< hv.inline >}} {{- hugo.Version -}} {{< /hv.inline >}}/extended
To learn about the
context-free[5]
hugo
function,hugo.Version
(used above)
and hugo.IsProduction
(used in the next section),
see
gohugo.io/functions/hugo/.
ℹ | The
dashes[3]
in
the delimiters
|
On
Infinite Ink’s To-Do and Done Lists👷♀,
in the section
Writing In Progress,
there is a list of articles
that
have not
yet
been published.
For production — i.e. what you see — this is a list of titles without links,
but
for me,
when I am developing the Infinite Ink website with the hugo server
command,
this is a list of titles with links
to these
unpublished
articles.
I do this
by putting my
writing-in-progress
articles
in
a directory named
content/wip/
[6][7]
and
by putting the following
inline shortcode
in
Infinite Ink’s
website-todo-done.asciidoc
[4]
content file.
{{< wip.inline >}}
<ul>
{{ range (where site.RegularPages.ByTitle "Section" "eq" "wip") }}
<li>
{{ if hugo.IsProduction }}
<em>{{ .Title }}</em>
{{ else }} <!-- not production -->
<a href="{{ .RelPermalink }}"><em>{{ .Title }}</em></a>
{{ end }} <!-- end if-else -->
</li>
{{ end }} <!-- end range -->
</ul>
{{< /wip.inline >}}
💡 | In the highlighted line above:
|
ℹ | I do things to ensure that no WIP[6] article is mentioned anywhere on Infinite Ink other than Infinite Ink’s To-Do and Done Lists👷♀. For example, I specify appropriate build options and the tag list in a WIP article’s front matter is commented out until it is no longer a WIP. |
The shortcodes in this section reside in my layouts/shortcodes/
directory and can be called from any content file
by
using the syntax specified in
the
comment
at the top of the shortcode.
{{/* USAGE: {{< build-date >}} Path: layouts/shortcodes/build-date.html Purpose: display current date */}} {{- now.Format "2006-01-02" -}}
Here it is in action…
page built 2021-03-29 ---------- 👆 generated by build-date shortcode
This build-date shortcode is used in www.ii.com/themeless-gitless-intro-hugo/#_edit_home_html.
The string
2006-01-02
in the above build-date shortcode
specifies the date format.
Note that
2006
, 01
, and 02
are not a random year, month, and day.
Instead they come from the Go
reference date, which is
.
You can remember the reference date with the following mnemonic.
Jan 2 15:04:05 2006 MST 1 2 3 4 5 6 -7
To learn about this, see:
{{/* Usage syntax: {{< omnicomment >}} commented out {{< /omnicomment >}} Forked from: github.com/gohugoio/hugoDocs/blob/master/layouts/shortcodes/todo.html Path: layouts/shortcodes/omnicomment.html Purpose: comment in content file written in any markup language Hugo supports Why 1: no comment translation needed when change file from, e.g., .md to .adoc Why 2: comment out big chunk that contains multiple markup comments[8] */}} {{ if .Inner }}{{ end }}
Note that this is a no-op shortcode.
{{- /* USAGE: {{< years-since YYYY >}} EXAMPLE: {{< years-since 2009 >}} Path: layouts/shortcodes/years-since.html Why: as time goes on, this will still be the approximate number of years since YYYY */ -}} {{- $thisyear := int (now.Format "2006") -}} {{- $thatyear := .Get 0 -}} {{- sub $thisyear $thatyear -}}
‼ | To avoid whitespace problems, I use
the
Go Template trim-whitespace delimiters {{- and
-}}
throughout the above years-since shortcode. |
This years-since shortcode is used in the following sections of Infinite Ink articles.
preamble of Hugo and sitemap.txt
Endnotes section of Commenting Code Cheatsheet
What is Markdown? section of Ordinary and Extraordinary Markdown
The names of Hugo variables (including parameter keys in config files and front matter)…
cannot
contain a dash
character
(-
),[3]
can contain
underscores (_
)
and
alphanumeric characters,
and are sometimes case sensitive.
Variable names that a Hugo user creates
in a layout file — such as
$thisyear
and
$thatyear
— are called custom variables
and
must
start with a dollar sign ($
).
💡 | Bep, Hugo’s lead developer, recommends
all lower case
snake_case — for example
$this_year
and
$that_year — for custom variable names. For more about this, see
discourse.gohugo.io’s
Best practices for naming variables etc. |
{{- /* USAGE: {{< get-leaf-text "filename" >}} EXAMPLE: {{< get-leaf-text "config.py" >}} Path: layouts/shortcodes/get-leaf-text.html Purpose: get content of text file located in current leaf bundle */ -}} {{- $filename := .Get 0 -}} {{- $file := .Page.Resources.GetMatch $filename -}} {{- $file.Content -}}
Below are three examples.
{{< highlight python "hl_lines=15" >}} {{< get-leaf-text "config.py" >}} {{< /highlight >}}
The above example is used in the source of Infinite Ink’s qutebrowser’s Template config.py.
{{< highlight markdown >}} {{< get-leaf-text "mainmatter-get.pdmd" >}} {{< /highlight >}}
Examples 2 and 3 are both used in
the source of Infinite Ink’s
Links and Footnotes in Markdown.
Note that Example 2 uses the
{{%
and %}}
{{<
and >}}
💡 | You are less likely to have a problem
if
get-leaf-text’s
argument (the file name)
does not use one of the
13 file extensions that Hugo interprets as a known Markup language
( This is why I use the file extension
|
The highlight shortcode is discussed in fragment 12 below.
{{- /* USAGE: {{< get-assets-text "filename" >}} EXAMPLE: {{< get-assets-text "qb/config-fragment1.py" >}} Path: layouts/shortcodes/get-assets-text.html Purpose: get content of text file located below assets/text/ */ -}} {{- $file := resources.Get (printf "text/%s" ($.Get 0)) -}} {{- $file.Content -}}
This get-assets-text
shortcode is used in Infinite Ink’s…
{{/* USAGE: {{< html4-get-bundle-image "filename" "alt text" "width" "link" >}} NOTE: parameters 1 & 2 required, parameters 3 & 4 optional EXAMPLE 1: {{< html4-get-bundle-image "gologo.png" "Go Logo" >}} EXAMPLE 2: {{< html4-get-bundle-image "gologo.png" "Go Logo" "50%" >}} EXAMPLE 3: {{< html4-get-bundle-image "gologo.png" "Go Logo" "25%" "https://blog.golang.org/go-brand" >}} PATH: layouts/shortcodes/html4-get-bundle-image.html PURPOSE: get image located in current bundle */}} {{ $filename := .Get 0 }} {{ $alt := .Get 1 }} {{ $width := .Get 2 }} {{ $link := .Get 3 }} {{ $file := .Page.Resources.GetMatch $filename }} {{ with $link }} <a href="{{ . }}"> {{ end }} <img src="{{ $file.RelPermalink }}" alt="{{ $alt }}" {{ with $width }} width="{{ . }}" {{ end }} > {{ if $link }} </a> {{ end }}
Below are three examples.
{{< html4-get-bundle-image "gologo.png" "Go Logo" "25%" "https://blog.golang.org/go-brand" >}}
ℹ |
|
{{/* USAGE: {{% embed-twitter-list listname %}} EXAMPLE: {{% embed-twitter-list zeitgeist %}} Path: layouts/shortcodes/embed-twitter-list.adoc Purpose: Embed heading and Twitter list in a page written in AsciiDoc */}} {{ $listbasename := .Get 0 }} === @nm/lists/{{- $listbasename }} ++++ <a class="twitter-timeline" href="https://twitter.com/nm/lists/{{- $listbasename -}}?ref_src=twsrc%5Etfw">A Twitter List by @nm <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> ++++
This shortcode is used in some Infinite Ink portals, for example in the #zeitgeist Portal.
‼ | This shortcode uses
AsciiDoc
syntax and is meant to be used in an
AsciiDoc (.ad , .adoc , or .asciidoc )
content
source file
and called with
the
{{% and %}}
shortcode delimiters
(not
the
{{< and >}}
shortcode
delimiters). |
Hugo includes built-in shortcodes, which you can read about at:
A good way to learn about writing your own shortcodes is to look at the source code of Hugo’s built-in shortcodes. This code is available on GitHub at:
When I use Hugo’s built-in highlight shortcode and want to highlight lines, I almost always need to look up the syntax, which can look like this:
{{< highlight html "hl_lines=3-5" >}} html code that will be rendered with lines 3, 4, and 5 highlighted {{< /highlight >}}
Or this:
{{< highlight toml "hl_lines=1 12 33" >}} toml code that will be rendered with lines 1, 12, and 33 highlighted {{< /highlight >}}
To learn about the highlight shortcode, see:
github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/shortcodes/highlight.html
gohugo.io/functions/highlight/ - this Hugo function is used in the built-in highlight shortcode (it’s confusing that a Hugo shortcode and a Hugo function are both named “highlight”😕[9])
💡 | To view a list of all possible highlighting languages, such as
html and toml , see
gohugo.io/content-management/syntax-highlighting#list-of-chroma-highlighting-languages. |
More shortcodes, including admonition shortcodes, are available in the Hugo Documentation repository in this directory:
To use
one of the Hugo docs
shortcodes, copy it
to
somewhere below
your
project’s
layout/shortcodes/
directory, for example to one of the following
directories.
layout/shortcodes/ layout/shortcodes/3rdparty/ layout/shortcodes/hugodocs/
💡 | {{ $_hugo_config := `{ "version": 1 }` }} This tells Hugo to process this shortcode the way that Hugo v0.54.0 and earlier do. To learn about this, see the Hugo v0.55.0 release notes. |
In step 13.2.2. Include emoji codes in Infinite Ink’s Hugo Tutorial, I wrote about the following emoji codes.
:man_astronaut: :star: :woman_astronaut: :bulb: :wrench: :sparkles:
Since I have enableEmoji: true
in my config.yaml
,
Hugo
emojifies
the above strings
in a content file
to:
👨🚀 ⭐ 👩🚀 💡 🔧 ✨
So how do you write about these strings without Hugo emojifying them? There is more than one way to escape emoji codes. The way I do it is to use an HTML entity for one of the colons in each emoji code. For example:
:man_astronaut: :star: :woman_astronaut: :bulb: :wrench: :sparkles:
ℹ | This trick works…
|
In a Hugo content file, shortcodes are
called using either
the delimiters
{{<
and >}}
or
the delimiters
{{%
and %}}
.
If you want to write about shortcodes, as I did in fragments 3, 4, 5, 6, 7, 8, 9, 10, 11, and 12 above, you need to escape these strings from being interpreted as being part of actual shortcode calls. Hugo uses the following syntax to escape these delimiters in a content source file:
{{</* something */>}} {{%/* something */%}}
If you use the above delimiters in a content file, they will be rendered in the destination file as:
{{< something >}} {{% something %}}
And these strings will not be interpreted as shortcode calls.
ℹ | I learned about escaping Hugo shortcodes in the discourse.gohugo.io thread How is the Hugo Doc site showing shortcodes in code blocks? |
To comment out a shortcode
in a Markdown
(.markdown
,
.md
,
or
.mdown
)
content
source
file,
you can do this:
<!-- { {< shortcode call >}} -->
Notice the space between the two leading curly braces. Actually any character between the curly braces will denature the shortcode. For example, I like to use an exclamation mark because it is more noticeable than a space character:
<!-- {!{< shortcode call >}} -->
To comment out a shortcode in
an
AsciiDoc
(.ad
, .adoc
, or .asciidoc
)
content
source
file, you can do this:
//// {!{< shortcode call >}} ////
Or this:
// {!{< shortcode call >}}
💡 | If you really want it to be noticeable that a shortcode is commented out, you could use !!! rather than ! to denature a shortcode call. |
To learn about configuring Hugo, see gohugo.io/getting-started/configuration/.
I use the
following nested map, which is also known as a table,[10]
in my config.yaml
because…
I want date
and publishDate
to mean the same thing
and
if no date is specified, I want
a
reasonably sane date (:fileModTime
) to be used
rather than
Hugo’s default date, which is
frontmatter:
date:
- publishDate
- :filename
- date
- :fileModTime
publishDate:
- publishDate
- :filename
- date
- :fileModTime
lastmod:
- lastmod
- :fileModTime
For more about this, see Stackoverflow.com’s Hugo Date vs PublishDate, which includes a post by n m (i.e. me😄).
The TOML syntax for this table is in fragment 17 below.
Starting with Hugo
v0.60.0[11],
the way to override Hugo’s default markup settings
is to use a markup
nested map
in your project’s config file.
Here is
an excerpt of
Infinite Ink’s config.yaml
:
markup:
goldmark:
renderer:
unsafe: true # default is false
highlight:
style: tango # default is monokai
Note that…
Without the
unsafe: true
setting,
which is the highlighted line in this YAML fragment,
raw HTML
in a
Goldmark-flavored
Markdown source file will be replaced
with
in the
markdownified[12]
destination file.
A nested-map markup
setting like this does not work in the front matter of a content file.
These variables
must be set globally.
The colors and italics in this YAML fragment are thanks to tango-style syntax highlighting.
💡 | To view examples of
all
possible values
of
|
For more about this, see the following.
gohugo.io:
ii.com:
The TOML syntax for this markup
nested map, which is also known as a table, is
at the bottom of the
next fragment.
When I use a config.toml
,
I
like to
include
comments like the
three
highlighted
lines
below.
### ---> Put tables below non-tables <--- ###
# next from “One-off shortcodes” above
enableInlineShortcodes = true
# next from fragment 13 above
enableEmoji = true
### ---> Put TOML tables below here <--- ###
# next from fragment 15 above
[frontmatter]
date = ["publishDate", ":filename", "date", ":fileModTime"]
publishDate = ["publishDate", ":filename", "date", ":fileModTime"]
lastmod = ["lastmod", ":fileModTime"]
# next from fragment 16 above
[markup]
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
[markup.highlight]
style = "tango"
### ---> Put tables below non-tables <--- ###
I use these
config.toml
.😩
To learn about TOML, which is an alternative to YAML, see:
-
) is “hyphen-minus,” but its proper name is rarely used. Instead it is usually referred to as “dash,” “hyphen,” or “minus.” Details are at wikipedia.org’s Hyphen-minus..asciidoc
could be any of the 13 content file extensions that are known to Hugo (.ad
, .adoc
, .asciidoc
, .htm
, .html
, .markdown
, .md
, .mdown
, .mmark
, .pandoc
, .pdc
, .org
, or .rst
).hugo
and site
are context-free by noticing that they do not have a leading dot (.
). To learn more about these two global functions, see the Hugo v0.53 release notes, especially the relevant GitHub commit and GitHub issues.draft: true
. Only the titles of the WIP articles that are not drafts are listed when I publish Infinite Ink’s To-Do and Done Lists👷♀ page.