Skip to content

Commit 513f300

Browse files
authored
Add support for extensionless URLs (pretty URLs) (#274)
* Add support for extensionless URLs * format * Refactor * Remove commented line * Fix tests * Also strip index * Update src/Elastic.Markdown/Myst/InlineParsers/DiagnosticLinkInlineParser.cs * Fix test
1 parent cc07233 commit 513f300

File tree

8 files changed

+52
-18
lines changed

8 files changed

+52
-18
lines changed

src/Elastic.Markdown/IO/MarkdownFile.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ public string? NavigationTitle
7070

7171
public string FilePath { get; }
7272
public string FileName { get; }
73-
public string Url => $"{UrlPathPrefix}/{RelativePath.Replace(".md", ".html")}";
73+
public string Url => Path.GetFileName(RelativePath) == "index.md"
74+
? $"{UrlPathPrefix}/{RelativePath.Remove(RelativePath.LastIndexOf("index.md", StringComparison.Ordinal), "index.md".Length)}"
75+
: $"{UrlPathPrefix}/{RelativePath.Remove(RelativePath.LastIndexOf(".md", StringComparison.Ordinal), 3)}";
7476

7577
public int NavigationIndex { get; internal set; } = -1;
7678

src/Elastic.Markdown/Myst/InlineParsers/DiagnosticLinkInlineParser.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,11 @@ private static void UpdateLinkUrl(LinkInline link, string url, ParserContext con
243243
url = GetRootRelativePath(context, file);
244244

245245
if (url.EndsWith(".md"))
246-
url = Path.ChangeExtension(url, ".html");
246+
{
247+
url = url.EndsWith("/index.md")
248+
? url.Remove(url.LastIndexOf("index.md", StringComparison.Ordinal), "index.md".Length)
249+
: url.Remove(url.LastIndexOf(".md", StringComparison.Ordinal), ".md".Length);
250+
}
247251

248252
if (!string.IsNullOrWhiteSpace(url) && !string.IsNullOrWhiteSpace(urlPathPrefix))
249253
url = $"{urlPathPrefix.TrimEnd('/')}{url}";

src/Elastic.Markdown/Slices/HtmlWriter.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,25 @@ public async Task WriteAsync(IFileInfo outputFile, MarkdownFile markdown, Cancel
8181
outputFile.Directory.Create();
8282

8383
var rendered = await RenderLayout(markdown, ctx);
84-
var path = Path.ChangeExtension(outputFile.FullName, ".html");
84+
string path;
85+
if (outputFile.Name == "index.md")
86+
{
87+
path = Path.ChangeExtension(outputFile.FullName, ".html");
88+
}
89+
else
90+
{
91+
var dir = outputFile.Directory is null
92+
? null
93+
: Path.Combine(outputFile.Directory.FullName, Path.GetFileNameWithoutExtension(outputFile.Name));
94+
95+
if (dir is not null && !_writeFileSystem.Directory.Exists(dir))
96+
_writeFileSystem.Directory.CreateDirectory(dir);
97+
98+
path = dir is null
99+
? Path.GetFileNameWithoutExtension(outputFile.Name) + ".html"
100+
: Path.Combine(dir, "index.html");
101+
}
102+
85103
await _writeFileSystem.File.WriteAllTextAsync(path, rendered, ctx);
86104
}
87105

src/docs-builder/Http/DocumentationWebHost.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,18 @@ private void SetUpRoutes()
9999
private static async Task<IResult> ServeDocumentationFile(ReloadableGeneratorState holder, string slug, Cancel ctx)
100100
{
101101
var generator = holder.Generator;
102-
slug = slug.Replace(".html", ".md");
103-
if (!generator.DocumentationSet.FlatMappedFiles.TryGetValue(slug, out var documentationFile))
104-
return Results.NotFound();
102+
103+
// For now, the logic is backwards compatible.
104+
// Hence, both http://localhost:5000/migration/versioning.html and http://localhost:5000/migration/versioning works,
105+
// so it's easier to copy links from issues created during the bug bounty.
106+
// However, we can remove this logic in the future and only support links without the .html extension.
107+
var s = Path.GetExtension(slug) == string.Empty ? Path.Combine(slug, "index.md") : slug.Replace(".html", ".md");
108+
if (!generator.DocumentationSet.FlatMappedFiles.TryGetValue(s, out var documentationFile))
109+
{
110+
s = Path.GetExtension(slug) == string.Empty ? slug + ".md" : s.Replace("/index.md", ".md");
111+
if (!generator.DocumentationSet.FlatMappedFiles.TryGetValue(s, out documentationFile))
112+
return Results.NotFound();
113+
}
105114

106115
switch (documentationFile)
107116
{

tests/Elastic.Markdown.Tests/Inline/AnchorLinkTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ [Sub Requirements](testing/req.md#sub-requirements)
7575
public void GeneratesHtml() =>
7676
// language=html
7777
Html.Should().Contain(
78-
"""<p><a href="/docs/testing/req.html#sub-requirements">Sub Requirements</a></p>"""
78+
"""<p><a href="/docs/testing/req#sub-requirements">Sub Requirements</a></p>"""
7979
);
8080

8181
[Fact]
@@ -93,7 +93,7 @@ [Sub Requirements](testing/req.md#new-reqs)
9393
public void GeneratesHtml() =>
9494
// language=html
9595
Html.Should().Contain(
96-
"""<p><a href="/docs/testing/req.html#new-reqs">Sub Requirements</a></p>"""
96+
"""<p><a href="/docs/testing/req#new-reqs">Sub Requirements</a></p>"""
9797
);
9898

9999
[Fact]
@@ -110,7 +110,7 @@ public class ExternalPageAnchorAutoTitleTests(ITestOutputHelper output) : Anchor
110110
public void GeneratesHtml() =>
111111
// language=html
112112
Html.Should().Contain(
113-
"""<p><a href="/docs/testing/req.html#sub-requirements">Special Requirements &gt; Sub Requirements</a></p>"""
113+
"""<p><a href="/docs/testing/req#sub-requirements">Special Requirements &gt; Sub Requirements</a></p>"""
114114
);
115115

116116
[Fact]
@@ -146,7 +146,7 @@ [Sub Requirements](testing/req.md#sub-requirements2)
146146
public void GeneratesHtml() =>
147147
// language=html
148148
Html.Should().Contain(
149-
"""<p><a href="/docs/testing/req.html#sub-requirements2">Sub Requirements</a></p>"""
149+
"""<p><a href="/docs/testing/req#sub-requirements2">Sub Requirements</a></p>"""
150150
);
151151

152152
[Fact]
@@ -165,7 +165,7 @@ [Heading inside dropdown](testing/req.md#heading-inside-dropdown)
165165
public void GeneratesHtml() =>
166166
// language=html
167167
Html.Should().Contain(
168-
"""<a href="/docs/testing/req.html#heading-inside-dropdown">Heading inside dropdown</a>"""
168+
"""<a href="/docs/testing/req#heading-inside-dropdown">Heading inside dropdown</a>"""
169169
);
170170
[Fact]
171171
public void HasError() => Collector.Diagnostics.Should().HaveCount(0);

tests/Elastic.Markdown.Tests/Inline/DirectiveBlockLinkTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ [Sub Requirements](testing/req.md#hint_ref)
6666
public void GeneratesHtml() =>
6767
// language=html
6868
Html.Should().Contain(
69-
"""<p><a href="/docs/testing/req.html#hint_ref">Sub Requirements</a></p>"""
69+
"""<p><a href="/docs/testing/req#hint_ref">Sub Requirements</a></p>"""
7070
);
7171

7272
[Fact]

tests/Elastic.Markdown.Tests/Inline/InlineAnchorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ [Sub Requirements](testing/req.md#custom-anchor)
202202
public void GeneratesHtml() =>
203203
// language=html
204204
Html.Should().Contain(
205-
"""<p><a href="/docs/testing/req.html#custom-anchor">Sub Requirements</a></p>"""
205+
"""<p><a href="/docs/testing/req#custom-anchor">Sub Requirements</a></p>"""
206206
);
207207

208208
[Fact]

tests/Elastic.Markdown.Tests/Inline/InlineLinkTests.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public class LinkToPageTests(ITestOutputHelper output) : LinkTestBase(output,
5757
public void GeneratesHtml() =>
5858
// language=html
5959
Html.Should().Contain(
60-
"""<p><a href="/docs/testing/req.html">Requirements</a></p>"""
60+
"""<p><a href="/docs/testing/req">Requirements</a></p>"""
6161
);
6262

6363
[Fact]
@@ -80,7 +80,7 @@ public class InsertPageTitleTests(ITestOutputHelper output) : LinkTestBase(outpu
8080
public void GeneratesHtml() =>
8181
// language=html
8282
Html.Should().Contain(
83-
"""<p><a href="/docs/testing/req.html">Special Requirements</a></p>"""
83+
"""<p><a href="/docs/testing/req">Special Requirements</a></p>"""
8484
);
8585

8686
[Fact]
@@ -105,7 +105,7 @@ public class LinkReferenceTest(ITestOutputHelper output) : LinkTestBase(output,
105105
public void GeneratesHtml() =>
106106
// language=html
107107
Html.Should().Contain(
108-
"""<p><a href="/docs/testing/req.html">test</a></p>"""
108+
"""<p><a href="/docs/testing/req">test</a></p>"""
109109
);
110110

111111
[Fact]
@@ -131,6 +131,7 @@ public void GeneratesHtml() =>
131131
// language=html
132132
Html.Should().Contain(
133133
// TODO: The link is not rendered correctly yet, will be fixed in a follow-up
134+
134135
"""<p><a href="kibana://index.md">test</a></p>"""
135136
);
136137

@@ -224,10 +225,10 @@ public void GeneratesHtml() =>
224225
Html.TrimEnd().Should().Be("""
225226
<p>Links:</p>
226227
<ul>
227-
<li><a href="/docs/testing/req.html">Special Requirements</a></li>
228+
<li><a href="/docs/testing/req">Special Requirements</a></li>
228229
</ul>
229230
<ul>
230-
<li><a href="/docs/testing/req.html">Special Requirements</a></li>
231+
<li><a href="/docs/testing/req">Special Requirements</a></li>
231232
</ul>
232233
""");
233234

0 commit comments

Comments
 (0)