Skip to main content

Documentation Style Guide

[edit on GitHub]

The Chef reference documentation is written using Markdown and built with Hugo.

We recommend that you use the conventions described in this guide when contributing to the Chef reference documentation.

The HTML version of the doc set can be found at


To build the docs, run the command:

make serve

TOML Front Matter

Each page starts with TOML front matter which contains metadata about the page and places it properly in the left navigation menu. Below is the TOML front matter for this page which you can use as a reference. Contact the Docs Team if you have any questions about properly formatting TOML front matter.

title = "Documentation Style Guide"
description = "DESCRIPTION"
draft = false
gh_repo = "chef-web-docs"
aliases = "/style_guide.html"

    title = "Docs Style Guide"
    identifier = "overview/community/ Docs Style Guide"
    parent = "overview/community"
    weight = 40

Page Metadata


The title of the page. This will appear at the top of the page.


Set draft to true if you don’t want Hugo to build the page.


Add an alias if you want Hugo to automatically redirect the user from another page to the page you are writing.


product is a list of Chef products that are relevant to a page. This list is used to facet search results in our documentation search by the product. Each section of the documentation has a default product parameter configured using Front Matter Cascade, however you may want add a product if a page references more than one Chef product. For example, if a page in the Chef InSpec documentation describes passing data to Chef Automate, you may want to add product = ["inspec", "automate"] to the page frontmatter.

Relevant values:

  • automate
  • desktop
  • client
  • server
  • habitat
  • inspec
  • workstation

The title of the page as it would appear in the left navigation menu.

The identifier of the page that you are writing. Each identifier must be unique.

The convention we’ve adopted is to use the identifier of the page’s parent, a forward slash, then the page file, a space, and then the page title.

For example, this page’s parent identifier is overview/community, the page file is and the page title is Docs Style Guide, so the full page identifier is overview/community/ Docs Style Guide

The menu identifier of the page’s parent.

The convention we’ve adopted is to append the different menu levels together, separated by a forward slash, and starting with the highest level. For example, this page is nested under Overview and then Community, so the page’s parent identifier is overview/community.

The rank that the page will appear in the menu, incremented by 10. Higher numbers are lower in the menu.

Section Headings

The following sections describe the section heading pattern that Chef is using for topic titles, H1s, H2s, H3s and H4s.

As a general rule, limit the number of heading levels to no more than two within a topic. There can be exceptions, especially if the document is very large, but remember that HTML TOC structures usually have width limitations (on the display side) and the more structure within a TOC, the harder it can be for users to figure out what’s in it.

Unless the topics are about installing things or about API endpoints, the headings should never wrap. Keep them to a single line.

The width of heading adornment must be at least equal to the length of the text in the heading and the same width for headings is used everywhere. Consistent width is preferred.


The H1 heading is reserved for the page title which is created by the Hugo page template. The Markdown file text should not have any H1 headings.


