Skip to content

Commit 988039f

Browse files
committed
first stab at html for applies to yaml frontmatter
1 parent c1d3bc3 commit 988039f

File tree

6 files changed

+185
-1
lines changed

6 files changed

+185
-1
lines changed

docs/source/markup/applies.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
title: Product Availability
3+
applies:
4+
stack: ga 8.1
5+
serverless: tech-preview
6+
hosted: beta 8.1.1
7+
eck: beta 3.0.2
8+
ece: unavailable
9+
---
10+
11+
12+
Using yaml frontmatter pages can explicitly indicate to each deployment targets availability and lifecycle status
13+
14+
15+
```yaml
16+
applies:
17+
stack: ga 8.1
18+
serverless: tech-preview
19+
hosted: beta 8.1.1
20+
eck: beta 3.0.2
21+
ece: unavailable
22+
```
23+
24+
Its syntax is
25+
26+
```
27+
<product>: <lifecycle> [version]
28+
```
29+
30+
Where version is optional.
31+
32+
`all` and empty string mean generally available for all active versions
33+
34+
```yaml
35+
applies:
36+
stack:
37+
serverless: all
38+
```
39+
40+
`all` and empty string can also be specified at a version level
41+
42+
```yaml
43+
applies:
44+
stack: beta all
45+
serverless: beta
46+
```
47+
48+
Are equivalent, note `all` just means we won't be rendering the version portion in the html.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
@using Elastic.Markdown.Myst.FrontMatter
2+
@inherits RazorSlice<Elastic.Markdown.Myst.FrontMatter.Deployment>
3+
<p class="product-availability">
4+
<span class="applies-to-label sd-badge sd-outline-transparent sd-text-black">
5+
Applies To:
6+
</span>
7+
@if (Model.SelfManaged is not null)
8+
{
9+
if (Model.SelfManaged.Stack is not null)
10+
{
11+
@RenderProduct("Elastic Stack", Model.SelfManaged.Stack)
12+
}
13+
if (Model.SelfManaged.Ece is not null)
14+
{
15+
@RenderProduct("Elastic Cloud Enterprise", Model.SelfManaged.Ece)
16+
}
17+
if (Model.SelfManaged.Eck is not null)
18+
{
19+
@RenderProduct("Elastic Cloud Kubernetes", Model.SelfManaged.Eck)
20+
}
21+
}
22+
@if (Model.Cloud is not null)
23+
{
24+
if (Model.Cloud.Hosted is not null)
25+
{
26+
@RenderProduct("Elastic Cloud Hosted", Model.Cloud.Hosted)
27+
}
28+
if (Model.Cloud.Serverless is not null)
29+
{
30+
@RenderProduct("Serverless", Model.Cloud.Serverless)
31+
}
32+
}
33+
</p>
34+
35+
@functions {
36+
37+
private string GetLifeCycleClass(ProductLifecycle cycle)
38+
{
39+
switch (cycle)
40+
{
41+
case ProductLifecycle.Deprecated:
42+
case ProductLifecycle.Coming:
43+
case ProductLifecycle.Discontinued:
44+
case ProductLifecycle.Unavailable:
45+
return "muted";
46+
case ProductLifecycle.GenerallyAvailable:
47+
case ProductLifecycle.TechnicalPreview:
48+
case ProductLifecycle.Beta:
49+
case ProductLifecycle.Development:
50+
return "primary";
51+
default:
52+
throw new ArgumentOutOfRangeException(nameof(cycle), cycle, null);
53+
}
54+
}
55+
private string GetLifeCycleName(ProductLifecycle cycle)
56+
{
57+
switch (cycle)
58+
{
59+
case ProductLifecycle.TechnicalPreview:
60+
return "Technical Preview";
61+
case ProductLifecycle.Beta:
62+
return "Beta";
63+
case ProductLifecycle.Development:
64+
return "Development";
65+
case ProductLifecycle.Deprecated:
66+
return "Deprecated";
67+
case ProductLifecycle.Coming:
68+
return "Coming";
69+
case ProductLifecycle.Discontinued:
70+
return "Discontinued";
71+
case ProductLifecycle.Unavailable:
72+
return "Unavailable";
73+
case ProductLifecycle.GenerallyAvailable:
74+
return "GA";
75+
default:
76+
throw new ArgumentOutOfRangeException(nameof(cycle), cycle, null);
77+
}
78+
}
79+
80+
private IHtmlContent RenderProduct(string name, ProductAvailability product)
81+
{
82+
var c = GetLifeCycleClass(product.Lifecycle);
83+
<span class="sd-badge sd-outline-@c sd-text-@c applies-badge">
84+
@name
85+
@if (product.Lifecycle != ProductLifecycle.GenerallyAvailable)
86+
{
87+
<span class="sd-text-secondary">@GetLifeCycleName(product.Lifecycle)</span>
88+
}
89+
@if (product.Version is not null and not AllVersions)
90+
{
91+
<span class="sd-text-success">(@product.Version)</span>
92+
}
93+
</span>
94+
return HtmlString.Empty;
95+
}
96+
}

