nobody's blog


crystal doc with multiple versions


Margret Riegert22 Nov 2023

blog@eowyn.net - views


The Crystal programming language includes a tool for generating API documentation from source code and comments, called via crystal doc. This blog post goes over how crystal doc works with API docs for multiple versions of a project, something I had to figure out while developing CrystalDoc.info, a website I created for hosting Crystal API documentation based around the built-in docs tool.

How it works

To provide support for multiple versions, a drop-down box is used in the sidebar. When the docs page loads, it fetches a versions JSON at a URL specified when the docs are generated and uses that to list the versions available. The versions JSON URL is provided by the flag --json-config-url=/path/to/versions.json, and this URL points to a file or path on the web server where the docs are hosted. This path is not read at generation time, but instead embedded in the docs site to be read at runtime from wherever the docs are hosted.

The verrsions JSON lists each version, the path on the web server where that version exists, and whether it has been released or not:

{
    "versons": [
        {
            "name": "version name",
            "url": "/version/url",
            "released": false // Not required
        },
        // ...
    ]
}

This is the versions.json that the official Crystal API docs uses, located at https://crystal-lang.org/api/versions.json:

{
  "versions": [
    { "name": "nightly", "url": "/api/master/", "released": false },
    { "name": "1.9.2", "url": "/api/1.9.2/" },
    { "name": "1.9.1", "url": "/api/1.9.1/" },
    { "name": "1.9.0", "url": "/api/1.9.0/" },
    { "name": "1.8.2", "url": "/api/1.8.2/" },
    { "name": "1.8.1", "url": "/api/1.8.1/" },
    { "name": "1.8.0", "url": "/api/1.8.0/" },
    // ...
  ]
}

The benefit of having this as a separate runtime file is that as new versions are added, the docs don’t need to be regenerated. Instead, the versions JSON can be updated with the new version and it’s readily available on every page. For crystaldoc.info, the versions JSON is actually generated on the fly, querying the backend database to get the list of current versions (how crystaldoc.info works in detail will come in a future blog post).

Small example

For an example of what a multi-version hosted API docs would look like:

docs-root/          # a directory to store all the docs
    v0.1/
        index.html
        ...
    v0.2/
        index.html
        ...
    main/
        index.html
        ...
    index.html      # could either list each version or redirect to one of the versions
    versions.json

Where the docs are generated using:

$ crystal doc --json-config-url=/versions.json -o /path/to/docs-root/v0.1

And the versions.json contains:

{
    "versions": [
        { "name": "main", "url": "/main", "released": false },
        { "name": "v0.2", "url": "/v0.2" },
        { "name": "v0.1", "url": "/v0.1" }
    ]
}

Then if a web server is setup to host from the docs-root folder, each of the versioned docs will be able to link to each other.



© 2020-2024 Margret Riegert
Unless otherwise noted, content is under a CC BY 4.0 license.