Use two hash characters (##) before the heading name to indicate H2 headings:

## H2 Heading

This is the body.


Use three hash characters (###) before the heading name to indicate H3 headings:

### H3 Heading

This is the body.


Use four hash characters (####) before the heading name to indicate H4 headings:

#### H4 Heading

This is the paragraph.

Other headings

If you need more than four heading levels, use bold emphasis and then white space to make the heading text stand out and separate the heading from the content:

**heading name goes here**         # bold emphasis
                                  # blank line
content, as normally authored.


The following sections describe conventions for lists and tables in Chef docs.

Bulleted Lists

Bulleted lists break up text blocks and draw attention to a group of items:

- text goes here
- text goes here

    - subitem text
    - subitem text

- text goes here
- text goes here

Use the dash symbol (-) for bulleted lists, even though Hugo supports other symbols. Indent nested list items by four spaces.

Numbered Lists

Numbered lists are created like this:

1. text goes here
1. text goes here
1. text goes here

    1. sub-list text
    1. sub-list text

1. text goes here

Start each ordered list item with the number 1 (1.). Hugo will generate the correct sequence of numbers in an ordered list regardless of the numbers that you use. Only using “1.” will save you from having to re-number items if you add or remove an item later.

Definition Lists

Definition lists are used to show the options available to a command line tool:

: Show only the names of modified files.

: Show only the names of files with a status of `Added`, `Deleted`, `Modified`, or `Type Changed`.


Create tables in Markdown like this:

Chef Software | Description
Infra Client | Awesome
Infra Server | Fun
Habitat | Super cool

Use three or more hyphens (—) to separate each column’s header from the content of the table. Separate columns with a vertical bar or pipe (|).

Inline Markup

Adding emphasis within text strings can be done using bold and code strings.


Use two asterisks (*) to mark a text string as bold:

**text goes here**

Code Strings

Sometimes the name of a method or database field needs to be used inline in a paragraph. Use one back quote to mark certain strings as code within a regular string of text:

code goes here

To make a link in Markdown put the page title in square brackets followed by the link in parentheses. For example this:

[Ruby Programming Language](

will produce this:

Ruby Programming Language

External links requires an HTTP address.

Code Blocks

Code blocks are used to show code samples, such as those for Ruby, JSON, and command-line strings.


Use this approach to show code blocks that use Ruby:

default['apache']['dir']          = '/etc/apache2'
default['apache']['listen_ports'] = [ '80', '443' ]


Use this approach to show code blocks that use any type of shell command, such as for Knife or the Chef Infra Client or for any other command-line example that may be required:

$ knife data bag create admins

Javascript (and JSON)

Use this approach to show code blocks that use any type of JavaScript, including any JSON code sample:

  "id": "charlie",
  "uid": 1005,
  "comment":"Crazy Charlie"


Literals should be used sparingly, but sometimes there is a need for a block of text that doesn’t work in a fenced code block, such as showing a directory structure, basic syntax, or pseudocode. To make a literal code block, indent the text by four spaces:

    a block of literal text indented three spaces
    with more
    text as required to
    complete the block of text.

Repeating Text Blocks

Chef docs uses shortcodes to maintain text that appears in more than one location and must be consistent in every location.

Writing a shortcode

All shortcode files are written in Markdown and stored in the layouts/shortcodes directory in the chef-web-docs repo.

Adding a Shortcode to a Page

To include a shortcode in a Markdown file, wrap the name of the shortcode file, without the file type suffix, in double curly braces and percent characters. For example, if you wanted to add the shortcode to a page, add the following text to the Markdown page:

{{% chef %}}

Notes and Warnings

In general, notes and warnings are not the best way to present important information. Before using them ask yourself how important the information is. If you want the information to be returned in a search result, then it is better for the information to have its own topic or section heading. Notes and warnings have a different color than the surrounding text so they can be easily spotted within a doc. If notes and warnings must be used, the approach for using them is as follows.

Notes and warnings are generated by bracketing the text of the note or warning in info, warning or danger shortcodes.


{{< note >}}
This is a note.
{{< /note >}}

What a note looks like after it’s built:


This is a note.


Use sparingly so that when the user sees a warning it registers appropriately:

{{< warning >}}
This is a warning.
{{< /warning >}}

What a warning looks like after it’s built:


This is a warning.


Danger should be used rarely and only when there are serious consequences for the user:

{{< danger >}}
This is a danger block.
{{< /danger >}}

This is what a danger block looks like after it’s built:


This is a danger block.


You have two options for formatting images in Hugo:

  • Markdown syntax
  • the figure shortcode

Markdown syntax

To add an image in Markdown, use an exclamation point, square brackets around the alt text, parenthesis around the path to the image file starting in the static directory, and then optional hover text. For example:

![Alt Text](/path/to/img.png "Optional Title")

Figure Shortcode

The figure shortcode allows you to specify the image size and include a title, a caption, and alternate text.

SVG images should be formatted using the figure shortcode.

{{< figure src="/images/chef-logo.svg" title="Chef Logo" height="100" width="150" >}}

Which looks like this:

Chef Logo

Raster images should be 96 dpi and no larger than 600 pixels wide. This helps ensure that the image can be printed and/or built into other output formats more easily; in some cases, separate 300 dpi files should be maintained for images that require inclusion in formats designed for printing and/or presentations.

Foundation Tabs Container

There are four shortcodes that can be combined together to create a container that will allow the user to click on a tab to reveal content in a matching panel. For example, you may want to display matching Ruby and YAML code blocks. You can create two tabs, one titled Ruby and the other YAML, and the user could click on one tab to show the Ruby code block and another tab to show the YAML code block. See the example below.

The four shortcodes are:

  • foundation_tabs
  • foundation_tab
  • foundation_tabs_panels
  • foundation_tabs_panel

These shortcodes use the Zurb Foundation Tabs component.

The container consists of two parts, the tabs and the panels.


Each tab is created with a foundation_tab shortcode. Use as many foundation_tab shortcodes as you need to display the number of code blocks or text blocks that you want the user to be able click on and reveal.

All foundation_tab shortcodes must be contained within opening and closing foundation_tabs shortcodes.

For example:

{{< foundation_tabs tabs-id="ruby-python-panel" >}}
  {{< foundation_tab active="true" panel-link="ruby-panel" tab-text="Ruby" >}}
  {{< foundation_tab panel-link="python-panel" tab-text="Python" >}}
{{< /foundation_tabs >}}

Tab Parameters

The foundation_tabs shortcode has one parameter:

This value must be identical to the tabs-id value in the foundation_tabs_panels shortcode, but otherwise it must be unique on the page.

The foundation_tab shortcode has three parameters:


Use active="true" to highlight the tab that user will see when they first load the page. Only add this value to one tab. The matching foundation_tabs_panel should also have active="true" in its parameters.

This is the value of the panel ID that this tab will link to. This must be identical to the panel-id value in the matching foundation_tabs_panel shortcode.
The text in the tab that the user will click on.


Each tab has a matching panel which is created with foundation_tabs_panel shortcodes. The Markdown text that is displayed in each panel must be contained in opening and closing foundation_tabs_panel shortcodes.

All foundation_tab_panel shortcodes must contained within opening and closing foundation_tabs_panels shortcodes.

For example:

{{< foundation_tabs_panels tabs-id="ruby-python-panel" >}}
  {{< foundation_tabs_panel active="true" panel-id="ruby-panel" >}}
  puts 'Hello, world!'
  {{< /foundation_tabs_panel >}}

  {{< foundation_tabs_panel panel-id="python-panel" >}}
  print('Hello, world!')
  {{< /foundation_tabs_panel >}}
{{< /foundation_tabs_panels >}}

Panel Parameters

The foundation_tabs_panels shortcode has one parameter:

This value must be identical to the tabs-id value in the foundation_tabs shortcode, but otherwise it must be unique on the page.

The foundation_tabs_panel shortcode has two parameters:

Use active="true" to indicate which panel the user will see when they first load the page. This value should also be added to the panels matching tab. Only add this value to one panel.
The HTML ID attribute of the panel. This value must be identical to the panel-link value in the matching foundation_tab shortcode that will link to this panel. This value must be unique on the page.


Below is an example of a container that shows three code blocks in three languages. You can copy and paste the code below into a page to get started. Note that the tabs-id and panel-id/panel-link values must be unique on the page.

puts 'Hello, world!'
print('Hello, world!')
package main

import "fmt"

func main() {
    fmt.Println("Hello, world!")
{{< foundation_tabs tabs-id="ruby-python-go-panel" >}}
  {{< foundation_tab active="true" panel-link="ruby-panel" tab-text="Ruby">}}
  {{< foundation_tab panel-link="python-panel" tab-text="Python" >}}
  {{< foundation_tab panel-link="golang-panel" tab-text="Go" >}}
{{< /foundation_tabs >}}

{{< foundation_tabs_panels tabs-id="ruby-python-go-panel" >}}
  {{< foundation_tabs_panel active="true" panel-id="ruby-panel" >}}
  puts 'Hello, world!'
  {{< /foundation_tabs_panel >}}

  {{< foundation_tabs_panel panel-id="python-panel" >}}
  print('Hello, world!')
  {{< /foundation_tabs_panel >}}
  {{< foundation_tabs_panel panel-id="golang-panel" >}}
  package main

  import "fmt"

  func main() {
      fmt.Println("Hello, world!")
  {{< /foundation_tabs_panel >}}
{{< /foundation_tabs_panels >}}


Chef does not follow a specific grammar convention. Be clear and consistent as often as possible. Follow the established patterns in the docs.


A tautology, when used as a description for a component, setting, method, etc. should be avoided. If a string is a tautology, some effort should be made to make it not so. An example of a tautology is something like “Create a new user” (by its very nature, a user created is a new user) or (for a setting named cidr_block) “The CIDR block for the VPC.”


Example Company

We use the fictional company “Fourth Cafe, Inc.” as an example throughout the docs.

Fourth Cafe, Inc. 123579 4th Ave Seattle, WA 98122

Examples in code: 4thcafe.pem

Example Domains

Use the domain for generic domains and email addresses in the documentation. Use the or domain for examples that should refer back to Chef Software.

Example Names

Don’t reveal personal information in examples, such as the names of real people, real email addresses, or phone numbers.

Don’t use the names of bands, musicians, or characters from works that are under copyright.

Write concretely about security wherever possible, for example, “server security” and “server-to-client authentication”. Try to avoid discussing security abstractly, but if it is unavoidable, follow the existing convention of the specialization and use “Alice” and “Bob”. Following established convention helps readers identify that the topic is security and and integrate the Chef information with their existing knowledge.

Here is a list of some example names for you to use (the last names are translations of “Chef”):

  • Ares Koch
  • Tamira Bucatar
  • Dan Gotvach
  • Lena Chushi
  • Haris Shefu
  • Booker Yolisa
  • Kala Baavarchee
  • Samuel Tagaluto

Example Email Addresses

Use for the Chef Technical Documentation team.

Example Phone Numbers

Never use a real phone number in an example. For a US phone number, use one from the range reserved for examples in fiction, which is (800) 555-0100 through (800) 555-0199.

Example Addresses

Use fictional street addresses in examples.

Use these fictional addresses:

2943 Conifer Drive Seattle, WA 98122

1214 Hollow Road Boston, MA 02110

Example IP Addresses

For IPv4 addresses, use one of the addresses provided in RFC 5735 for documentation.

IPv4 addresses:


IPv4 address ranges:

  • (TEST-NET-1)
  • (TEST-NET-2)
  • (TEST-NET-3)

For IPv6 addresses, use one of the addresses provided in RFC 3849 range for documentation.

IPv6 address range:

  • 2001:DB8::/32

Documentation Repo

The Chef reference documentation is located in:

  • The chef-web-docs repo contains a content directory which holds most the Markdown files in the doc set.
  • The static/images directory stores the image files used in the docs.
  • The config.toml tells Hugo how to build the navigation menus and contains other Hugo settings. Don’t modify this file.

In the past, the chef-web-docs repo contained documentation for prior versions of Chef components. Currently, the repo is limited to the current major versions of Chef components.

DCO Sign-off

Chef Software requires all contributors to include a Developer Certificate of Origin (DCO) sign-off with their pull request as long as the pull request does not fall under the Obvious Fix rule. This attests that you have the right to submit the work that you are contributing in your pull request.

For more information, review our full DCO signoff policy.

A proper DCO sign-off looks like:

Signed-off-by: Tamira Bucatar <>

You can add a DCO signoff to your pull request by adding it to the text of your commit message, or by using the -s or --signoff option when you make a commit.

If you forget to add a DCO sign-off before submitting a pull request, you can amend your commit by entering git commit --amend -s. After that you’ll likely have to force push your commit to github by entering git push -f.

See this blog post to understand why Chef started using the DCO signoff.

Obvious Fix

Small contributions, such as fixing spelling errors, where the content is small enough to not be considered intellectual property, can be submitted without signing the contribution for the DCO.

Changes that fall under our Obvious Fix policy include:

  • Spelling / grammar fixes
  • Typo correction, white space and formatting changes
  • Comment clean up
  • Bug fixes that change default return values or error codes stored in constants
  • Adding logging messages or debugging output
  • Changes to ‘metadata’ files like Gemfile, .gitignore, build scripts, etc.
  • Moving source files from one directory or package to another

To invoke the Obvious Fix rule, simply add Obvious Fix. to your commit message.

For more information, see our Obvious Fix policy.

Official Names

For Chef applications and components, use:

  • Chef Automate
  • Chef Habitat
  • Chef Infra (formerly Chef)
  • Chef Infra Client (Use Chef Client up to version 14.x)
  • Chef Infra Server (Formerly Chef Server)
  • Chef InSpec

Deleting Pages or Making New Pages

If a new page is created or an old page is deleted, they must be added or removed from the page.

In addition, pages must be placed in the left navigation menu properly. This may involve moving other pages up or down in the left navigation menu by increasing or decreasing their menu weight which is specified in TOML front matter of each page or possibly in the config.toml file.

Contact the documentation team if you have any questions about adding or removing pages.


See our feedback page if you have any questions or comments for the documentation team.

Was this page helpful?