mix docs — ExDoc v0.37.3 (original) (raw)

Uses ExDoc to generate a static web page from the project documentation.

Command line options

The command line options have higher precedence than the options specified in your mix.exs file below.

Configuration

ExDoc will automatically pull in information from your project, like the application and version. However, you may want to set:name, :source_url and :homepage_url to have a nicer output from ExDoc, for example:

def project do
  [
    app: :my_app,
    version: "0.1.0-dev",
    deps: deps(),

    # Docs
    name: "My App",
    source_url: "https://github.com/USER/PROJECT",
    homepage_url: "http://YOUR_PROJECT_HOMEPAGE",
    docs: [
      main: "MyApp", # The main page in the docs
      favicon: "path/to/favicon.png",
      logo: "path/to/logo.png",
      extras: ["README.md"]
    ]
  ]
end

ExDoc also allows configuration specific to the documentation to be set. The following options should be put under the :docs key in your project's main configuration. The :docs options should be a keyword list or a function returning a keyword list that will be lazily executed.

https://mydomain.org/user_or_team/repo_name/blob/main/%{path}#L%{line}  

For Bitbucket:

https://mydomain.org/user_or_team/repo_name/src/main/%{path}#cl-%{line}  

If a function, then it must be a function that takes two arguments, path and line, where path is either an relative path from the cwd, or an absolute path. The function must return the full URI as it should be placed in the documentation.

Groups

ExDoc content can be organized in groups. This is done via the :groups_for_extrasand :groups_for_modules. For example, imagine you are storing extra guides in your documentation which are organized per directory. In the extras section you have:

extras: [
  "guides/introduction/foo.md",
  "guides/introduction/bar.md",

  ...

  "guides/advanced/baz.md",
  "guides/advanced/bat.md"
]

You can have those grouped as follows:

groups_for_extras: [
  "Introduction": Path.wildcard("guides/introduction/*.md"),
  "Advanced": Path.wildcard("guides/advanced/*.md")
]

Or via a regex:

groups_for_extras: [
  "Introduction": ~r"/introduction/",
  "Advanced": ~r"/advanced/"
]

Similar can be done for modules:

groups_for_modules: [
  "Data types": [Atom, Regex, URI],
  "Collections": [Enum, MapSet, Stream]
]

A regex or the string name of the module is also supported.

Grouping functions, types, and callbacks

Types, functions, and callbacks inside a module can also be organized in groups. By default, ExDoc respects the :group metadata field:

@doc group: "Queries"
def get_by(schema, fields)

The function above will be automatically listed under the "Queries" section in the sidebar. The benefit of using :group is that it can also be used by tools such as IEx during autocompletion. These groups are then ordered alphabetically in the sidebar.

It is also possible to tell ExDoc to either enrich the group metadata or lookup a different field via the :default_group_for_doc configuration. The default is:

default_group_for_doc: fn metadata -> metadata[:group] end

The metadata received contains all of the documentation metadata, such as :group, but also :module, :name, :arity and :kind to help identify which entity is currently being processed. For example, projects like Nx have a custom function that converts "Queries" into "Function: Queries":

default_group_for_doc: fn metadata ->
  if group = metadata[:group] do
    "Functions: #{group}"
  end
end

Whenever using the :group key, the groups will be ordered alphabetically. If you also want control over the group order, you can also use the :groups_for_docswhich works similarly as the one for modules/extra pages.

:groups_for_docs is a keyword list of group titles and filtering functions that receive the documentation metadata and must return a boolean. For example, imagine that you have an API client library with a large surface area for all the API endpoints you need to support. It would be helpful to group the functions with similar responsibilities together. In this case in your module you might have:

defmodule APIClient do
  @doc section: :auth
  def refresh_token(params \\ [])

  @doc subject: :object
  def update_status(id, new_status)

  @doc permission: :grant
  def grant_privilege(resource, privilege)
end

And then in the configuration you can group these with:

groups_for_docs: [
  Authentication: & &1[:section] == :auth,
  Resource: & &1[:subject] == :object,
  Admin: & &1[:permission] in [:grant, :write]
]

A function can belong to a single group only. The first group that matches will be the one used. In case no group is found in :groups_for_docs, the :default_group_for_doc callback is invoked. If it returns nil, it then falls back to the appropriate "Functions", "Types" or "Callbacks" section respectively.

It is also possible to configure some of ExDoc behaviour using meta tags. These meta tags can be inserted using before_closing_head_tag.

Nesting

ExDoc also allows module names in the sidebar to appear nested under a given prefix. The :nest_modules_by_prefix expects a list of module names, such as[Foo.Bar, Bar.Baz]. In this case, a module named Foo.Bar.Baz will appear nested within Foo.Bar and only the name Baz will be shown in the sidebar. Note the Foo.Bar module itself is not affected.

This option is mainly intended to improve the display of long module names in the sidebar, particularly when they are too long for the sidebar or when many modules share a long prefix. If you mean to group modules logically or call attention to them in the docs, you should probably use :groups_for_modules(which can be used in conjunction with :nest_modules_by_prefix).

Changing documentation over time

As your project grows, your documentation may very likely change, even structurally. There are a few important things to consider in this regard:

Because these docs are static files, the behavior of a missing page will depend on where they are hosted. In particular, hexdocs.pm will show a 404 page.

You can improve the developer experience on everything but function names changing by using the redirects configuration. For example, if you changed the module MyApp.MyModuleto MyApp.My.Module and the extra get-started.md to quickstart.md, you can setup the following redirects:

redirects: %{
  "MyApp.MyModule" => "MyApp.My.Module",
  "get-started" => "quickstart"
}

Customizing Search Data

It is possible to fully customize the way a given extra is indexed, both in autocomplete and in search. In most cases, this makes sense for generated documentation. If search_data is provided, it completely overrides the built in logic for indexing your document based on the headers and content of the document. The following fields can be provided in a list of maps for search_data.

Umbrella project

ExDoc can be used in an umbrella project and generates a single documentation for all child apps. You can use the :ignore_apps configuration to exclude certain projects in the umbrella from documentation.

Generating documentation per each child app can be achieved by running:

mix cmd mix docs

See mix help cmd for more information.