[Feature Request]: Incorrect links to multi-version CRDs
I used crd-ref-docs to generate API documentation for a multi-version CRD.
# API Reference
## Packages
- [example.dev/v1](#exampledevv1)
- [example.dev/v2](#exampledevv2)
## example.dev/v1
### Resource Types
- [Foo](#foo)
- [FooList](#foolist)
#### Foo
<- Jump to here
## example.dev/v2
### Resource Types
- [Foo](#foo) <- Click this
- [FooList](#foolist)
#### Foo
<- Expect to jump to here
Clicking on the v2 version of Foo redirects to the v1 version of Foo
Refer to the implementation of Kubernetes Docs
We also have this issue on Markdown output. My idea to fix it is to add HTML anchors around markdown titles by replacing #### Foo with #### <a id="example-dev-v2-foo">Foo</a> and replace links [Foo](#foo) with [Foo](#example-dev-v2-foo).
I tried to fix it in pure templating at first, replacing the anchor #### {{ $type.Name }} with #### <a id="{{ markdownTypeID $type }}">{{ $type.Name }}</a>. I also replaced package links {{ $gv.TypeForKind . | markdownRenderTypeLink }} with {{ $type := $gv.TypeForKind . }}{{ markdownRenderExternalLink (printf "#%s" ($type | markdownTypeID)) $type.Name }}, but it did not work, as markdownRenderTypeLink skips native types, and since for field links the behavior of markdownRenderType is more complex.
Finally, I made a fix in this PR: https://github.com/elastic/crd-ref-docs/pull/118
We're also hitting this issue. Any chance to move forward with this?
I've tested #118 locally and it seems to produce updated links but the section names do not seem to get updated which breaks the links:
diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md
index 7a97bc0..039329a 100644
--- a/docs/gateway-operator-api-reference.md
+++ b/docs/gateway-operator-api-reference.md
@@ -1,9 +1,9 @@
<!-- This document is generated by kong/kubernetes-configuration's 'generate.docs' make target, DO NOT EDIT -->
## Packages
-- [gateway-operator.konghq.com/v1alpha1](#gateway-operatorkonghqcomv1alpha1)
-- [gateway-operator.konghq.com/v1beta1](#gateway-operatorkonghqcomv1beta1)
-- [gateway-operator.konghq.com/v2alpha1](#gateway-operatorkonghqcomv2alpha1)
+- [gateway-operator.konghq.com/v1alpha1](#gateway-operator-konghq-com-v1alpha1)
+- [gateway-operator.konghq.com/v1beta1](#gateway-operator-konghq-com-v1beta1)
+- [gateway-operator.konghq.com/v2alpha1](#gateway-operator-konghq-com-v2alpha1)
## gateway-operator.konghq.com/v1alpha1
@@ -12,43 +12,35 @@ Package v1alpha1 contains API Schema definitions for the gateway-operator.konghq
Package v1alpha1 contains API Schema definitions for the operator v1alpha1 API group
-- [AIGateway](#aigateway)
-- [DataPlaneMetricsExtension](#dataplanemetricsextension)
-- [KongPluginInstallation](#kongplugininstallation)
-- [KonnectExtension](#konnectextension)
-- [WatchNamespaceGrant](#watchnamespacegrant)
+- [AIGateway](#github-com-kong-kubernetes-configuration-api-gateway-operator-v1alpha1-aigateway)
+- [DataPlaneMetricsExtension](#github-com-kong-kubernetes-configuration-api-gateway-operator-v1alpha1-dataplanemetricsextension)
+- [KongPluginInstallation](#github-com-kong-kubernetes-configuration-api-gateway-operator-v1alpha1-kongplugininstallation)
+- [KonnectExtension](#github-com-kong-kubernetes-configuration-api-gateway-operator-v1alpha1-konnectextension)
+- [WatchNamespaceGrant](#github-com-kong-kubernetes-configuration-api-gateway-operator-v1alpha1-watchnamespacegrant)
### AIGateway
AIGateway is a network Gateway enabling access and management for AI &
-Machine Learning models such as Large Language Models (LLM).<br /><br />
-The underlying technology for the AIGateway is the Kong Gateway configured
-with a variety of plugins which provide the the AI featureset.<br /><br />
-This is a list of the plugins, which are available in Kong Gateway v3.6.x+:<br /><br />
- - ai-proxy (https://github.com/kong/kong/tree/master/kong/plugins/ai-proxy)
+Machine Learning models such as Large Language Models (LLM).<br /><br />The underlying technology for the AIGateway is the Kong Gateway configured
+with a variety of plugins which provide the the AI featureset.<br /><br />This is a list of the plugins, which are available in Kong Gateway v3.6.x+:<br /><br /> - ai-proxy (https://github.com/kong/kong/tree/master/kong/plugins/ai-proxy)
- ai-request-transformer (https://github.com/kong/kong/tree/master/kong/plugins/ai-request-transformer)
- ai-response-transformers (https://github.com/kong/kong/tree/master/kong/plugins/ai-response-transformer)
- ai-prompt-template (https://github.com/kong/kong/tree/master/kong/plugins/ai-prompt-template)
- ai-prompt-guard-plugin (https://github.com/kong/kong/tree/master/kong/plugins/ai-prompt-guard)
- - ai-prompt-decorator-plugin (https://github.com/kong/kong/tree/master/kong/plugins/ai-prompt-decorator)<br /><br />
-So effectively the AIGateway resource provides a bespoke Gateway resource
+ - ai-prompt-decorator-plugin (https://github.com/kong/kong/tree/master/kong/plugins/ai-prompt-decorator)<br /><br />So effectively the AIGateway resource provides a bespoke Gateway resource
(which it owns and manages) with the gateway, consumers and plugin
-configurations automated and configurable via Kubernetes APIs.<br /><br />
-The current iteration only supports the proxy itself, but the API is being
-built with room for future growth in several dimensions. For instance:<br /><br />
- - Supporting auxiliary functions (e.g. decorator, guard, templater, token-rate-limit)
+configurations automated and configurable via Kubernetes APIs.<br /><br />The current iteration only supports the proxy itself, but the API is being
+built with room for future growth in several dimensions. For instance:<br /><br /> - Supporting auxiliary functions (e.g. decorator, guard, templater, token-rate-limit)
- Supporting request/response transformers
- Supporting more than just LLMs (e.g. CCNs, GANs, e.t.c.)
- Supporting more hosting options for LLMs (e.g. self hosted)
- Supporting more AI cloud providers
- - Supporting more AI cloud provider features<br /><br />
-The validation rules throughout are set up to ensure at least one
+ - Supporting more AI cloud provider features<br /><br />The validation rules throughout are set up to ensure at least one
cloud-provider-based LLM is specified, but in the future when we have more
model types and more hosting options for those types so we may want to look
into using CEL validation to ensure that at least one model configuration is
provided. We may also want to use CEL to validate things like identifier
-unique-ness, e.t.c.<br /><br />
-See: https://kubernetes.io/docs/reference/using-api/cel/
+unique-ness, e.t.c.<br /><br />See: https://kubernetes.io/docs/reference/using-api/cel/
<!-- ai_gateway description placeholder -->
@@ -57,7 +49,7 @@ See: https://kubernetes.io/docs/reference/using-api/cel/
| `apiVersion` _string_ | `gateway-operator.konghq.com/v1alpha1`
| `kind` _string_ | `AIGateway`
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `spec` _[AIGatewaySpec](#aigatewayspec)_ | Spec is the desired state of the AIGateway. |
+| `spec` _[AIGatewaySpec](#github-com-kong-kubernetes-configuration-api-gateway-operator-v1alpha1-aigatewayspec)_ | Spec is the desired state of the AIGateway. |
@@ -69,8 +61,7 @@ It can be attached to a ControlPlane using its spec.extensions.
When attached it will make the ControlPlane configure its DataPlane with
the specified metrics configuration.
Additionally, it will also make the operator expose DataPlane's metrics
-enriched with metadata required for in-cluster Kubernetes autoscaling.<br /><br />
-NOTE: This is an enterprise feature. In order to use it you need to use
+enriched with metadata required for in-cluster Kubernetes autoscaling.<br /><br />NOTE: This is an enterprise feature. In order to use it you need to use
the EE version of Kong Gateway Operator with a valid license.
<!-- data_plane_metrics_extension description placeholder -->
@@ -80,7 +71,7 @@ the EE version of Kong Gateway Operator with a valid license.
| `apiVersion` _string_ | `gateway-operator.konghq.com/v1alpha1`
| `kind` _string_ | `DataPlaneMetricsExtension`
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `spec` _[DataPlaneMetricsExtensionSpec](#dataplanemetricsextensionspec)_ | |
+| `spec` _[DataPlaneMetricsExtensionSpec](#github-com-kong-kubernetes-configuration-api-gateway-operator-v1alpha1-dataplanemetricsextensionspec)_ | |
@pmalek thanks for the feedback.
Do you use custom templates ? The issue with my PR as it is is that you need to adapt the templates due to a change in how type names are rendered:
-#### {{ $type.Name }}
+#### <a id="{{ markdownTypeID $type | markdownSafeID }}">{{ $type.Name }}</a>
Currently, type.Name is hardcoded in templates, making a seamless update difficult. To avoid breaking custom templates, we could introduce a new function like markdownRenderHTMLTypeLink.
However, I wanted to get feedback before implementing this approach because:
- crd-ref-docs is still in v0.x.y.
- the current rendering method is broken for multiversion APIs
- this change would align Markdown output more closely with AsciiDoc
Ah, yes. I forgot about the custom templates. Indeed changing this fixes that issue but there's still other links that will need changing like the ones I suppose you were alluding to:
- "appears in" section (example: https://github.com/Kong/kubernetes-configuration/blob/e21787f5b6914766879c486cf92701e760b97ab9/scripts/apidocs-gen/template/type.tpl#L35-L38) which uses
markdownRenderTypeLink - packages list (example: https://github.com/Kong/kubernetes-configuration/blob/83553229a8687e15861976eea384cd670bc7db24/scripts/apidocs-gen/template/gv_list.tpl#L6-L9) which uses
markdownRenderGVLink)
I believe that we may try to introduce a config flag which would control this behavior. Default would stay as is but when multiAPIVersionLinks is set to true then HTML links with your proposal is used. I think that would be the safest option moving forward unblocking our use case and leaving the possibility to flip the default at a later stage if we want to. WDYT?
there's still other links that will need changing like the ones I suppose you were alluding to
Thanks for pointing out those other links. I've tested the "appears in" links with my version of crd-ref-docs on your project, and they seem to be working. Could you provide a specific example of a broken link?
The package list it is indeed broken by the HTML links. While replacing ## {{ $gv.GroupVersionString }} with ## <a id="{{ $gv.GroupVersionString | markdownSafeID }}">{{ $gv.GroupVersionString }}</a> would fix this, I'll try to restore the previous behavior for markdownRenderGVLink instead, as the HTML links seem unnecessary here.
Regarding the config flag for multiAPIVersionLinks, I like this approach, but since the markdown templates are relatively new and the project is still in version 0.x, perhaps enabling the new behavior by default with a flag to restore the old behavior might be preferable. I'll implement that and wait the reviewer opinion on it.
@pmalek I pushed an updated version with the packages list fixed.
@pmalek I pushed an updated version with the packages list fixed.
Thanks @antonincms 🙇 I've run this locally and links do seem to work now 👍