Skip to content

Commit 8df9149

Browse files
authored
Refactor markdown and layout rendering by decoupling from GlobalLayoutViewModel. Streamline layout handling, enhance navigation item visibility logic, and rework documentation file structures for improved maintainability. (#1353)
* Refactor markdown and layout rendering by decoupling from `GlobalLayoutViewModel`. Streamline layout handling, enhance navigation item visibility logic, and rework documentation file structures for improved maintainability. `Hidden` is a pure navigation property now as its removed from `MarkdownFile`. `GetCurrentNavigation()` is now non nullable * Ensure NavigationIndex is a navigation property. * Update advertising of landing-page-path * update landing page path output * Add xmldocs for IsPhantom
1 parent 66e27aa commit 8df9149

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+352
-314
lines changed

src/Elastic.ApiExplorer/Endpoints/ApiEndpoint.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,13 @@ public EndpointNavigationItem(int depth, string url, ApiEndpoint apiEndpoint, La
5858
public ApiEndpoint Index { get; }
5959
public string Url { get; }
6060
public string NavigationTitle { get; }
61+
public bool Hidden => false;
6162

6263
public IReadOnlyCollection<OperationNavigationItem> NavigationItems { get; set; } = [];
6364

6465
public INodeNavigationItem<INavigationModel, INavigationItem> NavigationRoot { get; }
6566

6667
public INodeNavigationItem<INavigationModel, INavigationItem>? Parent { get; set; }
68+
69+
public int NavigationIndex { get; set; }
6770
}

src/Elastic.ApiExplorer/Endpoints/EndpointView.cshtml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,15 @@
77
{
88
DocSetName = "Api Explorer",
99
Description = "",
10-
Layout = null,
11-
PageTocItems = [],
1210
CurrentNavigationItem = Model.CurrentNavigationItem,
1311
Previous = null,
1412
Next = null,
1513
NavigationHtml = Model.NavigationHtml,
16-
LegacyPage = null,
1714
UrlPathPrefix = null,
18-
GithubEditUrl = null,
19-
ReportIssueUrl = null,
2015
AllowIndexing = false,
2116
CanonicalBaseUrl = null,
2217
GoogleTagManager = new GoogleTagManagerConfiguration(),
2318
Features = new FeatureFlags([]),
24-
Parents =
25-
[
26-
],
27-
Products = null,
2819
StaticFileContentHashProvider = Model.StaticFileContentHashProvider
2920
};
3021
}

src/Elastic.ApiExplorer/Landing/LandingNavigationItem.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ public class LandingNavigationItem : INodeNavigationItem<ApiLanding, EndpointNav
3434
public int Depth { get; }
3535
public ApiLanding Index { get; }
3636
public INodeNavigationItem<INavigationModel, INavigationItem>? Parent { get; set; }
37+
public int NavigationIndex { get; set; }
3738
public IReadOnlyCollection<EndpointNavigationItem> NavigationItems { get; set; } = [];
3839
public string Url { get; }
40+
public bool Hidden => false;
3941

4042
//TODO
4143
public string NavigationTitle { get; } = "API Documentation";

src/Elastic.ApiExplorer/Landing/LandingView.cshtml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,15 @@
77
{
88
DocSetName = "Api Explorer",
99
Description = "",
10-
Layout = null,
11-
PageTocItems = [],
1210
CurrentNavigationItem = Model.CurrentNavigationItem,
1311
Previous = null,
1412
Next = null,
1513
NavigationHtml = Model.NavigationHtml,
16-
LegacyPage = null,
1714
UrlPathPrefix = null,
18-
GithubEditUrl = null,
19-
ReportIssueUrl = null,
2015
AllowIndexing = false,
2116
CanonicalBaseUrl = null,
2217
GoogleTagManager = new GoogleTagManagerConfiguration(),
2318
Features = new FeatureFlags([]),
24-
Parents =
25-
[
26-
],
27-
Products = null,
2819
StaticFileContentHashProvider = Model.StaticFileContentHashProvider
2920
};
3021
}

src/Elastic.ApiExplorer/Operations/OperationNavigationItem.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,12 @@ public OperationNavigationItem(int depth, string url, ApiOperation apiOperation,
4747
public int Depth { get; }
4848
public ApiOperation Model { get; }
4949
public string Url { get; }
50+
public bool Hidden => false;
5051

5152
public string NavigationTitle { get; }
5253

5354
public INodeNavigationItem<INavigationModel, INavigationItem>? Parent { get; set; }
55+
56+
public int NavigationIndex { get; set; }
57+
5458
}

