Contributing to the Documentation¶
How to Make Changes¶
The source for this documentation website is hosted in the Asterisk Documentation GitHub repository. To make changes, follow these basic steps...
- Fork the repository into your own GitHub account.
- Clone your fork to your local development environment.
- Make changes to the markup documents in the ./docs folder.
- Build the site locally and review your changes.
- Commit your changes.
- Push your changes to your fork.
- Create a pull request.
Get the repository¶
All changes need to go through the GitHub Pull Request process. To make this easier, you should install the GitHub CLI "gh" tool. Most distributions have it available as the "gh" package. Once the tool is installed, fork and clone the asterisk/documentation repo. Since "documentation" is a common name, you'll probably want to name your fork "asterisk-documentation".
$ gh repo fork asterisk/documentation --default-branch-only --fork-name asterisk-documentation --clone
...
$ cd asterisk-documentation
$ git remote -v
origin https://github.com/<username>/asterisk-documentation.git (fetch)
origin https://github.com/<username>/asterisk-documentation.git (push)
upstream https://github.com/asterisk/documentation.git (fetch)
upstream https://github.com/asterisk/documentation.git (push)
When everything finishes, create a new branch from the main branch in which to do your work. Never do your work in the main branch itself!
You're ready to go!
Site Organization¶
- About the Project - Any general information about the project. Licensing, History, What is Asterisk?
- Asterisk Community - Anything falling under community. The places we meet, our code of conduct, community services.
- Fundamentals - Basic, key and core concepts of Asterisk. Some of the most important foundational things to know about Asterisk.
- Getting Started - Information relevant to completely new users, information on installation and how to get rolling into configuration and the rest of the documentation.
- Configuration - How everything is configured. Where are the files? How do I use them? How do I program dialplan? How do I use the APIs?
- Deployment - Examples, tutorials, how-tos and recommendations for specific use-cases or scenarios of deployment. How do I deal with Asterisk in a NATed environment? How do I build a simple PBX?
- Operation - Details concerning Asterisk's operation. That is, starting and stopping the Asterisk daemon, command line operation and other non-configuration tasks.
- Development - All information regarding the development of Asterisk itself.
- Latest API - The auto-generated API documentation for the latest Asterisk release.
- Asterisk XX Documentation - The auto-generated API documentation for all current Asterisk releases. Changes to these pages MUST be done in the Asterisk source file that they were generated from. See Dynamic Documentation below.
- Asterisk Test Suite Documentation - Documentation for the test suite! Primarily for developers.
- Historical Documentation - Documentation that is no longer current but kept for historical purposes.for the test suite! Primarily for developers.
Each section and sub-section resides in its own directory under the ./docs/ directory in the repository.
Do NOT create new top-level pages/sections without consulting with the Asterisk development team first.
Page/Section Operations¶
Adding a new page¶
First, determine if a new page is really needed.
- Have you searched the website to see if it exists already?
- Is there already some content that you could use to build on?
- Is there related content which should be consolidated with your new content?
Warning
Directory and file names are used to create the left sidebar on the rendered site and become the URL for that content. Take this into account when naming new content!
A single new page must be named using Title Case with spaces replaced by dashes and must have an .md file suffix. Example: My-New-Page.md. Only characters in the set [A-Za-z0-9_.-] are allowed. By default the page title in the left sidebar is derived from the file name with the dashes converted to spaces and the .md suffix removed. The file should be placed in the directory for the section or sub-section it belongs to. For example:
If you anticipate adding supporting images or other artifacts, create a directory with the name of your page and place the content in a file named index.md in that directory. You can then place your supporting artifacts next to the index.md file. For example:
When rendered, the index will only show "My New Page" under "Configuration" and when clicked on, will automatically display the contents of index.md.
Adding a new section¶
Adding a new section is as simple as adding a new directory to the repo filesystem. The same naming rules apply as for pages with the exception of adding the .md suffix. You should also add an index.md page that describes describe the section. You can then add your additional pages as above.
Page ordering¶
The default page ordering in the left sidebar will be as it is ordered in the filesystem. If you want to customize the ordering for a section, add a .pages YAML file to the section's directory that lists the directory contents in the order it should be displayed on the rendered website. For example:
Each entry must be a name as it appears in the filesystem. Only list what you want to appear in the left sidebar. Don't list supporting files like images.
Note
The plugin that handles the .pages files has an annoying habit of automatically expanding the first item in the nav list which can be very confusing to the user. So, if the first entry is a directory and you don't want it automatically expanded, make the index.md file the first entry. It won't show up in the sidebar but it'll keep the first section from auto-expanding.
Deleting, renaming or moving pages or sections¶
If you delete, rename or move pages or sections, any links to those pages will return a 404 "Not found". That's usually not a good idea. If you are deleting old content, move that page to the Historical Documentation section and create a redirect for that page. If you are replacing with updated content or renaming a page, you don't need to move the original to Historical Documentation but you do need to create a redirect. See Redirects below.
You'll also need to search the full docs directory for any internal links to the moved content and update them accordingly. You could use something like grep -r --include='*.md' "Moved_Page" to search.
Redirects¶
If you've moved a page, you should create a redirect for it so any links from outside to the original location will still work. Redirects are listed in the top-level mkdocs.yml file in the plugins.redirects.redirect_maps section. Follow the same pattern as the existing entries.
Redirects should also be used to fix broken links caused by the previous documentation site migration. If you run across a link in the wild that results in a "404", find the correct page and create a redirect from the old to the new.
Creating page content¶
All content is created as markdown and rendered to HTML using the MkDocs project. The docs are written in standard markdown, not GitHub Flavored markdown but there are lots of extensions available. See Markdown extensions below.
Much of the feature set available to content authors is actually used to create this page. Browse the source to see how this page was created. Contributing-to-the-Documentation.md
Front matter¶
Many of the pages converted from the old Confluence wiki have "front matter" at the top of the markdown file. For instance:
Although supported, there's no longer any need to specify front matter except for specific circumstances noted below.
Warning
If there's a front-matter fragment at the top of the file and it contains a "title" entry, it will override the top-level header as the page name in the left sidebar. For this reason, if you're editing a page that has front-matter that specifies a "title", it's a good idea to make sure the page has a top-level header with the correct title and just remove the front-matter altogether. See Headings below for more info.
Headings¶
All headings MUST use the hash-sign header format and there MUST be only one top-level (#) header. For example:
Header level 1
==============
Header level 2
-----------------
Another level 1
==============
---
title: Original Page Title
---
# New Page Title
## Header level 2
The top-level header will override the file name as the page title in the left sidebar. The URL will still reference that actual file name and if the page is listed in a .pages file it must also be referenced by the actual file name.
Nothing says you have to have a top-level header but it is good practice and you should include it unless you have a good reason not to. It should always be Title Case. The lower level headers have no case restrictions. Use whatever looks best.
The Table of Contents¶
The table of contents that appears on the right side of pages is automatically generated from the headers present in the page and an HTML "anchor" is created for each. The anchor is created by converting the header text to all lower case, converting spaces to dashes (-) and removing any characters not in the set [a-z0-9-]. The anchor for this section would be the-table-of-contents
If, for some reason, you need to hide the ToC for a page, you can do it in the front-matter. For example:
This is really the only valid use of front-matter now.
Linking¶
Linking to your supporting artifacts¶
If you have supporting artifacts you need to link to or embed in your page and those artifacts are in the same directory as your page, the syntax is simple:
Linking to another section in your document¶
Each header defined in your page is automatically assigned an "anchor" reference consisting of the header text converted to lower case with spaces replaced by dashes. For instance the anchor for this section would be linking-to-another-section-in-your-document. If you wanted to create a link to this section in another place in your document, you'd reference it as follows:
[Linking to another section in your document](#linking-to-another-section-in-your-document)
The leading # in the URL is the standard way to referenece anchors in a document.
Linking to other content on the Documentation website¶
If the content is in the same directory or in a directory below the current directory you can use relative link.
To link to other content on the website, use an absolute URL.
[Configuring Alternate Channel Storage Backends](/Configuration/Core-Configuration/Alternate-Channel-Storage-Backends)
The mkdocs documentation actually discourages using absolute links and would rather you use a relative link like ../../../Configuration/Core-Configuration/Alternate-Channel-Storage-Backends. This is to accomodate sites where the documentation isn't hosted at the root of the website. The Asterisk documentation is at the root level so relative links just make things difficult for us. Always use absolute links.
Don't forget, you can link directly to a specific section in any page by using the heading's anchor...
[POC Conclusions](/Configuration/Core-Configuration/Alternate-Channel-Storage-Backends/#poc-conclusions)
Warning
Do NOT include the .md suffix of pages you link to. If that page maintainer decides to add supporting artifacts and changes the page to a directory with an index.md file in it, your link may break. When in doubt about what link to use, you can get it by simply hovering over the link to the page you want in the live site and noting the URL.
Comments¶
Although not usually needed, you can add comments to markdown files that won't be rendered on the website. For instance, it could be useful to explain why you formatted something the way you did so future maintainers don't accidentally undo it. The format is the same as it is for HTML:
<!--title="Example multi-line comment in markdown"
Some comment
that won't appear on the rendered website
-->
Standard markdown text formatting¶
All standard markdown formatting syntax. A good guide for basic syntax is Markdown Guide. Just don't use the "Alternate Syntax" for headings and use "fenced code blocks" (see below) instead of indented code blocks.
Markdown extensions¶
Most extensions from the PyMdown plugin are available. The most useful include SuperFences (which handles code blocks) and Blocks (which handles admonitions). To see the list of extensions that are currently enabled for this site, see the "markdown_extensions" section at the bottom of the site's mkdocs.yml file.
Most of the extensions provided by Material for MkDocs are also enabled except those only available to paying sponsors and a few that don't make sense in this environment. Many of these are actually implemented using PyMdown.
Extension Preference
If the same extension is available in both PyMdown and Material for MkDocs, ALWAYS use the PyMdown version/syntax!
Code blocks¶
Speaking of code blocks, you should always create "fenced" code blocks using the 'three-backtick' (```) technique which can include syntax a highlighting hint and a title (among other things). For example:
would produce:
You can also nest code blocks. This was required to show the example for the syntax above as well as the note below. Here's the example for above:
That needed 3 levels of nesting to render properly :).
Note
Use "ini" as the syntax highlighting hint for Asterisk config files. For example:
Admonitions¶
Available admonitions include "note", "attention", "caution", "danger", "error", "tip", "hint", "warning" and "details".
Examples:
This Is A Note
Take note of this.
And yes, you can nest them...
/// note | This Is A Note
Take note of this.
//// warning | But be warned about this!
Pay attention
////
///
This Is A Note
Take note of this.
But be warned about this!
Pay attention
Danger! (this is a real admonition, not an example)
Most of the pages that were converted from the old Confluence wiki use the !!! admonition style. For example:
!!! tip
The `-R` option will also attach a remote console - however, it will attempt to automatically
reconnect to Asterisk if for some reason the connection is broken. This is particularly useful
if your remote console restarts Asterisk.
[//]: # (end-tip)
That style is only supported for backwards compatibility and must not be used in new content. If you are editing a page with old style admonitions, you MUST convert them ALL to the new style. Mixing old and new styles will most probably cause the page to not be rendered correctly.
Details¶
"details" is a special type of admonition whose content is initially collapsed.
Summary
These details are initially collapsed.
You can set the type to change the icon and color if needed:
Summary
These details are initially collapsed.
Danger! (another real admonition, not an example)
Don't over-use admonitions (like I did in this page )! It can be very distracting.
Snippets¶
Another extension you might find useful is Snippets. This extension allows you to include other files (or parts of other files) in your document. A good use case would be explaining sections of a sample config file.
In your index.md file you could not only have a link to the entire sample_config.conf file, but you could also include sections of that file in your markdown file:
```ini title="Example configuration"
--8<-- "Configuration/My-New-Feature/sample_config.conf:5:10"
```
Snippets are implemented as a pre-processor so you must always specify the path to the file to be included relative to the top-level docs directory. The file contents are included verbatim and can contain any valid markdown.
Emojis¶
Yes you can use emojis like :smile: but don't over do it.
Tables¶
Tables are fully supported. See the syntax in Markdown Guide.
Diagrams and Graphs¶
When the documentation site was hosted in a Confluence Wiki, the mechanism for creating diagrams was a Gliffy Confluence macro which allowed you to design diagrams in-line. You'll still see files in this repo with a .gliffy.xml file extension which contained the source for the diagram and a file with the .png extension right next to it with the rendered result. Although the .png files are still rendered correctly, the .gliffy.xml files are simply ignored. Since Gliffy is a Confluence-specific tool, we needed another way to create diagrams. This turned out to be Mermaid.
You can use Mermaid to create over 20 types of diagrams and charts. There's no in-line visual editor to create the diagrams but the syntax is pretty simple. Here's a short example:
---
title: Flowchart Example
---
flowchart LR
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
---
title: Flowchart Example
---
flowchart LR
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
Mermaid itself is a Javascript library but the mkdocs-mermaid2-plugin takes care of all of the plumbing so all you have to do is describe the diagram you want. Visit the Mermaid Diagram Syntax page to see all the different types of diagrams you can create and how to create them.
Mermaid does have an on-line playground to help design diagrams and while the basic version is free, you do have to register to use it. Since you already have a GitHub account (or you wouldn't be here), you can use that to register with. You can then just copy the generated code and paste it into your page. Please don't export diagrams to images. That makes it impossible to edit them later.
HTML in markdown¶
For very rare cases where the markdown syntax already described above doesn't cover a case you absolutely need, you can embed some HTML directly into your markdown. The only case that comes to mind is forcing a line break.
this is
a broken
line
This can be useful to force wrap the text in table cells.
| Column 1 | Column 2<br>(optional) |
| ----------| ----------|
| cell 1 | For instance:<br>abc = ABC |
| Column 1 | Column 2 (optional) |
|---|---|
| cell 1 | For instance: abc = ABC |
Building the documentation locally¶
Once you've made your updates, you'll want to test it locally to make sure everything renders properly.
Setup the environment¶
You've already cloned your fork of the documentation repo at this point but to set it up for building the documentation perform the following steps:
# Install python3-virtualenv
$ sudo (apt | dnf | yum) install python3-virtualenv
$ cd asterisk-documentation
$ python3 -m venv --system-site-packages --symlinks .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt
Build the web site¶
To build only the static documentation without any of the API documentation for the branches simlpy run make:
This will take about 30 seconds.
Start up a web server.¶
The rendered website will be located in the ./temp/site directory. You can use the web server software of your choice to serve it but it's much simpler to use the mkdocs built-in webserver:
By default the server is started on port 8000 but you can supply different arguments to the server by adding a SERVE_OPTS variable to the command line:
Run mkdocs serve --help to see the options you can set.
Note
You can't browse the site using file:// URLS without a web server. MkDocs generates index.html files assuming a web server's rules will automatically use them as the default page for directories.
Save often-used variables in Makefile.inc¶
The main Makefile automatically includes the Makefile.inc file if it exists. You can use this to define variables like SERVE_OPTS so you don't have to specify them on the command line every time. This file is ignored by git so don't check it in.
Dynamic Documentation¶
The dynamic documentation includes the pages generated from Asterisk itself and includes:
- AGI Commands
- AMI Actions
- AMI Events
- Asterisk REST Interface
- Dialplan Applications
- Dialplan Functions
- Module Configuration
These will be rendered under the "Asterisk XX Documentation/API Documentation" directories where "XX" is the branch name.
The publish process gets this information directly from the Asterisk CreateDocs job (which runs nightly) and generates markdown which MkDocs will then use to render the site. For this reason, all changes to the dynamic documentation need to be made in the Asterisk source code itself.
The AGI, AMI, Dialplan and Module documentation comes from the XML documentation embedded in the provider modules and generated by CreateDocs running xmldoc dump from the Asterisk CLI.
The Asterisk REST Interface documentation comes from the markdown files generated by CreateDocs running make ari-stubs.
The nightly documentation "publish" performs the following steps:
- Retrieves the XML and ARI markdown from the latest Asterisk CreateDocs workflow run for each branch.
- Runs
utils/astxml2markdown.pyon the retrieved XML and places the resulting markdown in thetemp/build-<branch>directory. - Places the retrieved ARI markdown in the
temp/build-<branch>directory. - Builds the website.
Build the static documentation plus the dynamic API documentation for one or more branches.¶
Note
In order to build the dynamic documentation, you'll need to have the GitHub CLI "gh" tool installed to retrieve the source files from the Asterisk nightly job that creates them.
Attention
It can take 5 minutes or more to build the dynamic documentation for each branch so don't do this unless you're sure you need to. HINT: You probably don't need to.
If you do need to generate the dynamic documentation, run make with a BRANCHES variable set to a comma-separated list of branches you want to build.
Test changes you've made to Asterisk source files¶
Let's say you have actually made changes to the documentation contained in the Asterisk source files and want to see how it will be rendered. Instead of the documentation build process getting the Asterisk sources from the latest CreateDocs workflows, you can export the documentation and then tell the documentation build process where to get the files.
The XML documentation for AGI, AMI, Dialplan and Module configuration has to be generated from a running asterisk instance so build and start it. Then from the Asterisk CLI run xmldoc dump /tmp/asterisk-<branch>-documentation.xml.
The markdown for ARI resources and events is generated by running make ari-stubs in your Asterisk source directory. Asterisk doesn't need to be built or run for this.
Once you've done both, create a new file in your documentation directory named Makefile.<branch>.inc. These files are already ignored by git so don't check them in.
# If you want to use a local XML file to generate the
# AGI, AMI, Dialplan and Module_Configuration documentation,
# specify it here.
ASTERISK_XML_FILE := /tmp/asterisk-22-documentation.xml
#
# If you want to use local markdown files for the ARI
# documentation, specify a path to a directory containing
# the markdown generated by "make ari-stubs".
ASTERISK_ARI_DIR := /usr/src/asterisk/asterisk/doc/rest-api
#
# If you want to use local XML but skip processing ARI
# altogether, set this variable to "yes".
#SKIP_ARI := no
# If either ASTERISK_XML_FILE or ASTERISK_ARI_DIR are not set,
# that documentation source will be downloaded from the
# CreateDocs job.
Now run make:
The main Makefile will automatically include the Makefile.Makefile.<branch>.inc file for each branch you want to build and that the paths in each file are adjusted to that branch's Asterisk files.