Documentation With Docfx
Documentation plays a crucial role in helping everyone adopt and use custom packages. For packages published by the Bonsai Foundation, we use docfx, a static site generator for .NET projects, to automatically generate and publish documentation pages. As we have integrated and extended docfx with specific Bonsai documentation features, we encourage package developers to use docfx to ensure a consistent and integrated experience across the Bonsai community.
The following article will go into detail on how to create a docfx website for your package. For documentation style guidelines, check out the Documentation Style Guide.
Tip
We recommend using a code editor with an integrated terminal like Visual Studio Code to follow along with these instructions.
Repository organization
To help long term maintenance of documentation, we recommend package repositories to be organized according to the following standard folder structure before setting up docfx:
.
├── .bonsai/ # Local Bonsai Environment (see note below)
├── .github/workflows/ # GitHub Actions Folder (see note below)
│ └── docs.yml
├── docs/ # Folder to setup docfx
└── src/
└── Bonsai.PackageName/ # Project files here
...
.bonsai/- A local Bonsai environment is required to run the script that exports Bonsai workflow images. To create one, run the following commands:
dotnet new install Bonsai.Templates
dotnet new bonsaienv
.github/workflows/- Thedocfxwebsite is often automatically published to GitHub Pages using a GitHub Actions workflow specified in thedocs.ymlfile. Unfortunately these workflows tend to be very project specific and we do not yet have a standardized pipeline. For a minimal example and inspiration you can check the workflow on a package repository that has been recently updated, e.g. bonsai-rx/zeromq.
Setup docfx
You can setup a local installation of docfx directly in your package repository with the following commands (executed in the root directory):
dotnet new tool-manifest
dotnet tool install --local docfx
Then navigate to the docs folder and initialize a new docfx website with the following command:
dotnet docfx init
We recommend the following options for new websites (make sure to match the name to your package):
Name (mysite): Bonsai - Package Name
Generate .NET API documentation? [y/n] (y): y
.NET projects location (src): src
Markdown docs location (docs): articles
Enable site search? [y/n] (y): y
Enable PDF? [y/n] (y): n
You should now have a minimal docfx website. Run the following command to generate a local preview of the website, and verify that API documentation for your package has been generated successfully:
dotnet docfx --serve
Docfx folder organization
The documentation guides assume the docs folder is organized according to the following layout:
.
├── api/ # Automatically generated by docfx
├── apidoc/ # Place individual operator articles here (see style guide)
├── articles/ # Place "Manual" section articles here (see style guide)
├── bonsai/ # Docfx-tools submodule (see note below)
├── images/ # Place images like screenshots here
├── template/ # Custom CSS template (see note below)
│ └── public/
│ ├── main.css
│ └── main.js
├── tutorials/ # Place "Tutorials" section articles here (see style guide)
├── workflows/ # Place .bonsai workflow files here for image export
├── build.ps1 # Bonsai workflow image export script (see note below)
├── logo.svg # Website logo
└── favicon.ico # Website bookmark logo
...
bonsai/- this folder is where we initialize the submodule referencing docfx-tools. This submodule contains scripts for automating image export fromBonsaiworkflows (if you want to include them in your article) and also common infrastructure for workflow containers. To create this submodule, run this command in thedocsfolder:
git submodule add https://github.com/bonsai-rx/docfx-tools bonsai
If you cloned the repository and the bonsai folder does not contain any files:
git submodule update --init
To update the submodule to the latest commit:
git submodule update --remote
template/- the files in thisdocfxtemplate extend the base template indocfx-tools. Below are templates formain.cssandmain.jswhich add a GitHub link to the top right of the navigation bar and include all styles for workflow containers.
main.css
@import "workflow.css";
main.js
import WorkflowContainer from "./workflow.js"
export default {
defaultTheme: 'auto',
iconLinks: [{
icon: 'github',
href: 'https://github.com/org-name/PackageName',
title: 'GitHub'
}],
start: () => {
WorkflowContainer.init();
}
}
build.ps1- this custom script exports Bonsai workflow images usingdocfx-toolsand then calls thedocfxbuild process. Make sure to change the line to point to your package output location:
.\bonsai\modules\Export-Image.ps1 "..\src\Bonsai.PackageName\bin\Release\net462"
dotnet docfx @args
logo.svgandfavicon.ico- for official Bonsai packages these can be downloaded from the docfx-assets repository.
Configuring docfx
The docfx.json file in the docs folder specifies the configuration options for the website and needs to be modified to make use of all available features. If in doubt, refer to a Bonsai package repository that has been recently updated, e.g. bonsai-rx/machinelearning, or the docfx documentation for more information. These steps are listed in order of appearance in docfx.json.
Hide obsolete operators
Add a filter attribute to hide obsolete operators from the package docs. In the process of upgrading packages we want to avoid documenting operators that are no longer supported (but are still included for compatibility purposes for old workflows). You can also hide private classes that are not supposed to be shown to the end user.
"metadata": [
{
"filter": "filter.yml"
}
]
Make a file called filter.yml with the following lines and place it in the docs directory. You can also specify other uids here.
apiRules:
- exclude:
hasAttribute:
uid: System.ObsoleteAttribute
Exclude these files from content to avoid duplicate errors.
"build": {
"content": [
"exclude": [
"_site/**",
"filter.yml",
"apidoc/**"
]
]
}
Enable operator articles
Add the overwrite attribute to ensure individual operator articles stored in the apidoc folder are included in both articles and API docs.
"build": {
"overwrite": [
{
"files": [
"apidoc/**.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
}
Add resource files
Modify the resource attribute to include files that need to be imported.
"resource": {
"files": [
"logo.svg",
"favicon.ico",
"images/**",
"workflows/**"
]
}
Apply modern template
Modify the template attribute to use the modern template and apply the docfx-tools custom templates to enable workflow containers.
"template": [
"default",
"modern",
"bonsai/template",
"template"
]
Update global metadata
Modify the globalMetadata attribute to change package name and add the _appFooter attribute and description.
"globalMetadata": {
"_appName": "Bonsai - PackageName",
"_appTitle": "Bonsai.PackageName",
"_appFooter": "© 2024 Bonsai Foundation CIC and Contributors. Made with <a href=\"https://dotnet.github.io/docfx\">docfx</a>"
}
Enable custom extensions and xref
Add the markdownEngineProperties attribute to enable markdig(docfx markdown processor) extensions for additional markdown functionality.
"build": {
"markdownEngineProperties": {
"markdigExtensions": [
"attributes",
"customcontainers"
]
}
}
Add the xref attribute to cross reference classes from the Bonsai library (if you use them to build your package). If you have used other libraries with docfx documentation, add their xrefmap.yml here as well.
"build": {
"xref": [
"https://bonsai-rx.org/docs/xrefmap.yml",
]
}
Publishing to GitHub Pages
Once you are satisfied with the website, publish to GitHub Pages. A GitHub Actions workflow should already be in place if you follow the standard folder structure. Make sure docs.yml is in the .github/workflows folder.
- Setup a new branch called
gh-pageson your fork of the repository. - Go to your repo settings >
Pages>Build and deployment> underSourceselectDeploy from a branchand make suregh-pagesis selected. - Commit your edits and push them online.
- Under the
Actionstab of your GitHub repo, trigger theBuild docsworkflow manually with theRun workflowbutton on the branch you committed your edits to. This will build the docs site on thegh-pagesbranch. - Once the
Build docsworkflow has been completed, thepages-build-deploymentworkflow will run and publish your forked repo automatically. - The URL for the site can be found in the
Pagessection of your repository settings.
Note
To ensure that the Bonsai Editor can link to the reference documentation for package operators, make sure that the PackageProjectUrl in either the .csproj file or the Directory.Build.props file points to the URL for the documentation website.
Version control cleanup
To keep your online GitHub repository clean, you can use .gitignore files to ignore files or documentation which are automatically generated and do not need to be version controlled. Add each item as a separate line to the appropriate .gitignore file in each location.
.
├── .bonsai/
│ └── .gitignore # Packages, *.exe, *.exe.settings, *.exe.old (local environment files regenerated by Setup.cmd)
└── docs/
├── api/
│ └── .gitignore # *.yml, .manifest (docfx automatically generated files)
├── workflows/
│ └── .gitignore # *.layout, *.svg (bonsai workflow layout files and locally generated images)
└── .gitignore # _site (folder generated by docfx for local preview)
...
Creating example workflows
To include an example workflow in an article of the documentation, first create the example workflow using the local bonsai environment and save it as articleFileName-workflowName.bonsai into the workflows folder. In the text of the article that references this example workflow, add a workflow custom container.
For example, assuming you want to include CustomPulseTrain-SendCustomWaveform.bonsai:
:::workflow

:::
Workflow images are automatically exported as SVG files by the docfx-tools submodule. The steps below require an existing build.ps1 file and a local bonsai environment.
To generate the images locally for the docfx preview, navigate to the docs folder and run this command (make sure build.ps1 has been modified to point to the correct package folder in src):
./build.ps1
If any of the nodes are greyed out in the generated SVG, then additional packages need to be installed in the local bonsai environment by using the package manager.
Troubleshooting
File not found errors
These are usually due to folders not being in the right place. Check the directory trees above or a repository that has been recently updated, e.g. bonsai-rx/machinelearning, for reference. Also pay attention to any scripts or CSS files that require modification to the package name or link/source location.
Docfx local preview not updating
If you are running the local preview dotnet docfx --serve and not seeing changes:
- Make sure that any changes you have made in your code editor are saved.
- Hard refresh pages in the browser using either
Ctrl+Shift+RandCtrl+F5or clear the cache to avoid cache issues. - As a last resort - check that the content updates online by publishing your website.
Differences between local and online builds
If there are discrepancies between local and online builds and they persist, this could indicate a docfx version conflict. The online build process uses a local installation of docfx but it is also possible to install docfx globally (which we do not recommend). To check if this is the cause of the discrepancy:
Make sure to run this command which uses the local installation of docfx
dotnet docfx --serve
Instead of this command which uses the global installation of docfx.
docfx --serve
The .config folder in the root directory contains docfx local version info if you need to check it.
If you wish to update the local installation of docfx run this command in the root directory:
dotnet tool update docfx