src/Elastic.ApiExplorer/Operations/OperationView.cshtml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,15 @@
77
{
88
DocSetName = "Api Explorer",
99
Description = "",
10-
Layout = null,
11-
PageTocItems = [],
1210
CurrentNavigationItem = Model.CurrentNavigationItem,
1311
Previous = null,
1412
Next = null,
1513
NavigationHtml = Model.NavigationHtml,
16-
LegacyPage = null,
1714
UrlPathPrefix = null,
18-
GithubEditUrl = null,
19-
ReportIssueUrl = null,
2015
AllowIndexing = false,
2116
CanonicalBaseUrl = null,
2217
GoogleTagManager = new GoogleTagManagerConfiguration(),
2318
Features = new FeatureFlags([]),
24-
Parents =
25-
[
26-
],
27-
Products = null,
2819
StaticFileContentHashProvider = Model.StaticFileContentHashProvider
2920
};
3021
}

src/Elastic.Documentation.Configuration/TableOfContents/ITocItem.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,20 @@ public record TocReference(Uri Source, ITableOfContentsScope TableOfContentsScop
2222
{
2323
public IReadOnlyDictionary<Uri, TocReference> TocReferences { get; } =
2424
Children.OfType<TocReference>().ToDictionary(kv => kv.Source, kv => kv);
25+
26+
/// <summary>
27+
/// A phantom table of contents is a table of contents that is not rendered in the UI but is used to generate the TOC.
28+
/// This should be used sparingly and needs explicit configuration in navigation.yml.
29+
/// It's typically used for container TOC that holds various other TOC's where its children are rehomed throughout the navigation.
30+
/// <para>Examples of phantom toc's:</para>
31+
/// <list type="">
32+
/// <item> - toc: elasticsearch://reference</item>
33+
/// <item> - toc: docs-content://</item>
34+
/// </list>
35+
/// <para>Because navigation.yml does exhaustive checks to ensure all toc.yml files are referenced, marking these containers as phantoms
36+
/// ensures that these skip validation checks
37+
/// </para>
38+
/// </summary>
39+
public bool IsPhantom { get; init; }
2540
}
41+

src/Elastic.Documentation.Site/Layout/_Head.cshtml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
@inherits RazorSlice<Elastic.Documentation.Site.GlobalLayoutViewModel>
22
@using FontPreloader = Elastic.Documentation.Site.FileProviders.FontPreloader
3-
<head hx-head="merge">
43
<meta charset="utf-8">
54
<title>@Model.Title</title>
65
<meta name="description" content="@Model.Description">
@@ -35,9 +34,3 @@
3534
{
3635
<meta property="og:url" content="@Model.CanonicalUrl" />
3736
}
38-
@if (!string.IsNullOrEmpty(Model.Products))
39-
{
40-
<meta class="elastic" name="product_name" content="@(Model.Products)"/>
41-
<meta name="DC.subject" content="@(Model.Products)"/>
42-
}
43-
</head>

src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<nav id="secondary-nav" class="bg-grey-10 border-t-1 border-grey-20 font-sans font-semibold text-sm text-ink-light md:text-base">
33
<div class="max-w-(--max-layout-width) flex mx-auto justify-between items-center p-6">
44
<div class="flex gap-2 flex-nowrap items-center">
5-
@if (Model.Layout != LayoutName.LandingPage)
5+
@if (Model.RenderHamburgerIcon)
66
{
77
@* ReSharper disable once Html.IdNotResolved *@
88
<label role="button" class="md:hidden cursor-pointer" for="pages-nav-hamburger">

src/Elastic.Documentation.Site/Navigation/INavigationItem.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public interface INavigationItem
3030
/// TODO: This should be read-only however currently needs the setter in assembler.
3131
/// </remarks>
3232
INodeNavigationItem<INavigationModel, INavigationItem>? Parent { get; set; }
33+
34+
bool Hidden { get; }
35+
36+
int NavigationIndex { get; set; }
3337
}
3438

3539
/// Represents a leaf node in the navigation tree with associated model data.

src/Elastic.Documentation.Site/Navigation/_TocTreeNav.cshtml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
}
66
@foreach (var item in Model.SubTree.NavigationItems)
77
{
8+
if (item.Hidden)
9+
{
10+
continue;
11+
}
812
if (item is INodeNavigationItem<INavigationModel, INavigationItem> { NavigationItems.Count: 0, Index: not null } group)
913
{
1014
<li class="flex group/li pr-8 @(isTopLevel ? "font-semibold mt-6" : "mt-4")">
Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
@inherits RazorLayoutSlice<GlobalLayoutViewModel>
22
<!DOCTYPE html>
33
<html lang="en" class="h-screen" xmlns="http://www.w3.org/1999/html">
4-
@await RenderPartialAsync(_Head.Create(Model))
5-
6-
@{
7-
var layout = Model.Layout;
8-
}
4+
<head hx-head="merge">
5+
@await RenderPartialAsync(_Head.Create(Model))
6+
@await RenderSectionAsync(GlobalSections.Head)
7+
</head>
98

109
<body
1110
class="group/body text-ink has-[#primary-nav-hamburger:checked]:overflow-hidden"
@@ -18,38 +17,9 @@
1817
}
1918
@(await RenderPartialAsync(_Header.Create(Model)))
2019
<div id="main-container" class="flex flex-col items-center border-t-1 border-grey-20">
21-
@switch (layout)
22-
{
23-
case LayoutName.NotFound:
24-
await RenderPartialAsync(_NotFound.Create(Model));
25-
break;
26-
case LayoutName.LandingPage:
27-
await RenderPartialAsync(_LandingPage.Create(Model));
28-
break;
29-
case LayoutName.Archive:
30-
await RenderPartialAsync(_Archive.Create(Model));
31-
break;
32-
default:
33-
await RenderBodyAsync();
34-
break;
35-
}
20+
@(await RenderBodyAsync())
3621
</div>
3722
@await RenderPartialAsync(_Footer.Create(Model))
38-
@if (layout is not LayoutName.Archive)
39-
{
40-
<aside id="dismissible-banner" class="admonition tip">
41-
<div class="container flex justify-between items-center mx-auto">
42-
<p>
43-
Welcome to the docs for the <a class="link text-base" href="/docs/get-started/versioning-availability#find-docs-for-your-product-version">latest Elastic product versions</a>, including Elastic Stack 9.0 and Elastic Cloud Serverless.
44-
To view previous versions, go to <a class="link text-base" target="_blank" href="https://elastic.co/guide">elastic.co/guide</a>.
45-
</p>
46-
<button id="dismissible-button">
47-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
48-
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>
49-
</svg>
50-
</button>
51-
</div>
52-
</aside>
53-
}
23+
@await RenderSectionAsync(GlobalSections.Footer)
5424
</body>
5525
</html>

src/Elastic.Documentation.Site/_ViewModels.cs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,41 @@
44

55
using Elastic.Documentation.Configuration.Assembler;
66
using Elastic.Documentation.Configuration.Builder;
7-
using Elastic.Documentation.Legacy;
87
using Elastic.Documentation.Site.FileProviders;
98
using Elastic.Documentation.Site.Navigation;
109

1110
namespace Elastic.Documentation.Site;
1211

12+
public static class GlobalSections
13+
{
14+
public const string Head = "head";
15+
public const string Footer = "footer";
16+
}
17+
1318
public class GlobalLayoutViewModel
1419
{
1520
public required string DocSetName { get; init; }
1621
public string Title { get; set; } = "Elastic Documentation";
1722
public required string Description { get; init; }
18-
public required LayoutName? Layout { get; init; }
1923

20-
public required IReadOnlyCollection<PageTocItem> PageTocItems { get; init; }
21-
public required INavigationItem? CurrentNavigationItem { get; init; }
24+
public required INavigationItem CurrentNavigationItem { get; init; }
2225
public required INavigationItem? Previous { get; init; }
2326
public required INavigationItem? Next { get; init; }
27+
2428
public required string NavigationHtml { get; init; }
25-
public required LegacyPageMapping? LegacyPage { get; init; }
2629
public required string? UrlPathPrefix { get; init; }
27-
public required string? GithubEditUrl { get; init; }
28-
public required string? ReportIssueUrl { get; init; }
29-
public required bool AllowIndexing { get; init; }
3030
public required Uri? CanonicalBaseUrl { get; init; }
31-
public required GoogleTagManagerConfiguration GoogleTagManager { get; init; }
3231
public string? CanonicalUrl => CanonicalBaseUrl is not null ?
3332
new Uri(CanonicalBaseUrl, CurrentNavigationItem?.Url).ToString().TrimEnd('/') : null;
33+
3434
public required FeatureFlags Features { get; init; }
3535

36-
public required INavigationItem[] Parents { get; init; }
36+
// TODO move to @inject
37+
public required GoogleTagManagerConfiguration GoogleTagManager { get; init; }
38+
public required bool AllowIndexing { get; init; }
39+
public required StaticFileContentHashProvider StaticFileContentHashProvider { get; init; }
3740

38-
public required string? Products { get; init; }
41+
public bool RenderHamburgerIcon { get; init; } = true;
3942

4043
public string Static(string path)
4144
{
@@ -46,19 +49,10 @@ public string Static(string path)
4649
: $"{UrlPathPrefix}/{staticPath}?v={contentHash}";
4750
}
4851

49-
// TODO move to @inject
50-
public required StaticFileContentHashProvider StaticFileContentHashProvider { get; init; }
51-
5252
public string Link(string path)
5353
{
5454
path = path.AsSpan().TrimStart('/').ToString();
5555
return $"{UrlPathPrefix}/{path}";
5656
}
5757
}
5858

59-
public record PageTocItem
60-
{
61-
public required string Heading { get; init; }
62-
public required string Slug { get; init; }
63-
public required int Level { get; init; }
64-
}

src/Elastic.Markdown/IO/DocumentationFile.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Elastic.Documentation.Site;
66
using Elastic.Markdown.Myst;
77
using Elastic.Markdown.Myst.FrontMatter;
8+
using Elastic.Markdown.Slices;
89

910
namespace Elastic.Markdown.IO;
1011

0 commit comments

Comments
 (0)