Writing a New Topic

This page shows how to create a new Istio documentation topic.

Before you begin

You first need to create a fork of the Istio documentation repository as described in Working with GitHub.

Choosing a page type

As you prepare to write a new topic, think about which of these page types is the best fit for your content:

ConceptA concept page explains some significant aspect of Istio. For example, a concept page might describe the Mixer's configuration model and explain some of its subtleties. Typically, concept pages don't include sequences of steps, but instead provide links to tasks that do.
ReferenceA reference page provides exhaustive lists of things like API parameters, command-line options, configuration settings, and procedures.
ExamplesAn example page describes a fully working stand-alone example highlighting a particular set of features. Examples must have easy to follow setup and usage instructions so users can quickly run the sample themselves and experiment with changing the example to explore the system.
TaskA task page shows how to do a single thing, typically by giving a short sequence of steps. Task pages have minimal explanation, but often provide links to conceptual topics that provide related background and knowledge.
SetupA setup page is similar to a task page, except that it is focused on installation activities.
Blog PostA blog post is a timely article on Istio or products and technologies related to it.

Naming a topic

Choose a title for your topic that has the keywords you want search engines to find. Create a filename for your topic that uses the words in your title, separated by hyphens, all in lower case.

Updating front matter

Every documentation file needs to start with front matter. The front matter is a block of YAML that is between triple-dashed lines at the top of each file. Here’s the chunk of front matter you should start with:

---
title: <title>
description: <description>
weight: <weight>
keywords: [keyword1,keyword2,...]
---

Copy the above at the start of your new markdown file and update the information fields. The available front matter fields are:

FieldDescription
titleThe short title of the page
subtitleAn optional subtitle which gets displayed below the main title
descriptionA one-line description of what the page is about
iconAn optional path to an image file which gets displayed next to the main title
weightAn integer used to determine the sort order of this page relative to other pages in the same directory
keywordsAn array of keywords describing the page, used to create the web of See Also links
draftWhen true, prevents the page from showing up in any navigation area
aliasesSee Renaming, moving, or deleting pages below for details on this item
skip_tocSet this to true to prevent the page from having a table of contents generated for it
skip_seealsoSet this to true to prevent the page from having a “See also” section generated for it
force_inline_tocSet this to true to force the generated table of contents to be inserted inline in the text instead of in a sidebar

There are a few more front matter fields available specifically for blog posts:

FieldDescription
publishdateDate of the post’s publication
attributionOptional name of the post’s author
twitterOptional Twitter of the post’s author

Adding images

Put image files in the same directory as your markdown file. The preferred image format is SVG. Within markdown, use the following sequence to add the image:

{{< image width="75%" ratio="69.52%"
    link="./myfile.svg"
    alt="Alternate text to display when the image is not available"
    title="A tooltip displayed when hovering over the image"
    caption="A caption displayed under the image"
    >}}

The width, ratio, link and caption values are required. If the title value isn’t supplied, it’ll default to the same as caption. If the alt value is not supplied, it’ll default to title or if that’s not defined, to caption.

width represents the percentage of space used by the image relative to the surrounding text. ratio must be manually calculated using (image height / image width) * 100.

Adding icons & emojis

You can embed some common icons in your content using:

{{< warning_icon >}}
{{< idea_icon >}}

which look like Warning and Bulb

In addition, you can embed an emoji in your content using a sequence such as :sailboat: which looks like ⛵️. Here’s a handy cheat sheet of the supported emojis.

Linking to other pages

