diff --git a/docs/en/Getting-Started-Create-Solution-Single-Layer.md b/docs/en/Getting-Started-Create-Solution-Single-Layer.md index 8c4a6d0d88..d2fbadd1b5 100644 --- a/docs/en/Getting-Started-Create-Solution-Single-Layer.md +++ b/docs/en/Getting-Started-Create-Solution-Single-Layer.md @@ -8,6 +8,20 @@ } ```` +````json +//[doc-nav] +{ + "Next": { + "Name": "Running the solution", + "Path": "Getting-Started-Running-Solution-Single-Layer" + }, + "Previous": { + "Name": "Setup Your Development Environment", + "Path": "Getting-Started-Setup-Environment-Single-Layer" + } +} +```` + > This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. ## Create a New Project @@ -45,8 +59,4 @@ Configure(options => > Or you can delete that code since `Auto` is already the default behavior. -{{ end }} - -## Next Step - -* [Running the solution](Getting-Started-Running-Solution-Single-Layer.md) \ No newline at end of file +{{ end }} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json index 26bc77e6d1..2d26d12c60 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json @@ -37,6 +37,8 @@ "Preview": "preview", "Search": "Search", "SearchResults": "Search Results", - "SearchInTheAllDocuments": "Search in the all documents" + "SearchInTheAllDocuments": "Search in the all documents", + "Next": "Next", + "Previous": "Previous" } } diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationDto.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationDto.cs new file mode 100644 index 0000000000..bcfbdb5a25 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationDto.cs @@ -0,0 +1,7 @@ +namespace Volo.Docs.HtmlConverting; + +public class DocumentNavigationDto +{ + public string Name { get; set; } + public string Path { get; set; } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationsDto.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationsDto.cs new file mode 100644 index 0000000000..d1f6335466 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationsDto.cs @@ -0,0 +1,13 @@ +using System; + +namespace Volo.Docs.HtmlConverting; + +public class DocumentNavigationsDto +{ + public DocumentNavigationDto Previous { get; set; } + public DocumentNavigationDto Next { get; set; } + + public bool HasPrevious => Previous?.Path.IsNullOrEmpty() == false; + public bool HasNext => Next?.Path.IsNullOrEmpty() == false; + public bool HasValues => HasPrevious || HasNext; +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs index 0738b4fd5c..73560a7273 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs @@ -11,5 +11,7 @@ namespace Volo.Docs.HtmlConverting Task>> GetAvailableParametersAsync(string document); Task> GetPartialTemplatesInDocumentAsync(string documentContent); + + Task GetDocumentNavigationsAsync(string documentContent); } } diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs index 1ade06aa26..b95966ea28 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs @@ -17,6 +17,7 @@ namespace Volo.Docs.HtmlConverting private const string JsonCloser = "````"; private const string DocsParam = "//[doc-params]"; private const string DocsTemplates = "//[doc-template]"; + private const string DocsNav = "//[doc-nav]"; public ILogger Logger { get; set; } @@ -41,71 +42,87 @@ namespace Volo.Docs.HtmlConverting var result = await scribanTemplate.RenderAsync(parameters); - return RemoveOptionsJson(result); + return RemoveOptionsJson(result, DocsParam, DocsNav); } - public async Task>> GetAvailableParametersAsync(string document) + public Task>> GetAvailableParametersAsync(string document) + { + return GetSectionAsync>>(document, DocsParam); + } + + public Task GetDocumentNavigationsAsync(string documentContent) + { + return GetSectionAsync(documentContent, DocsNav); + } + + protected virtual async Task GetSectionAsync(string document, string sectionName) where T : new() { try { - if (!document.Contains(JsonOpener) || !document.Contains(DocsParam)) + if (!document.Contains(JsonOpener) || !document.Contains(sectionName)) { - return new Dictionary>(); + return new T(); } - var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document); + var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document, sectionName); if (jsonBeginningIndex < 0 || jsonEndingIndex <= 0 || string.IsNullOrWhiteSpace(insideJsonSection)) { - return new Dictionary>(); + return new T(); } - var pureJson = insideJsonSection.Replace(DocsParam, "").Trim(); + var pureJson = insideJsonSection.Replace(sectionName, "").Trim(); - if (!DocsJsonSerializerHelper.TryDeserialize>>(pureJson, out var availableParameters)) + if (!DocsJsonSerializerHelper.TryDeserialize(pureJson, out var section)) { - throw new UserFriendlyException("ERROR-20200327: Cannot validate JSON content for `AvailableParameters`!"); + throw new UserFriendlyException($"ERROR-20200327: Cannot validate JSON content for `{sectionName}`!"); } - return await Task.FromResult(availableParameters); + return await Task.FromResult(section); } catch (Exception) { Logger.LogWarning("Unable to parse parameters of document."); - return new Dictionary>(); + return new T(); } } - private static string RemoveOptionsJson(string document) + private static string RemoveOptionsJson(string document, params string[] sectionNames) { - var orgDocument = document; - try + foreach (var sectionName in sectionNames) { - if (!document.Contains(JsonOpener) || !document.Contains(DocsParam)) + var orgDocument = document; + + try { - return orgDocument; - } + if (!document.Contains(JsonOpener) || !document.Contains(sectionName)) + { + continue; + } - var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document); + var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document, sectionName); - if (jsonBeginningIndex < 0 || jsonEndingIndex <= 0 || string.IsNullOrWhiteSpace(insideJsonSection)) + if (jsonBeginningIndex < 0 || jsonEndingIndex <= 0 || string.IsNullOrWhiteSpace(insideJsonSection)) + { + continue; + } + + document = document.Remove( + jsonBeginningIndex - JsonOpener.Length, + (jsonEndingIndex + JsonCloser.Length) - (jsonBeginningIndex - JsonOpener.Length) + ); + } + catch (Exception) { - return orgDocument; + document = orgDocument; } - - return document.Remove( - jsonBeginningIndex - JsonOpener.Length, - (jsonEndingIndex + JsonCloser.Length) - (jsonBeginningIndex - JsonOpener.Length) - ); - } - catch (Exception) - { - return orgDocument; } + + return document; } - private static (int, int, string) GetJsonBeginEndIndexesAndPureJson(string document) + private static (int, int, string) GetJsonBeginEndIndexesAndPureJson(string document, string sectionName) { var searchedIndex = 0; @@ -121,7 +138,7 @@ namespace Volo.Docs.HtmlConverting var jsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(JsonCloser, StringComparison.Ordinal) + jsonBeginningIndex; var insideJsonSection = document[jsonBeginningIndex..jsonEndingIndex]; - if (insideJsonSection.IndexOf(DocsParam, StringComparison.Ordinal) < 0) + if (insideJsonSection.IndexOf(sectionName, StringComparison.Ordinal) < 0) { searchedIndex = jsonEndingIndex + JsonCloser.Length; continue; diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index 83f4c7a775..b2a5b2d1dd 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -388,6 +388,38 @@ } @Html.Raw(Model.Document.Content) + + @if (Model.DocumentNavigationsDto.HasValues) + { +
+ + + }