diff --git a/docs/syntax/titles.md b/docs/syntax/titles.md index ab8ffb0a0b..ab19c7dc3d 100644 --- a/docs/syntax/titles.md +++ b/docs/syntax/titles.md @@ -4,28 +4,48 @@ navigation_title: Title # Page title -### Syntax +## Syntax -Each page is required to at least define a level one heading. +Each page must define a level-one heading. ```markdown # This is my title ``` -This title is used both by the documentation navigation +The heading supplies the visible page title, link text, and the default HTML page title. +For public Elastic Docs builds, the builder appends `| Elastic Docs` to the HTML title. -* Left hand site -* Navigational elements such as breadcrumbs and previous/next links. - -As well as when using the [auto text links](./links.md#same-page-links-anchors), e.g: +When the page resolves to exactly one product and the heading does not already contain +that product's display name, the builder adds the product name automatically. Product +resolution merges page frontmatter with docset, repository, `applies_to`, and `mapped_pages` +metadata: ```markdown -[](titles.md) +--- +products: + - id: elasticsearch +--- + +# Query DSL ``` -Generated link text: [](titles.md) +The resulting HTML title is `Query DSL - Elasticsearch | Elastic Docs`, while the +visible heading remains `Query DSL`. Pages associated with multiple products keep the +heading as their default HTML title because the builder cannot choose one product keyword. + +API operation pages use the related form `{H1} - {Product} API | Elastic Docs`. +The heading is also used by: + +* The left navigation. +* Navigational elements, such as breadcrumbs and previous and next links. +* [Automatic link text](./links.md#same-page-links-anchors). + +```markdown +[](titles.md) +``` +Generated link text: [](titles.md). ```markdown --- diff --git a/src/Elastic.ApiExplorer/Infrastructure/ApiViewModel.cs b/src/Elastic.ApiExplorer/Infrastructure/ApiViewModel.cs index 6ce5455f1a..14652e56d2 100644 --- a/src/Elastic.ApiExplorer/Infrastructure/ApiViewModel.cs +++ b/src/Elastic.ApiExplorer/Infrastructure/ApiViewModel.cs @@ -77,7 +77,9 @@ public ApiLayoutViewModel CreateGlobalLayoutModel() { var docTitle = Document.Info?.Title ?? "API Documentation"; var pageTitle = LayoutPageTitle; - var documentTitle = pageTitle is not null ? $"{pageTitle} | {docTitle}" : docTitle; + var documentTitle = BuildContext.BuildType == BuildType.Assembler && BuildContext.Configuration.Branding is null + ? $"{pageTitle ?? docTitle} | Elastic Docs" + : pageTitle is not null ? $"{pageTitle} | {docTitle}" : docTitle; return new() { diff --git a/src/Elastic.ApiExplorer/Operations/OperationViewModel.cs b/src/Elastic.ApiExplorer/Operations/OperationViewModel.cs index 22880fb562..4b0bb8887d 100644 --- a/src/Elastic.ApiExplorer/Operations/OperationViewModel.cs +++ b/src/Elastic.ApiExplorer/Operations/OperationViewModel.cs @@ -26,6 +26,17 @@ public class OperationViewModel(ApiRenderContext context) : ApiViewModel(context public IReadOnlyList PrerequisiteNames => [.. (Prerequisites ?? []).Select(static r => r.Label).Where(static l => l.Length > 0)]; + protected override string? LayoutPageTitle + { + get + { + var title = string.IsNullOrWhiteSpace(Operation.Operation.Summary) + ? CurrentNavigationItem.NavigationTitle + : Operation.Operation.Summary; + return RenderContext.Product?.DisplayName is { Length: > 0 } product ? $"{title} - {product} API" : title; + } + } + protected override string BreadcrumbCurrentTitle => Operation.Operation.Summary ?? CurrentNavigationItem.NavigationTitle; protected override IReadOnlyList GetTocItems() diff --git a/src/Elastic.Markdown/Exporters/Pagefind/PagefindMarkdownExporter.cs b/src/Elastic.Markdown/Exporters/Pagefind/PagefindMarkdownExporter.cs index f97686ebfe..908dd176e5 100644 --- a/src/Elastic.Markdown/Exporters/Pagefind/PagefindMarkdownExporter.cs +++ b/src/Elastic.Markdown/Exporters/Pagefind/PagefindMarkdownExporter.cs @@ -10,6 +10,7 @@ using Elastic.Markdown.Helpers; using Elastic.Markdown.IO; using Elastic.Markdown.Myst.InlineParsers; +using Elastic.Markdown.Page; using Markdig.Syntax; using Microsoft.Extensions.Logging; using Pagefind.Net; @@ -55,7 +56,23 @@ public ValueTask ExportAsync(MarkdownExportFileContext fileContext, Cancel var parents = navigation.GetParentsOfMarkdownFile(file).Reverse().ToArray(); var breadcrumbsMeta = BuildBreadcrumbsMeta(parents, fileContext.BuildContext.CanonicalBaseUrl); - var meta = new Dictionary { ["title"] = file.Title ?? url }; + var inference = fileContext.InferenceService.InferForMarkdown( + fileContext.BuildContext.Git.RepositoryName, + file.YamlFrontMatter?.MappedPages, + fileContext.DocumentationSet.Configuration.Products, + file.YamlFrontMatter?.Products, + file.YamlFrontMatter?.AppliesTo + ); + var title = PageTitleResolver.Resolve( + file.Title ?? url, + inference.RelatedProducts, + new( + fileContext.BuildContext.BuildType, + fileContext.DocumentationSet.Configuration.Branding, + fileContext.DocumentationSet.Navigation.NavigationTitle + ) + ); + var meta = new Dictionary { ["title"] = title }; if (!string.IsNullOrEmpty(breadcrumbsMeta)) meta["breadcrumbs"] = breadcrumbsMeta; diff --git a/src/Elastic.Markdown/Page/Index.cshtml b/src/Elastic.Markdown/Page/Index.cshtml index 39c9776b28..77370770a4 100644 --- a/src/Elastic.Markdown/Page/Index.cshtml +++ b/src/Elastic.Markdown/Page/Index.cshtml @@ -16,7 +16,7 @@ Layout = Model.CurrentDocument.YamlFrontMatter?.Layout, RenderHamburgerIcon = Model.CurrentDocument.YamlFrontMatter?.Layout != MarkdownPageLayout.LandingPage, DocSetName = Model.DocSetName, - Title = $"{Model.Title} | {Model.SiteName}", + Title = Model.PageTitle, Description = Model.Description, PageTocItems = Model.PageTocItems.Where(i => i is { @@ -72,7 +72,7 @@ } - +