protobuffet / docusaurus-protobuffet

Docusaurus toolset for Protobuf contract documentation.
https://protobuffet.com
ISC License
38 stars 7 forks source link

Added option `templatePath` to use custom template for generated MDX #9

Open jk8 opened 1 year ago

jk8 commented 1 year ago

Motivation and Context

TLDR - skip to the Problem section

I am searching for a solution for our product that will allow us to have a single documentation with both REST API and gRPC API reference. It seems that using Docusaurus + OpenAPI Docs + Protobuffet could be feasible.

I found out that I will most likely need to make some customizations:

  1. First, our developers want to use Markdown format for description fields in protobuf. I found out that it is possible to "swizzle" the ProtoFile component (thanks for this possibility) and I extended the original components with using ReactMarkdown. These changes were done in my code without the need to modify Protobuffet.
  2. Second, I will probably need to make some minor changes to the output MDX document structure, at least in the Front Matter metadata section. Currently, it is hardcoded, and it will require some changes in Protobuffet.

I noticed that the OpenAPI Docs plugin gives the possibility to pass your own template to customize the generated MDX content. I think this feature could be useful for Protobuffet as well. My initial plan was to use the same templating library as the one used in OpenAPI Docs - Mustache. However, as I wanted to implement this feature without any breaking changes in the output, I had to choose something a little more powerful than Mustache since it does not provide the possibility to render indexes (which is needed in key={} attributes). Therefore, I chose Handlebars which is similar to Mustache and provides @index. Additionally, custom helpers can be useful as well.

Problem

The generated MDX content is hardcoded, and it can't be customized. At least, it would be nice to customize the Front Matter section. Additionally, other things like strings ("Messages", "Enums", etc.) could be customizable for l18n purposes.

Proposed solution

I added an optional protobuffet.templatePath parameter, which brings the possibility to customize the generated content's template.

Usage

To configure a custom template, specify the path to your template file in the protobuffet.templatePath parameter.

Example config:

[
  'docusaurus-protobuffet',
  {
    protobuffet: {
      ...
      templatePath: './template.hbs'
    },
    docs: {
      ...
    },
  }
]

Example (default) template:

template.hbs

---
title: {{getLeafFileName name}}
hide_title: true
---

import { ProtoMessage, ProtoServiceMethod, ProtoEnum } from '@theme/ProtoFile';

# \`{{getLeafFileName name}}\`
_**path** {{{name}}}_

_**package** {{{package}}}_

{{{description}}}

---

{{#if messages}}
## Messages

{{#each messages}}

### \`{{{longName}}}\`
<ProtoMessage key=\{ {{@index}} \} message=\{ {{{stringify this}}} \} />

{{/each}}
---
{{/if}}

{{#if enums}}
## Enums

{{#each enums}}
### \`{{{longName}}}\`
<ProtoEnum key=\{ {{@index}} \} enumb=\{ {{{stringify this}}} \} />

{{/each}}
---
{{/if}}

{{#if services}}
## Services

{{#each services}}

### \`{{{name}}}\`

{{{description}}}

{{#each methods}}
#### \`{{name}}\`
<ProtoServiceMethod key=\{'{{name}}-{{@index}}'\} method=\{ {{{stringify this}}} \} />

{{/each}}
{{/each}}
---
{{/if}}

Please let me know if you think this feature would be useful for your plugin or not. In the Road map I see - "Extension support for generated sidebar and mdx files". Maybe you plan to do it differently or more robustly - so then just ignore/close this PR. I also see that you haven't been very active on this project lately, so I decided to try to do it myself. Anyway, any feedback would be appreciated.