There are three types of links that can be included in documentation. Each uses a different way to indicate the link target:

  1. Internet Link. You use classic URL syntax, preferably with the HTTPS protocol, to reference files on the Internet:

    [see here](https://mysite/myfile.html)
  2. Relative Link. You use relative links that start with a period to reference any content that is at the same level as the current file, or below within the hierarchy of the site:

    [see here](./adir/anotherfile.html)
  3. Absolute Link. You use absolute links that start with a / to reference content outside of the current hierarchy:

    [see here](/docs/adir/afile/)

GitHub

There are a few ways to reference files from GitHub:

  • {{< github_file >}} is how you reference individual files in GitHub such as yaml files. This produces a link to https://raw.githubusercontent.com/istio/istio/...

    [liveness]({{< github_file >}}/samples/health-check/liveness-command.yaml)
  • {{< github_tree >}} is how you reference a directory tree in GitHub. This produces a link to https://github.com/istio/istio/tree/...

    [httpbin]({{< github_tree >}}/samples/httpbin)
  • {{< github_blob >}} is how you reference a file in GitHub sources. This produces a link to https://github.com/istio/istio/blob/...

    [RawVM MySQL]({{< github_blob >}}/samples/rawvm/README.md)

The above annotations yield links to the appropriate branch in GitHub, relative to the branch that the documentation is currently targeting. If you need to manually construct a URL, you can use the sequence {{< branch_name >}} to get the name of the currently targeted branch.

Embedding preformatted blocks

You can embed blocks of preformatted content using the text sequence:

{{< text plain >}}
func HelloWorld() {
  fmt.Println("Hello World")
}
{{< /text >}}

The above produces this kind of output:

func HelloWorld() {
  fmt.Println("Hello World")
}

You must indicate the syntax of the content in the preformatted block. Above, the block was marked as being plain indicating that no syntax coloring should be applied to the block. Consider the same block, but now annotated with the Go language syntax:

{{< text go >}}
func HelloWorld() {
  fmt.Println("Hello World")
}
{{< /text >}}

which renders as:

func HelloWorld() {
  fmt.Println("Hello World")
}

You can use plain, markdown, yaml, json, java, javascript, c, cpp, csharp, go, html, protobuf, perl, docker, and bash.

Commands and command output

When showing one or more bash command-lines, you start each command-line with a $:

{{< text bash >}}
$ echo "Hello"
{{< /text >}}

which produces:

$ echo "Hello"

You can have as many command-lines as you want, but only one chunk of output is recognized.

{{< text bash >}}
$ echo "Hello" >file.txt
$ cat file.txt
Hello
{{< /text >}}

which yields:

$ echo "Hello" >file.txt
$ cat file.txt
Hello

You can also use line continuation in your command-lines:

{{< text bash >}}
$ echo "Hello" \
    >file.txt
$ echo "There" >>file.txt
$ cat file.txt
Hello
There
{{< /text >}}

which looks like:

$ echo "Hello" \
    >file.txt
$ echo "There" >>file.txt
$ cat file.txt
Hello
There

By default, the output section is handled using the plain syntax. If the output uses a well-known syntax, you can specify it and get proper coloring for it. This is particularly common for YAML or JSON output:

{{< text bash json >}}
$ kubectl -n istio-system logs $(kubectl -n istio-system get pods -l istio-mixer-type=telemetry -o jsonpath='{.items[0].metadata.name}') mixer | grep \"instance\":\"newlog.logentry.istio-system\"
{"level":"warn","ts":"2017-09-21T04:33:31.249Z","instance":"newlog.logentry.istio-system","destination":"details","latency":"6.848ms","responseCode":200,"responseSize":178,"source":"productpage","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.291Z","instance":"newlog.logentry.istio-system","destination":"ratings","latency":"6.753ms","responseCode":200,"responseSize":48,"source":"reviews","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.263Z","instance":"newlog.logentry.istio-system","destination":"reviews","latency":"39.848ms","responseCode":200,"responseSize":379,"source":"productpage","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.239Z","instance":"newlog.logentry.istio-system","destination":"productpage","latency":"67.675ms","responseCode":200,"responseSize":5599,"source":"ingress.istio-system.svc.cluster.local","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.233Z","instance":"newlog.logentry.istio-system","destination":"ingress.istio-system.svc.cluster.local","latency":"74.47ms","responseCode":200,"responseSize":5599,"source":"unknown","user":"unknown"}
{{< /text >}}

which gives:

$ kubectl -n istio-system logs $(kubectl -n istio-system get pods -l istio-mixer-type=telemetry -o jsonpath='{.items[0].metadata.name}') mixer | grep \"instance\":\"newlog.logentry.istio-system\"
{"level":"warn","ts":"2017-09-21T04:33:31.249Z","instance":"newlog.logentry.istio-system","destination":"details","latency":"6.848ms","responseCode":200,"responseSize":178,"source":"productpage","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.291Z","instance":"newlog.logentry.istio-system","destination":"ratings","latency":"6.753ms","responseCode":200,"responseSize":48,"source":"reviews","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.263Z","instance":"newlog.logentry.istio-system","destination":"reviews","latency":"39.848ms","responseCode":200,"responseSize":379,"source":"productpage","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.239Z","instance":"newlog.logentry.istio-system","destination":"productpage","latency":"67.675ms","responseCode":200,"responseSize":5599,"source":"ingress.istio-system.svc.cluster.local","user":"unknown"}
{"level":"warn","ts":"2017-09-21T04:33:31.233Z","instance":"newlog.logentry.istio-system","destination":"ingress.istio-system.svc.cluster.local","latency":"74.47ms","responseCode":200,"responseSize":5599,"source":"unknown","user":"unknown"}

You can specify an optional third value which controls the name that the browser will use when the user chooses to download the file. For example:

{{< text go plain "hello.go" >}}
func HelloWorld() {
  fmt.Println("Hello World")
}
{{< /text >}}

If you don’t specify a third value, then the download name is derived automatically based on the name of the current page.

If your code block references a file from Istio’s GitHub repo, you can surround the relative path name of the file with a pair of @ symbols. These indicate the path should be rendered as a link to the file from the current branch. For example:

{{< text bash >}}
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-v3.yaml@
{{< /text >}}

This will be rendered as:

$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-v3.yaml@

Files and snippets

It is often useful to display a file or a portion of a file. You can annotate a text file to create named snippets within the file by using the $snippet and $endsnippet annotations. For example, you could have a text file that looks like this:

BEFORE

# $snippet SNIP1
This is snippet 1
# $endsnippet

# $snippet SNIP2
This is snippet 2
# $endsnippet

AFTER

and in your markdown file, you can then reference a particular snippet with:

{{< text_file file="examples/snippet_example.txt" syntax="plain" snippet="SNIP1" >}}

where file specifies the relative path of the text file within the documentation repo, syntax specifies the syntax to use for syntax coloring (use plain for generic text), and snippet specifies the name of the snippet.

The above snippet produces this output:

This is snippet 1

If you don’t specify a snippet name, then the whole file will be inserted instead.

You can specify an optional downloadas attribute to control the name that the browser will use when the user chooses to download the file. For example:

{{< text_file file="examples/snippet_example.txt" syntax="plain" downloadas="foo.txt" >}}

If you don’t specify the downloadas attribute, then the download name is taken from the file attribute instead.

A common thing to do is to copy an example script or yaml file from GitHub into the documentation repo and then use snippets within the file to produce examples in the documentation. To pull in annotated files from GitHub, add the needed entries at the end of the script scripts/grab_reference_docs.sh in the documentation repo.

Dynamic content

You can dynamically pull in an external file and display its content as a preformatted block. This is handy to display a configuration file or a test file. To do so, you use a statement such as:

{{< text_dynamic url="https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/policy/mixer-rule-ratings-ratelimit.yaml" syntax="yaml" >}}

which produces the following result:

If the file is from a different origin site, CORS should be enabled on that site. Note that the GitHub raw content site (raw.githubusercontent.com) may be used here.

You can specify an optional downloadas attribute to control the name that the browser will use when the user chooses to download the file. For example:

{{< text_dynamic url="https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/policy/mixer-rule-ratings-ratelimit.yaml" syntax="yaml" downloadas="foo.yaml" >}}

If you don’t specify the downloadas attribute, then the download name is taken from the url attribute instead.

Renaming, moving, or deleting pages

If you move pages around or delete them completely, you should make sure existing links users may have to those pages continue to work. You do this by adding aliases which will cause the user to be redirected automatically from the old URL to a new URL.

In the page that is the target of the redirect (where you’d like users to land), you simply add the following to the front-matter:

aliases:
    - <url>

For example

---
title: Frequently Asked Questions
description: Questions Asked Frequently.
weight: 12
aliases:
    - /faq
---

With the above in a page saved as _help/faq.md, the user will be able to access the page by going to istio.io/help/faq/ as normal, as well as istio.io/faq/.

You can also add many redirects like so:

---
title: Frequently Asked Questions
description: Questions Asked Frequently.
weight: 12
aliases:
    - /faq
    - /faq2
    - /faq3
---

See also

Explains the dos and donts of writing Istio documentation.

Shows you how to use GitHub to work on Istio documentation.