src/Elastic.Markdown/Slices/HtmlWriter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ public async Task<string> RenderLayout(MarkdownFile markdown, Cancel ctx = defau
5252
Tree = DocumentationSet.Tree,
5353
CurrentDocument = markdown,
5454
NavigationHtml = navigationHtml,
55-
UrlPathPrefix = markdown.UrlPathPrefix
55+
UrlPathPrefix = markdown.UrlPathPrefix,
56+
Applies = markdown.YamlFrontMatter?.AppliesTo
5657
});
5758
return await slice.RenderAsync(cancellationToken: ctx);
5859
}

src/Elastic.Markdown/Slices/Index.cshtml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,9 @@
1313
}
1414
<section id="elastic-docs-v3">
1515
<h1>@(Model.Title)</h1>
16+
@if (Model.Applies is not null)
17+
{
18+
await RenderPartialAsync(Applies.Create(Model.Applies));
19+
}
1620
@(new HtmlString(Model.MarkdownHtml))
1721
</section>

src/Elastic.Markdown/Slices/_ViewModels.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information
44
using Elastic.Markdown.IO;
5+
using Elastic.Markdown.Myst.FrontMatter;
56

67
namespace Elastic.Markdown.Slices;
78

@@ -14,6 +15,7 @@ public class IndexViewModel
1415
public required MarkdownFile CurrentDocument { get; init; }
1516
public required string NavigationHtml { get; init; }
1617
public required string? UrlPathPrefix { get; init; }
18+
public required Deployment? Applies { get; init; }
1719
}
1820

1921
public class LayoutViewModel

src/Elastic.Markdown/_static/custom.css

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,37 @@ body > footer > div > div > div.sy-foot-copyright > p:nth-child(2){
3030
.yue img {
3131
margin-top: 0;
3232
margin-bottom: 0;
33+
}
34+
35+
.applies-badge {
36+
font-size: 1em;
37+
margin-top: 0.4em;
38+
}
39+
40+
h1 {
41+
padding-bottom: 0.4em;
42+
border-bottom: 1px solid #dfdfdf;
43+
}
44+
.sd-outline-muted
45+
{
46+
border: 1px solid #dfdfdf;
47+
}
48+
.product-availability {
49+
padding-bottom: 0.8em;
50+
border-bottom: 1px solid #dfdfdf;
51+
}
52+
53+
h1:has(+ .product-availability) {
54+
margin-bottom: 0.4em;
55+
padding-bottom: 0;
56+
border-bottom: none;
57+
}
58+
59+
.applies-to-label {
60+
font-size: 1em;
61+
margin-top: 0.4em;
62+
margin-left: 0;
63+
font-weight: bold;
64+
text-align: left;
65+
padding-left: 0;
3366
}

0 commit comments

Comments
 (0)