Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/cli/cli-reference-how-to.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ toc:
folder: cli-reference
```

Use `title:` to customize the generated CLI root page title, and `navigation_title:` to customize the sidebar and breadcrumb label without changing generated command examples:

```yaml
toc:
- cli: cli-schema.json
folder: cli-reference
title: Elastic CLI reference
navigation_title: CLI reference
```

Use `children:` to prepend hand-written pages — installation guides, conceptual overviews, or quick-start tutorials — before the auto-generated reference. All schema-generated pages follow the listed children:

```yaml
Expand Down Expand Up @@ -101,4 +111,6 @@ Your CLI reference section is live. As your CLI evolves, regenerate the schema a
|---|---|
| `cli: <path>` | Path to the schema JSON, relative to `docset.yml` |
| `folder: <path>` | Supplemental docs folder; also sets the URL prefix |
| `title: <title>` | Optional generated CLI root page title |
| `navigation_title: <title>` | Optional generated CLI root navigation label |
| `children:` | Regular toc items prepended before generated pages |
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace Elastic.Documentation.Configuration.Toc.CliReference;
public record CliReferenceRef(
string SchemaPath,
string? SupplementalFolder,
string? Title,
string? NavigationTitle,
string PathRelativeToDocumentationSet,
string PathRelativeToContainer,
string Context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ private static ITableOfContentsItem ResolveRuleOverviewReference(IDiagnosticsCol
? ResolveTableOfContents(collector, cliRef.Children, baseDirectory, fileSystem, fullVirtualRoot, containerPath, context)
: [];

return new CliReferenceRef(schemaFullPath, cliRef.SupplementalFolder, fullVirtualRoot, pathRelativeToContainer, context, resolvedChildren);
return new CliReferenceRef(schemaFullPath, cliRef.SupplementalFolder, cliRef.Title, cliRef.NavigationTitle, fullVirtualRoot, pathRelativeToContainer, context, resolvedChildren);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ public class TocItemYamlConverter : IYamlTypeConverter
if (dictionary.TryGetValue("cli", out var cliSchemaPath) && cliSchemaPath is string cliSchema)
{
var supplementalFolder = dictionary.TryGetValue("folder", out var f) && f is string fStr ? fStr : null;
return new CliReferenceRef(cliSchema, supplementalFolder, cliSchema, cliSchema, placeholderContext, children);
var title = dictionary.TryGetValue("title", out var t) && t is string titleStr ? titleStr : null;
var navigationTitle = dictionary.TryGetValue("navigation_title", out var nt) && nt is string navigationTitleStr ? navigationTitleStr : null;
return new CliReferenceRef(cliSchema, supplementalFolder, title, navigationTitle, cliSchema, cliSchema, placeholderContext, children);
}

// Check for folder+file combination (e.g., folder: getting-started, file: getting-started.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ namespace Elastic.Markdown.Extensions.CliReference;

internal static partial class CliMarkdownGenerator
{
public static string RootPage(CliSchema schema, CliSupplementalDoc? supplemental)
public static string RootPage(CliSchema schema, CliSupplementalDoc? supplemental, string? title = null)
{
var sb = new StringBuilder();
AppendFrontMatter(sb, supplemental);
_ = sb.AppendLine($"# {schema.Name}");
var pageTitle = string.IsNullOrWhiteSpace(title) ? schema.Name : title.Trim();
_ = sb.AppendLine($"# {pageTitle}");
_ = sb.AppendLine();

var description = supplemental?.Description ?? schema.Description?.Trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ internal sealed record CliEntityInfo(
/// <summary>Ancestor namespace options ordered from closest to furthest (direct parent first).</summary>
IReadOnlyList<(string Segment, List<CliParamSchema>? Options)>? AncestorNamespaceOptions = null,
/// <summary>Relative path from this file to the alias target — set for CliShortcutSchema entities only.</summary>
string? AliasCanonicalRelativePath = null
string? AliasCanonicalRelativePath = null,
/// <summary>Display title for the generated CLI root page.</summary>
string? Title = null,
/// <summary>Navigation title for the generated CLI root page.</summary>
string? NavigationTitle = null
);

public class CliReferenceDocsBuilderExtension(BuildContext build) : IDocsBuilderExtension
Expand Down Expand Up @@ -113,7 +117,7 @@ private void EnsureSyntheticFilesBuilt()
private MarkdownFile? CreateCliFileFromInfo(IFileInfo sourceFile, MarkdownParser markdownParser, CliEntityInfo info) =>
info.Entity switch
{
CliSchema schema => new CliRootFile(sourceFile, Build.DocumentationSourceDirectory, markdownParser, Build, schema, info.SupplementalDoc),
CliSchema schema => new CliRootFile(sourceFile, Build.DocumentationSourceDirectory, markdownParser, Build, schema, info.SupplementalDoc, info.Title, info.NavigationTitle),
CliNamespaceSchema ns => new CliNamespaceFile(sourceFile, Build.DocumentationSourceDirectory, markdownParser, Build, ns, info.SupplementalDoc, info.FullPath ?? [ns.Segment], info.Schema.Name, info.Schema.ReservedMetaCommands, info.Schema.Shortcuts),
CliCommandSchema cmd => new CliCommandFile(sourceFile, Build.DocumentationSourceDirectory, markdownParser, Build, cmd, info.SupplementalDoc, info.FullPath ?? [cmd.Name], info.Schema.Name, info.Schema.ReservedMetaCommands, info.AncestorNamespaceOptions, info.Schema.GlobalOptions, info.Schema.Shortcuts),
CliShortcutSchema shortcut => new CliAliasFile(sourceFile, Build.DocumentationSourceDirectory, markdownParser, Build, shortcut, info.Schema.Name, info.AliasCanonicalRelativePath ?? "../"),
Expand Down Expand Up @@ -186,7 +190,7 @@ private List<IFileInfo> BuildSyntheticFiles()
var rootSupplemental = FindSupplemental(supplementalDirPath, [], isNamespace: true, matched);
var rootSyntheticPath = SyntheticPath(Build.DocumentationSourceDirectory.FullName, virtualRoot, [], isNamespace: true);
var rootFileInfo = Build.ReadFileSystem.FileInfo.New(rootSyntheticPath);
var rootInfo = new CliEntityInfo(schema, schema, rootSupplemental, rootFileInfo);
var rootInfo = new CliEntityInfo(schema, schema, rootSupplemental, rootFileInfo, Title: cliRef.Title, NavigationTitle: cliRef.NavigationTitle);
_syntheticFiles![rootSyntheticPath] = rootInfo;
if (rootSupplemental != null)
_supplementalFiles![rootSupplemental.FullName] = rootInfo;
Expand Down
16 changes: 11 additions & 5 deletions src/Elastic.Markdown/Extensions/CliReference/CliRootFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,32 @@ public record CliRootFile : IO.MarkdownFile
{
private readonly CliSchema _schema;
private readonly IFileInfo? _supplementalDoc;
private readonly string _title;
private readonly string _navigationTitle;

public CliRootFile(
IFileInfo sourceFile,
IDirectoryInfo rootPath,
MarkdownParser parser,
BuildContext build,
CliSchema schema,
IFileInfo? supplementalDoc
IFileInfo? supplementalDoc,
string? title = null,
string? navigationTitle = null
) : base(sourceFile, rootPath, parser, build)
{
_schema = schema;
_supplementalDoc = supplementalDoc;
Title = schema.Name;
_title = string.IsNullOrWhiteSpace(title) ? schema.Name : title;
_navigationTitle = string.IsNullOrWhiteSpace(navigationTitle) ? $"{schema.Name} CLI" : navigationTitle;
Title = _title;
}

public override string NavigationTitle => $"{_schema.Name} CLI";
public override string NavigationTitle => _navigationTitle;

protected override Task<MarkdownDocument> GetMinimalParseDocumentAsync(Cancel ctx)
{
Title = _schema.Name;
Title = _title;
var markdown = BuildMarkdown();
return Task.FromResult(MarkdownParser.MinimalParseStringAsync(markdown, SourceFile, null));
}
Expand All @@ -50,6 +56,6 @@ private string BuildMarkdown()
? _supplementalDoc.FileSystem.File.ReadAllText(_supplementalDoc.FullName)
: null;
var supplemental = CliSupplementalDoc.Parse(rawSupplemental);
return CliMarkdownGenerator.RootPage(_schema, supplemental);
return CliMarkdownGenerator.RootPage(_schema, supplemental, _title);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@ namespace Elastic.Documentation.Configuration.Tests;

public class PhysicalDocsetTests
{
[Fact]
public void CliReferenceRefReadsTitleOverrides()
{
const string yaml = """
project: test
toc:
- cli: cli/schema.json
folder: cli
title: Elastic CLI reference
navigation_title: CLI reference
""";

var docSet = ConfigurationFileProvider.Deserializer.Deserialize<DocumentationSetFile>(yaml);
var cliRef = docSet.TableOfContents.OfType<CliReferenceRef>().Single();

cliRef.Title.Should().Be("Elastic CLI reference");
cliRef.NavigationTitle.Should().Be("CLI reference");
}

[Fact]
public void PhysicalDocsetFileCanBeDeserialized()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using AwesomeAssertions;
using Elastic.Documentation.Configuration.Toc.CliReference;
using Elastic.Markdown.Extensions.CliReference;

namespace Elastic.Markdown.Tests.CliReference;

public class CliMarkdownGeneratorTests
{
[Fact]
public void RootPage_UsesTitleOverrideForHeading()
{
var schema = new CliSchema(
SchemaVersion: 1,
Name: "elastic",
Description: "Interact with Elastic from the command line.",
GlobalOptions: [],
RootDefault: null,
Commands: [],
Namespaces: []
);

var markdown = CliMarkdownGenerator.RootPage(schema, null, "Elastic CLI reference");

markdown.Should().StartWith("# Elastic CLI reference");
markdown.Should().Contain("Interact with Elastic from the command line.");
}

[Theory]
[InlineData("")]
[InlineData(" ")]
public void RootPage_FallsBackToSchemaNameForBlankTitleOverride(string title)
{
var schema = new CliSchema(
SchemaVersion: 1,
Name: "elastic",
Description: "Interact with Elastic from the command line.",
GlobalOptions: [],
RootDefault: null,
Commands: [],
Namespaces: []
);

var markdown = CliMarkdownGenerator.RootPage(schema, null, title);

markdown.Should().StartWith("# elastic");
}
}
Loading