hugo/docs/content/extras/shortcodes.md

414 lines
14 KiB
Markdown
Raw Normal View History

---
aliases:
- /doc/shortcodes/
lastmod: 2016-02-03
date: 2013-07-01
menu:
main:
parent: extras
next: /extras/highlighting
prev: /extras/scratch
title: Shortcodes
toc: true
---
Hugo uses Markdown for its simple content format. However, there are a lot
of things that Markdown doesnt support well.
We are unwilling to accept being constrained by our simple format. Also
unacceptable is writing raw HTML in our Markdown every time we want to include
unsupported content such as a video. To do so is in complete opposition to the
intent of using a bare-bones format for our content and utilizing templates to
apply styling for display.
To avoid both of these limitations, Hugo created shortcodes.
A shortcode is a simple snippet inside a content file that Hugo will render
using a predefined template. Note that shortcodes will not work in template
files---if you need a functionality like that in a template, you most likely
want a [partial template](/templates/partials/) instead.
Another benefit is, you can update your shortcode with any related new classes or
techniques, and upon generation, Hugo will easily merge in your changes. You
avoid a possibly complicated search and replace operation.
## Using a shortcode
In your content files, a shortcode can be called by using the `{{%/* name parameters
*/%}}` form. Shortcode parameters are space delimited. Parameters with spaces
can be quoted.
The first word is always the name of the shortcode. Parameters follow the name.
Depending upon how the shortcode is defined, the parameters may be named,
positional or both (although you can't mix parameter types in a single call).
The format for named parameters models that of HTML with the format
`name="value"`.
Some shortcodes use or require closing shortcodes. Like HTML, the opening and closing
shortcodes match (name only), the closing being prepended with a slash.
Example of a paired shortcode:
{{</* highlight go */>}} A bunch of code here {{</* /highlight */>}}
The examples above use two different delimiters, the difference being the `%` and the `<` character:
### Shortcodes with Markdown
The `%` characters indicates that the shortcode's inner content needs further processing by the page's rendering processor (i.e. Markdown), needed to get the **bold** text in the example below:
{{%/* myshortcode */%}}Hello **World!**{{%/* /myshortcode */%}}
### Shortcodes without Markdown
The `<` character indicates that the shortcode's inner content doesn't need any further rendering, this will typically be pure HTML:
{{</* myshortcode */>}}<p>Hello <strong>World!</strong></p>{{</* /myshortcode */>}}
## Built-in Shortcodes
Hugo ships with a set of predefined shortcodes.
### highlight
This shortcode will convert the source code provided into syntax highlighted
HTML. Read more on [highlighting](/extras/highlighting/).
#### Usage
`highlight` takes exactly one required parameter of _language_ and requires a
closing shortcode.
#### Example
{{</* highlight html */>}}
<section id="main">
<div>
<h1 id="title">{{ .Title }}</h1>
{{ range .Data.Pages }}
{{ .Render "summary"}}
{{ end }}
</div>
</section>
{{</* /highlight */>}}
#### Example Output
<span style="color: #f92672">&lt;section</span> <span style="color: #a6e22e">id=</span><span style="color: #e6db74">&quot;main&quot;</span><span style="color: #f92672">&gt;</span>
<span style="color: #f92672">&lt;div&gt;</span>
<span style="color: #f92672">&lt;h1</span> <span style="color: #a6e22e">id=</span><span style="color: #e6db74">&quot;title&quot;</span><span style="color: #f92672">&gt;</span>{{ .Title }}<span style="color: #f92672">&lt;/h1&gt;</span>
{{ range .Data.Pages }}
{{ .Render &quot;summary&quot;}}
{{ end }}
<span style="color: #f92672">&lt;/div&gt;</span>
<span style="color: #f92672">&lt;/section&gt;</span>
### figure
`figure` is simply an extension of the image capabilities present with Markdown.
`figure` provides the ability to add captions, CSS classes, alt text, links etc.
#### Usage
`figure` can use the following named parameters:
* src
* link
* title
* caption
* class
* attr (attribution)
* attrlink
* alt
#### Example
{{</* figure src="/media/spf13.jpg" title="Steve Francia" */>}}
#### Example output
<figure>
<img src="/media/spf13.jpg" />
<figcaption>
<h4>Steve Francia</h4>
</figcaption>
</figure>
### ref, relref
These shortcodes will look up the pages by their relative path (e.g.,
`blog/post.md`) or their logical name (`post.md`) and return the permalink
(`ref`) or relative permalink (`relref`) for the found page.
`ref` and `relref` also make it possible to make fragmentary links that work
for the header links generated by Hugo.
Read more on [cross-references]({{% ref "extras/crossreferences.md" %}}).
#### Usage
`ref` and `relref` take exactly one required parameter of _reference_.
#### Example
[Neat]({{</* ref "blog/neat.md" */>}})
[Who]({{</* relref "about.md#who" */>}})
If the page exists in multiple [output formats]({{< relref "extras/output-formats.md" >}}), `ref` or `relref` can be used with a output format name:
[Neat]({{</* ref "blog/neat.md" "amp" */>}})
#### Example Output
Assuming that standard Hugo pretty URLs are turned on.
<a href="/blog/neat">Neat</a>
<a href="/about/#who:c28654c202e73453784cfd2c5ab356c0">Who</a>
### Twitter
You want to include a single tweet into your blog post? Everything you need is the URL of the tweet, e.g.:
* https://twitter.com/spf13/status/666616452582129664
Pass the tweet's ID from the URL as parameter to the shortcode as shown below:
{{</* tweet 666616452582129664 */>}}
### YouTube
This shortcode embeds a responsive video player for [YouTube](https://www.youtube.com/) videos. Only the ID of the video is required, e.g.:
* https://www.youtube.com/watch?v=w7Ft2ymGmfc
Copy the ID from behind `v=` and pass it to the shortcode:
{{</* youtube w7Ft2ymGmfc */>}}
Furthermore, you can autoplay the embedded video by setting the `autoplay` parameter to true. Remember that you can't mix named and unnamed parameters. Assign the yet unnamed video id to the parameter `id` like below too.
{{</* youtube id="w7Ft2ymGmfc" autoplay="true" */>}}
### Vimeo
Adding a video from [Vimeo](https://vimeo.com/) is equivalent to the YouTube shortcode above. Extract the ID from the URL, e.g.:
* https://vimeo.com/channels/staffpicks/146022717
and pass it to the shortcode:
{{</* vimeo 146022717 */>}}
### GitHub gists
Including code snippets with GitHub gists while writing a tutorial is common situation bloggers face. With a given URL of the gist, e.g.:
* https://gist.github.com/spf13/7896402
pass the owner and the ID of the gist to the shortcode:
{{</* gist spf13 7896402 */>}}
If the gist contains several files and you want to quote just one of them, you can pass the filename (quoted) as an optional third argument:
{{</* gist spf13 7896402 "img.html" */>}}
### Speaker Deck
To embed slides from [Speaker Deck](https://speakerdeck.com/), click on "&lt;&#8239;/&gt;&nbsp;Embed" (under Share right next to the template on Speaker Deck) and copy the URL, e.g.:
<script async class="speakerdeck-embed" data-id="4e8126e72d853c0060001f97" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
Extract the value from the field `data-id` and pass it to the shortcode:
{{</* speakerdeck 4e8126e72d853c0060001f97 */>}}
### Instagram
If you'd like to embed photo from [Instagram](https://www.instagram.com/), all you need is photo ID from the URL, e. g.:
* https://www.instagram.com/p/BMokmydjG-M/
Pass it to the shortcode:
{{</* instagram BMokmydjG-M */>}}
Optionally, hide caption:
{{</* instagram BMokmydjG-M hidecaption */>}}
## Creating your own shortcodes
To create a shortcode, place a template in the layouts/shortcodes directory. The
template name will be the name of the shortcode.
In creating a shortcode, you can choose if the shortcode will use _positional
parameters_, or _named parameters_, or _both_. A good rule of thumb is that if a
shortcode has a single required value in the case of the `youtube` example below,
then positional works very well. For more complex layouts with optional
parameters, named parameters work best. Allowing both types of parameters is
useful for complex layouts where you want to set default values that can be
overridden.
**Inside the template**
To access a parameter by position, the `.Get` method can be used:
{{ .Get 0 }}
To access a parameter by name, the `.Get` method should be utilized:
{{ .Get "class" }}
`with` is great when the output depends on a parameter being set:
{{ with .Get "class"}} class="{{.}}"{{ end }}
`.Get` can also be used to check if a parameter has been provided. This is
most helpful when the condition depends on either one value or another...
or both:
{{ or .Get "title" | .Get "alt" | if }} alt="{{ with .Get "alt"}}{{.}}{{else}}{{.Get "title"}}{{end}}"{{ end }}
If a closing shortcode is used, the variable `.Inner` will be populated with all
of the content between the opening and closing shortcodes. If a closing
shortcode is required, you can check the length of `.Inner` and provide a warning
to the user.
A shortcode with `.Inner` content can be used without the inline content, and without the closing shortcode, by using the self-closing syntax:
{{</* innershortcode /*/>}}
The variable `.Params` contains the list of parameters in case you need to do
more complicated things than `.Get`. It is sometimes useful to provide a
flexible shortcode that can take named or positional parameters. To meet this
need, Hugo shortcodes have a `.IsNamedParams` boolean available that can be used
such as `{{ if .IsNamedParams }}...{{ else }}...{{ end }}`. See the
`Single Flexible Example` below for an example.
You can also use the variable `.Page` to access all the normal [Page Variables](/templates/variables/).
A shortcodes can be nested. In a nested shortcode you can access the parent shortcode context with `.Parent`. This can be very useful for inheritance of common shortcode parameters from the root.
## Single Positional Example: youtube
{{</* youtube 09jf3ow9jfw */>}}
Would load the template /layouts/shortcodes/youtube.html
<div class="embed video-player">
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/{{ index .Params 0 }}" allowfullscreen frameborder="0">
</iframe>
</div>
This would be rendered as:
<div class="embed video-player">
<iframe class="youtube-player" type="text/html"
width="640" height="385"
src="http://www.youtube.com/embed/09jf3ow9jfw"
allowfullscreen frameborder="0">
</iframe>
</div>
## Single Named Example: image with caption
{{</* img src="/media/spf13.jpg" title="Steve Francia" */>}}
Would load the template /layouts/shortcodes/img.html
<!-- image -->
<figure {{ with .Get "class" }}class="{{.}}"{{ end }}>
{{ with .Get "link"}}<a href="{{.}}">{{ end }}
<img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}"{{ end }} />
{{ if .Get "link"}}</a>{{ end }}
{{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
<figcaption>{{ if isset .Params "title" }}
<h4>{{ .Get "title" }}</h4>{{ end }}
{{ if or (.Get "caption") (.Get "attr")}}<p>
{{ .Get "caption" }}
{{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
{{ .Get "attr" }}
{{ if .Get "attrlink"}}</a> {{ end }}
</p> {{ end }}
</figcaption>
{{ end }}
</figure>
<!-- image -->
Would be rendered as:
<figure >
<img src="/media/spf13.jpg" />
<figcaption>
<h4>Steve Francia</h4>
</figcaption>
</figure>
## Single Flexible Example: vimeo with defaults
{{</* vimeo 49718712 */>}}
{{</* vimeo id="49718712" class="flex-video" */>}}
Would load the template /layouts/shortcodes/vimeo.html
{{ if .IsNamedParams }}
<div class="{{ if .Get "class" }}{{ .Get "class" }}{{ else }}vimeo-container{{ end }}">
<iframe src="//player.vimeo.com/video/{{ .Get "id" }}" allowfullscreen></iframe>
</div>
{{ else }}
<div class="{{ if len .Params | eq 2 }}{{ .Get 1 }}{{ else }}vimeo-container{{ end }}">
<iframe src="//player.vimeo.com/video/{{ .Get 0 }}" allowfullscreen></iframe>
</div>
{{ end }}
Would be rendered as:
<div class="vimeo-container">
<iframe src="//player.vimeo.com/video/49718712" allowfullscreen></iframe>
</div>
<div class="flex-video">
<iframe src="//player.vimeo.com/video/49718712" allowfullscreen></iframe>
</div>
## Paired Example: Highlight
*Hugo already ships with the `highlight` shortcode*
{{</* highlight html */>}}
<html>
<body> This HTML </body>
</html>
{{</* /highlight */>}}
The template for this utilizes the following code (already included in Hugo)
{{ .Get 0 | highlight .Inner }}
And will be rendered as:
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f92672">&lt;html&gt;</span>
<span style="color: #f92672">&lt;body&gt;</span> This HTML <span style="color: #f92672">&lt;/body&gt;</span>
<span style="color: #f92672">&lt;/html&gt;</span>
</pre></div>
Please notice that this template makes use of a Hugo-specific template function
called `highlight` which uses Pygments to add the highlighting code.
## Simple Single-word Example: Year
Let's assume you would like to have a shortcode to be replaced by the current year in your Markdown content files, for a license or copyright statement. Calling a shortcode like this:
{{</* year */>}}
... would load your one-line template ``/layouts/shortcodes/year.html``, which contains:
{{ .Page.Now.Year }}
More shortcode examples can be found at [spf13.com](https://github.com/spf13/spf13.com/tree/master/layouts/shortcodes).