Table of Contents

Add a custom post processor

We provide the ability to process output files by adding a customized post-processor. In DocFX, the index file for full-text-search is generated by one post-processor named ExtractSearchIndex. In this topic, we will show how to add a customized post-processor.

Step0: Preparation

  • Create a new C# class library project in Visual Studio.
  • Add nuget packages:
  • Add Docfx.Plugins If you are building DocFX from source code, add this reference to the project, otherwise add the nuget package Docfx.Plugins with the same version as DocFX.

Step1: Create a new class (MyProcessor.cs) with the following code:

[Export(nameof(MyProcessor), typeof(IPostProcessor))]
public class MyProcessor : IPostProcessor
{
    // TODO: implements IPostProcessor
}

Step2: Update global metadata

public ImmutableDictionary<string, object> PrepareMetadata(ImmutableDictionary<string, object> metadata)
{
    // TODO: add/remove/update property from global metadata
    return metadata;
}

In this method, we can update the global metadata before building all the files declared in docfx.json. Otherwise, you can just return the metadata from parameters if you don't need to change global metadata.

Using ExtractSearchIndex for example, we add "_enableSearch": true in global metadata. The default template would then know it should load a search box in the navbar.

Step3: Process all the files generated by DocFX

    public Manifest Process(Manifest manifest, string outputFolder)
    {
        // TODO: add/remove/update all the files included in manifest
        return manifest;
    }

Input for the method manifest contains a list of all files to process, and outputFolder specifies the output folder where our static website will be placed. We can implement customized operations here to process all files generated by DocFX.

Note

Post-processor aims to process the output files, so the FileModel can't be accessed in this phase. If some metadata is needed here, an option is to save it in FileModel.ManifestProperties in build phase, then access it through ManifestItem.Metadata. Another option is to save it somewhere in output files, like HTML's <meta> Tag.

Using ExtractSearchIndex for example again, we traverse all HTML files, extract key words from these HTML files and save a file named index.json under the outputFolder. Finally we return the manifest which is not modified.

Step4: Build your project and copy the output dll files to:

  • Global: the folder that contains the Docfx executable.

  • Non-global: the folder with name plugins under a template folder, then run DocFX build command with parameter -t {template}.

    Hint: DocFX can merge templates, so we can specify multiple template folders as DocFX build -t {templateForRender},{templateForPlugins}. Each of the template folders should have a subfolder named Plugins with exported assemblies.

Step5: Add your post processor in docfx.json

In this step, we need to enable the processor by adding its name in docfx.json. Here is an example:

{
  "build": {
    ...
    "postProcessors": ["OutputPDF", "BeautifyHTML", "OutputPDF"]
  }
}

As you can see, the postProcessors is an array, which means it could have multiple processors. It needs to be pointed out that the order of postProcessors written in docfx.json is also the order to process output files. In the above example, DocFX will run OutputPDF first, then BeautifyHTML, and then OutputPDF again.

If you want to enable the post processors without changing docfx.json, you can use the build command option like docfx build --postProcessors=OutputPDF,BeautifyHTML,OutputPDF.

One more thing need to be noted: the build command option postProcessors would override the corresponding configuration in docfx.json.