@redpanda-data/docs-extensions-and-macros 4.12.5 → 4.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.adoc +33 -1064
- package/bin/doc-tools-mcp.js +720 -0
- package/bin/doc-tools.js +1050 -50
- package/bin/mcp-tools/antora.js +153 -0
- package/bin/mcp-tools/cache.js +89 -0
- package/bin/mcp-tools/cloud-regions.js +127 -0
- package/bin/mcp-tools/content-review.js +196 -0
- package/bin/mcp-tools/crd-docs.js +153 -0
- package/bin/mcp-tools/frontmatter.js +138 -0
- package/bin/mcp-tools/generated-docs-review.js +887 -0
- package/bin/mcp-tools/helm-docs.js +152 -0
- package/bin/mcp-tools/index.js +245 -0
- package/bin/mcp-tools/job-queue.js +468 -0
- package/bin/mcp-tools/mcp-validation.js +266 -0
- package/bin/mcp-tools/metrics-docs.js +146 -0
- package/bin/mcp-tools/openapi.js +174 -0
- package/bin/mcp-tools/prompt-discovery.js +283 -0
- package/bin/mcp-tools/property-docs.js +157 -0
- package/bin/mcp-tools/rpcn-docs.js +113 -0
- package/bin/mcp-tools/rpk-docs.js +141 -0
- package/bin/mcp-tools/telemetry.js +211 -0
- package/bin/mcp-tools/utils.js +131 -0
- package/bin/mcp-tools/versions.js +168 -0
- package/cli-utils/convert-doc-links.js +1 -1
- package/cli-utils/github-token.js +58 -0
- package/cli-utils/self-managed-docs-branch.js +2 -2
- package/cli-utils/setup-mcp.js +313 -0
- package/docker-compose/25.1/transactions.md +1 -1
- package/docker-compose/transactions.md +1 -1
- package/extensions/DEVELOPMENT.adoc +464 -0
- package/extensions/README.adoc +124 -0
- package/extensions/REFERENCE.adoc +768 -0
- package/extensions/USER_GUIDE.adoc +339 -0
- package/extensions/generate-rp-connect-info.js +3 -4
- package/extensions/version-fetcher/get-latest-console-version.js +38 -27
- package/extensions/version-fetcher/get-latest-redpanda-helm-version-from-operator.js +1 -1
- package/extensions/version-fetcher/get-latest-redpanda-version.js +65 -54
- package/extensions/version-fetcher/retry-util.js +88 -0
- package/extensions/version-fetcher/set-latest-version.js +6 -3
- package/macros/DEVELOPMENT.adoc +377 -0
- package/macros/README.adoc +105 -0
- package/macros/REFERENCE.adoc +222 -0
- package/macros/USER_GUIDE.adoc +220 -0
- package/macros/rp-connect-components.js +6 -6
- package/package.json +12 -3
- package/tools/bundle-openapi.js +20 -10
- package/tools/cloud-regions/generate-cloud-regions.js +1 -1
- package/tools/fetch-from-github.js +18 -4
- package/tools/gen-rpk-ascii.py +3 -1
- package/tools/generate-cli-docs.js +325 -0
- package/tools/get-console-version.js +4 -2
- package/tools/get-redpanda-version.js +4 -2
- package/tools/metrics/metrics.py +19 -7
- package/tools/property-extractor/Makefile +7 -1
- package/tools/property-extractor/cloud_config.py +4 -4
- package/tools/property-extractor/constant_resolver.py +11 -11
- package/tools/property-extractor/property_extractor.py +18 -16
- package/tools/property-extractor/topic_property_extractor.py +2 -2
- package/tools/property-extractor/transformers.py +7 -7
- package/tools/property-extractor/type_definition_extractor.py +4 -4
- package/tools/redpanda-connect/README.adoc +1 -1
- package/tools/redpanda-connect/generate-rpcn-connector-docs.js +5 -3
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
= Antora Extensions Development Guide
|
|
2
|
+
:toc:
|
|
3
|
+
:toclevels: 3
|
|
4
|
+
|
|
5
|
+
Guide for developing new Antora extensions.
|
|
6
|
+
|
|
7
|
+
Antora extensions are Node.js modules that hook into the Antora build pipeline to modify, enhance, or generate content. Extensions can run at different stages of the build process and access the content catalog, component descriptors, and more.
|
|
8
|
+
|
|
9
|
+
== Extension architecture
|
|
10
|
+
|
|
11
|
+
Antora extensions are JavaScript modules that export a `register` function. This function receives a context object that provides access to the Antora build lifecycle and APIs.
|
|
12
|
+
|
|
13
|
+
=== Extension lifecycle
|
|
14
|
+
|
|
15
|
+
Extensions register event listeners that execute at specific points in the Antora build:
|
|
16
|
+
|
|
17
|
+
. **contentAggregated** - After content is collected but before conversion
|
|
18
|
+
. **uiLoaded** - After UI bundle is loaded
|
|
19
|
+
. **contentClassified** - After content is organized by component/module
|
|
20
|
+
. **documentsConverted** - After AsciiDoc conversion to HTML
|
|
21
|
+
. **beforePublish** - Before site is written to disk
|
|
22
|
+
. **sitepublished** - After site is published
|
|
23
|
+
|
|
24
|
+
=== Extension structure
|
|
25
|
+
|
|
26
|
+
Basic extension structure:
|
|
27
|
+
|
|
28
|
+
[,javascript]
|
|
29
|
+
----
|
|
30
|
+
module.exports.register = function ({ config }) {
|
|
31
|
+
// Extension logic here
|
|
32
|
+
}
|
|
33
|
+
----
|
|
34
|
+
|
|
35
|
+
With event listeners:
|
|
36
|
+
|
|
37
|
+
[,javascript]
|
|
38
|
+
----
|
|
39
|
+
module.exports.register = function ({ config }) {
|
|
40
|
+
this
|
|
41
|
+
.on('contentAggregated', ({ contentAggregate }) => {
|
|
42
|
+
// Process aggregated content
|
|
43
|
+
})
|
|
44
|
+
.on('documentsConverted', ({ contentCatalog }) => {
|
|
45
|
+
// Process converted documents
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
----
|
|
49
|
+
|
|
50
|
+
== Creating a new extension
|
|
51
|
+
|
|
52
|
+
=== Create the file
|
|
53
|
+
|
|
54
|
+
Create a new JavaScript file in the `extensions/` directory:
|
|
55
|
+
|
|
56
|
+
[,bash]
|
|
57
|
+
----
|
|
58
|
+
touch extensions/my-extension.js
|
|
59
|
+
----
|
|
60
|
+
|
|
61
|
+
=== Implement the register function
|
|
62
|
+
|
|
63
|
+
[,javascript]
|
|
64
|
+
----
|
|
65
|
+
/**
|
|
66
|
+
* My Extension - Does something useful
|
|
67
|
+
*
|
|
68
|
+
* Configuration options:
|
|
69
|
+
* - option1: Description of option1
|
|
70
|
+
* - option2: Description of option2
|
|
71
|
+
*/
|
|
72
|
+
module.exports.register = function ({ config }) {
|
|
73
|
+
const logger = this.getLogger('my-extension')
|
|
74
|
+
|
|
75
|
+
// Access configuration
|
|
76
|
+
const option1 = config.option1 || 'default-value'
|
|
77
|
+
const option2 = config.option2
|
|
78
|
+
|
|
79
|
+
// Validate configuration
|
|
80
|
+
if (!option2) {
|
|
81
|
+
logger.error('option2 is required')
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Register event listeners
|
|
86
|
+
this.on('contentClassified', ({ contentCatalog }) => {
|
|
87
|
+
logger.info('Processing content...')
|
|
88
|
+
|
|
89
|
+
// Your extension logic here
|
|
90
|
+
const pages = contentCatalog.getPages()
|
|
91
|
+
|
|
92
|
+
pages.forEach(page => {
|
|
93
|
+
// Do something with each page
|
|
94
|
+
logger.debug(`Processing ${page.src.relative}`)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
logger.info('Processing complete')
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
----
|
|
101
|
+
|
|
102
|
+
=== Add to playbook
|
|
103
|
+
|
|
104
|
+
Test your extension by adding it to a playbook:
|
|
105
|
+
|
|
106
|
+
[,yaml]
|
|
107
|
+
----
|
|
108
|
+
antora:
|
|
109
|
+
extensions:
|
|
110
|
+
- require: './extensions/my-extension.js'
|
|
111
|
+
option1: value1
|
|
112
|
+
option2: value2
|
|
113
|
+
----
|
|
114
|
+
|
|
115
|
+
=== Test
|
|
116
|
+
|
|
117
|
+
Run Antora and verify your extension works:
|
|
118
|
+
|
|
119
|
+
[,bash]
|
|
120
|
+
----
|
|
121
|
+
npx antora local-antora-playbook.yml
|
|
122
|
+
----
|
|
123
|
+
|
|
124
|
+
== Common patterns
|
|
125
|
+
|
|
126
|
+
=== Accessing content
|
|
127
|
+
|
|
128
|
+
Get all pages:
|
|
129
|
+
|
|
130
|
+
[,javascript]
|
|
131
|
+
----
|
|
132
|
+
this.on('contentClassified', ({ contentCatalog }) => {
|
|
133
|
+
const pages = contentCatalog.getPages()
|
|
134
|
+
|
|
135
|
+
pages.forEach(page => {
|
|
136
|
+
console.log(page.src.relative)
|
|
137
|
+
console.log(page.asciidoc) // AsciiDoc content
|
|
138
|
+
console.log(page.contents) // Converted HTML
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
----
|
|
142
|
+
|
|
143
|
+
Filter pages by component:
|
|
144
|
+
|
|
145
|
+
[,javascript]
|
|
146
|
+
----
|
|
147
|
+
const pages = contentCatalog.getPages(page =>
|
|
148
|
+
page.src.component === 'redpanda'
|
|
149
|
+
)
|
|
150
|
+
----
|
|
151
|
+
|
|
152
|
+
=== Creating new pages
|
|
153
|
+
|
|
154
|
+
Add a generated page to the catalog:
|
|
155
|
+
|
|
156
|
+
[,javascript]
|
|
157
|
+
----
|
|
158
|
+
this.on('contentClassified', ({ contentCatalog }) => {
|
|
159
|
+
const newPage = contentCatalog.addFile({
|
|
160
|
+
contents: Buffer.from('<h1>Generated Page</h1>'),
|
|
161
|
+
src: {
|
|
162
|
+
component: 'redpanda',
|
|
163
|
+
version: '1.0',
|
|
164
|
+
module: 'ROOT',
|
|
165
|
+
family: 'page',
|
|
166
|
+
relative: 'generated-page.adoc'
|
|
167
|
+
},
|
|
168
|
+
out: {
|
|
169
|
+
path: 'generated-page.html'
|
|
170
|
+
},
|
|
171
|
+
pub: {
|
|
172
|
+
url: '/generated-page.html'
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
// Set page attributes
|
|
177
|
+
newPage.asciidoc = {
|
|
178
|
+
attributes: {
|
|
179
|
+
'page-title': 'Generated Page'
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
----
|
|
184
|
+
|
|
185
|
+
=== Modifying pages
|
|
186
|
+
|
|
187
|
+
Update page content:
|
|
188
|
+
|
|
189
|
+
[,javascript]
|
|
190
|
+
----
|
|
191
|
+
this.on('documentsConverted', ({ contentCatalog }) => {
|
|
192
|
+
const pages = contentCatalog.getPages()
|
|
193
|
+
|
|
194
|
+
pages.forEach(page => {
|
|
195
|
+
if (page.asciidoc) {
|
|
196
|
+
// Modify AsciiDoc attributes
|
|
197
|
+
page.asciidoc.attributes['custom-attr'] = 'value'
|
|
198
|
+
|
|
199
|
+
// Modify HTML content
|
|
200
|
+
page.contents = Buffer.from(
|
|
201
|
+
page.contents.toString().replace(/old/g, 'new')
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
----
|
|
207
|
+
|
|
208
|
+
=== Working with components
|
|
209
|
+
|
|
210
|
+
Access component descriptors:
|
|
211
|
+
|
|
212
|
+
[,javascript]
|
|
213
|
+
----
|
|
214
|
+
this.on('contentAggregated', ({ contentAggregate }) => {
|
|
215
|
+
contentAggregate.forEach(aggregate => {
|
|
216
|
+
const { name, version, title } = aggregate
|
|
217
|
+
console.log(`Component: ${name} v${version}`)
|
|
218
|
+
|
|
219
|
+
// Access component files
|
|
220
|
+
aggregate.files.forEach(file => {
|
|
221
|
+
console.log(file.path)
|
|
222
|
+
})
|
|
223
|
+
})
|
|
224
|
+
})
|
|
225
|
+
----
|
|
226
|
+
|
|
227
|
+
=== Reading external data
|
|
228
|
+
|
|
229
|
+
Load external files or fetch data:
|
|
230
|
+
|
|
231
|
+
[,javascript]
|
|
232
|
+
----
|
|
233
|
+
const fs = require('fs')
|
|
234
|
+
const path = require('path')
|
|
235
|
+
|
|
236
|
+
module.exports.register = function ({ config }) {
|
|
237
|
+
this.on('contentClassified', ({ contentCatalog, playbook }) => {
|
|
238
|
+
const dataPath = path.join(playbook.dir, 'data', 'my-data.json')
|
|
239
|
+
const data = JSON.parse(fs.readFileSync(dataPath, 'utf8'))
|
|
240
|
+
|
|
241
|
+
// Use data to generate or modify content
|
|
242
|
+
})
|
|
243
|
+
}
|
|
244
|
+
----
|
|
245
|
+
|
|
246
|
+
Fetch data from APIs:
|
|
247
|
+
|
|
248
|
+
[,javascript]
|
|
249
|
+
----
|
|
250
|
+
const https = require('https')
|
|
251
|
+
|
|
252
|
+
function fetchData(url) {
|
|
253
|
+
return new Promise((resolve, reject) => {
|
|
254
|
+
https.get(url, (res) => {
|
|
255
|
+
let data = ''
|
|
256
|
+
res.on('data', chunk => data += chunk)
|
|
257
|
+
res.on('end', () => resolve(JSON.parse(data)))
|
|
258
|
+
res.on('error', reject)
|
|
259
|
+
})
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
module.exports.register = function ({ config }) {
|
|
264
|
+
this.on('contentClassified', async ({ contentCatalog }) => {
|
|
265
|
+
const data = await fetchData('https://api.example.com/data')
|
|
266
|
+
// Process data
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
----
|
|
270
|
+
|
|
271
|
+
=== Logging
|
|
272
|
+
|
|
273
|
+
Use the logger for debugging:
|
|
274
|
+
|
|
275
|
+
[,javascript]
|
|
276
|
+
----
|
|
277
|
+
const logger = this.getLogger('my-extension')
|
|
278
|
+
|
|
279
|
+
logger.error('Critical error message')
|
|
280
|
+
logger.warn('Warning message')
|
|
281
|
+
logger.info('Informational message')
|
|
282
|
+
logger.debug('Debug message')
|
|
283
|
+
----
|
|
284
|
+
|
|
285
|
+
Set log level in playbook:
|
|
286
|
+
|
|
287
|
+
[,yaml]
|
|
288
|
+
----
|
|
289
|
+
runtime:
|
|
290
|
+
log:
|
|
291
|
+
level: debug
|
|
292
|
+
----
|
|
293
|
+
|
|
294
|
+
=== Environment variables
|
|
295
|
+
|
|
296
|
+
Access environment variables:
|
|
297
|
+
|
|
298
|
+
[,javascript]
|
|
299
|
+
----
|
|
300
|
+
module.exports.register = function ({ config }) {
|
|
301
|
+
const apiKey = process.env.API_KEY || config.api_key
|
|
302
|
+
|
|
303
|
+
if (!apiKey) {
|
|
304
|
+
this.getLogger('my-extension').error('API_KEY not set')
|
|
305
|
+
return
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Use apiKey
|
|
309
|
+
}
|
|
310
|
+
----
|
|
311
|
+
|
|
312
|
+
== Best practices
|
|
313
|
+
|
|
314
|
+
=== Error handling
|
|
315
|
+
|
|
316
|
+
Always handle errors gracefully:
|
|
317
|
+
|
|
318
|
+
[,javascript]
|
|
319
|
+
----
|
|
320
|
+
this.on('contentClassified', ({ contentCatalog }) => {
|
|
321
|
+
try {
|
|
322
|
+
// Extension logic
|
|
323
|
+
} catch (err) {
|
|
324
|
+
const logger = this.getLogger('my-extension')
|
|
325
|
+
logger.error(`Error: ${err.message}`)
|
|
326
|
+
logger.debug(err.stack)
|
|
327
|
+
// Don't throw - let build continue
|
|
328
|
+
}
|
|
329
|
+
})
|
|
330
|
+
----
|
|
331
|
+
|
|
332
|
+
=== Performance
|
|
333
|
+
|
|
334
|
+
* Cache expensive operations
|
|
335
|
+
* Use async/await for I/O operations
|
|
336
|
+
* Avoid processing files multiple times
|
|
337
|
+
* Filter content early to reduce iterations
|
|
338
|
+
|
|
339
|
+
[,javascript]
|
|
340
|
+
----
|
|
341
|
+
// Good: Filter early
|
|
342
|
+
const relevantPages = contentCatalog.getPages(page =>
|
|
343
|
+
page.src.component === 'redpanda' && page.asciidoc
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
relevantPages.forEach(page => {
|
|
347
|
+
// Process only relevant pages
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
// Bad: Filter during iteration
|
|
351
|
+
const allPages = contentCatalog.getPages()
|
|
352
|
+
allPages.forEach(page => {
|
|
353
|
+
if (page.src.component === 'redpanda' && page.asciidoc) {
|
|
354
|
+
// Process
|
|
355
|
+
}
|
|
356
|
+
})
|
|
357
|
+
----
|
|
358
|
+
|
|
359
|
+
=== Testing
|
|
360
|
+
|
|
361
|
+
Test extensions independently:
|
|
362
|
+
|
|
363
|
+
[,javascript]
|
|
364
|
+
----
|
|
365
|
+
// extensions/__tests__/my-extension.test.js
|
|
366
|
+
const myExtension = require('../my-extension')
|
|
367
|
+
|
|
368
|
+
describe('my-extension', () => {
|
|
369
|
+
test('registers correctly', () => {
|
|
370
|
+
const context = {
|
|
371
|
+
on: jest.fn(),
|
|
372
|
+
getLogger: jest.fn(() => ({
|
|
373
|
+
info: jest.fn(),
|
|
374
|
+
error: jest.fn()
|
|
375
|
+
}))
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
myExtension.register.call(context, { config: {} })
|
|
379
|
+
|
|
380
|
+
expect(context.on).toHaveBeenCalled()
|
|
381
|
+
})
|
|
382
|
+
})
|
|
383
|
+
----
|
|
384
|
+
|
|
385
|
+
=== Documentation
|
|
386
|
+
|
|
387
|
+
Document your extension:
|
|
388
|
+
|
|
389
|
+
[,javascript]
|
|
390
|
+
----
|
|
391
|
+
/**
|
|
392
|
+
* My Extension
|
|
393
|
+
*
|
|
394
|
+
* Description of what the extension does.
|
|
395
|
+
*
|
|
396
|
+
* Configuration:
|
|
397
|
+
* @param {string} option1 - Description of option1
|
|
398
|
+
* @param {boolean} option2 - Description of option2 (required)
|
|
399
|
+
*
|
|
400
|
+
* Environment variables:
|
|
401
|
+
* - MY_VAR: Description
|
|
402
|
+
*
|
|
403
|
+
* Example:
|
|
404
|
+
* antora:
|
|
405
|
+
* extensions:
|
|
406
|
+
* - require: './extensions/my-extension.js'
|
|
407
|
+
* option1: value
|
|
408
|
+
* option2: true
|
|
409
|
+
*/
|
|
410
|
+
module.exports.register = function ({ config }) {
|
|
411
|
+
// Implementation
|
|
412
|
+
}
|
|
413
|
+
----
|
|
414
|
+
|
|
415
|
+
=== Code organization
|
|
416
|
+
|
|
417
|
+
For complex extensions, split into modules:
|
|
418
|
+
|
|
419
|
+
----
|
|
420
|
+
extensions/
|
|
421
|
+
my-extension/
|
|
422
|
+
index.js # Main extension file
|
|
423
|
+
processor.js # Processing logic
|
|
424
|
+
generator.js # Content generation
|
|
425
|
+
utils.js # Utility functions
|
|
426
|
+
----
|
|
427
|
+
|
|
428
|
+
== Debugging
|
|
429
|
+
|
|
430
|
+
=== Enable debug logging
|
|
431
|
+
|
|
432
|
+
[,bash]
|
|
433
|
+
----
|
|
434
|
+
ANTORA_LOG_LEVEL=debug npx antora playbook.yml
|
|
435
|
+
----
|
|
436
|
+
|
|
437
|
+
=== Use console.log sparingly
|
|
438
|
+
|
|
439
|
+
Prefer the logger:
|
|
440
|
+
|
|
441
|
+
[,javascript]
|
|
442
|
+
----
|
|
443
|
+
// Good
|
|
444
|
+
const logger = this.getLogger('my-extension')
|
|
445
|
+
logger.debug('Debug info')
|
|
446
|
+
|
|
447
|
+
// Avoid
|
|
448
|
+
console.log('Debug info')
|
|
449
|
+
----
|
|
450
|
+
|
|
451
|
+
=== Inspect objects
|
|
452
|
+
|
|
453
|
+
[,javascript]
|
|
454
|
+
----
|
|
455
|
+
const util = require('util')
|
|
456
|
+
|
|
457
|
+
console.log(util.inspect(object, { depth: null, colors: true }))
|
|
458
|
+
----
|
|
459
|
+
|
|
460
|
+
== Related documentation
|
|
461
|
+
|
|
462
|
+
* link:USER_GUIDE.adoc[User guide] - How to use extensions
|
|
463
|
+
* link:REFERENCE.adoc[Reference] - Complete extension documentation
|
|
464
|
+
* https://docs.antora.org/antora/latest/extend/extensions/[Antora Extensions API]
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
= Antora Extensions
|
|
2
|
+
:toc:
|
|
3
|
+
:toclevels: 2
|
|
4
|
+
|
|
5
|
+
Documentation for Antora extensions that enhance the documentation build process.
|
|
6
|
+
|
|
7
|
+
== What are Antora extensions?
|
|
8
|
+
|
|
9
|
+
Antora extensions are Node.js modules that extend Antora's capabilities during the documentation site build. These extensions can modify content, generate new pages, integrate with external services, and customize the build pipeline.
|
|
10
|
+
|
|
11
|
+
== Documentation
|
|
12
|
+
|
|
13
|
+
link:USER_GUIDE.adoc[**User guide**]:: How to use and configure Antora extensions in your playbook
|
|
14
|
+
+
|
|
15
|
+
* Installation and setup
|
|
16
|
+
* Configuring extensions
|
|
17
|
+
* Common usage patterns
|
|
18
|
+
* Troubleshooting
|
|
19
|
+
|
|
20
|
+
link:REFERENCE.adoc[**Reference**]:: Complete reference for all available extensions
|
|
21
|
+
+
|
|
22
|
+
* Extension descriptions
|
|
23
|
+
* Configuration options
|
|
24
|
+
* Environment variables
|
|
25
|
+
* Examples for each extension
|
|
26
|
+
|
|
27
|
+
link:DEVELOPMENT.adoc[**Development guide**]:: How to develop new Antora extensions
|
|
28
|
+
+
|
|
29
|
+
* Extension architecture
|
|
30
|
+
* Creating new extensions
|
|
31
|
+
* Testing and debugging
|
|
32
|
+
* Best practices
|
|
33
|
+
|
|
34
|
+
== Quickstart
|
|
35
|
+
|
|
36
|
+
=== Install the package
|
|
37
|
+
|
|
38
|
+
[,bash]
|
|
39
|
+
----
|
|
40
|
+
npm i @redpanda-data/docs-extensions-and-macros
|
|
41
|
+
----
|
|
42
|
+
|
|
43
|
+
=== Configure in your playbook
|
|
44
|
+
|
|
45
|
+
[,yaml]
|
|
46
|
+
----
|
|
47
|
+
antora:
|
|
48
|
+
extensions:
|
|
49
|
+
- '@redpanda-data/docs-extensions-and-macros/extensions/version-fetcher/set-latest-version'
|
|
50
|
+
----
|
|
51
|
+
|
|
52
|
+
IMPORTANT: Extensions must be registered under the `antora.extensions` key in your playbook, not `asciidoc.extensions`.
|
|
53
|
+
|
|
54
|
+
== Available extensions
|
|
55
|
+
|
|
56
|
+
=== Version management
|
|
57
|
+
* **set-latest-version** - Automatically fetch latest versions from GitHub releases
|
|
58
|
+
|
|
59
|
+
=== Content generation
|
|
60
|
+
* **generate-index-data** - Generate searchable indexes from content
|
|
61
|
+
* **generate-rp-connect-categories** - Generate Redpanda Connect component categories
|
|
62
|
+
* **generate-rp-connect-info** - Generate Redpanda Connect component information
|
|
63
|
+
|
|
64
|
+
=== Navigation
|
|
65
|
+
* **unlisted-pages** - Manage pages that appear in navigation but aren't listed
|
|
66
|
+
* **produce-redirects** - Generate redirect configurations
|
|
67
|
+
* **unpublish-pages** - Mark pages as unpublished
|
|
68
|
+
|
|
69
|
+
=== Integrations
|
|
70
|
+
* **algolia-indexer** - Index content for Algolia search
|
|
71
|
+
* **compute-end-of-life** - Calculate and display EOL information
|
|
72
|
+
* **find-related-docs** - Find and link related documentation
|
|
73
|
+
* **find-related-labs** - Find and link related lab exercises
|
|
74
|
+
|
|
75
|
+
=== File processing
|
|
76
|
+
* **archive-attachments** - Archive file attachments
|
|
77
|
+
* **replace-attributes-in-attachments** - Replace AsciiDoc attributes in attached files
|
|
78
|
+
* **collect-bloblang-samples** - Collect Bloblang code samples
|
|
79
|
+
|
|
80
|
+
=== Content enhancement
|
|
81
|
+
* **add-global-attributes** - Add attributes globally to all pages
|
|
82
|
+
* **add-pages-to-root** - Add pages to the root navigation
|
|
83
|
+
* **process-context-switcher** - Handle context-dependent content
|
|
84
|
+
* **validate-attributes** - Validate AsciiDoc attributes
|
|
85
|
+
|
|
86
|
+
See link:REFERENCE.adoc[Reference documentation] for complete details on each extension.
|
|
87
|
+
|
|
88
|
+
== Common use cases
|
|
89
|
+
|
|
90
|
+
=== Automatically update version numbers
|
|
91
|
+
|
|
92
|
+
[,yaml]
|
|
93
|
+
----
|
|
94
|
+
antora:
|
|
95
|
+
extensions:
|
|
96
|
+
- '@redpanda-data/docs-extensions-and-macros/extensions/version-fetcher/set-latest-version'
|
|
97
|
+
----
|
|
98
|
+
|
|
99
|
+
=== Enable Algolia search
|
|
100
|
+
|
|
101
|
+
[,yaml]
|
|
102
|
+
----
|
|
103
|
+
antora:
|
|
104
|
+
extensions:
|
|
105
|
+
- require: '@redpanda-data/docs-extensions-and-macros/extensions/algolia-indexer'
|
|
106
|
+
algolia_app_id: YOUR_APP_ID
|
|
107
|
+
algolia_api_key: YOUR_API_KEY
|
|
108
|
+
algolia_index_name: YOUR_INDEX
|
|
109
|
+
----
|
|
110
|
+
|
|
111
|
+
=== Generate redirects
|
|
112
|
+
|
|
113
|
+
[,yaml]
|
|
114
|
+
----
|
|
115
|
+
antora:
|
|
116
|
+
extensions:
|
|
117
|
+
- '@redpanda-data/docs-extensions-and-macros/extensions/produce-redirects.js'
|
|
118
|
+
----
|
|
119
|
+
|
|
120
|
+
== Support
|
|
121
|
+
|
|
122
|
+
* link:USER_GUIDE.adoc#troubleshooting[Troubleshooting guide]
|
|
123
|
+
* https://github.com/redpanda-data/docs-extensions-and-macros/issues[Report issues]
|
|
124
|
+
* https://docs.antora.org/antora/latest/extend/extensions/[Antora Extensions Documentation]
|