Browse Source

Merge pull request #18990 from abpframework/issue-17775

Better navigation to "Next Step" in the documentation
pull/19027/head
Gizem Mutu Kurt 3 years ago
committed by GitHub
parent
commit
4bc79fa930
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 20
      docs/en/Getting-Started-Create-Solution-Single-Layer.md
  2. 4
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json
  3. 7
      modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationDto.cs
  4. 13
      modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentNavigationsDto.cs
  5. 2
      modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs
  6. 79
      modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs
  7. 32
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  8. 18
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs
  9. 1
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.css.map
  10. 1
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.min.css.map
  11. 23
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.css
  12. 2
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.min.css
  13. 18
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.scss

20
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<AbpUnitOfWorkDefaultOptions>(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)
{{ end }}

4
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"
}
}

7
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; }
}

13
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;
}

2
modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs

@ -11,5 +11,7 @@ namespace Volo.Docs.HtmlConverting
Task<Dictionary<string, List<string>>> GetAvailableParametersAsync(string document);
Task<List<DocumentPartialTemplateWithValuesDto>> GetPartialTemplatesInDocumentAsync(string documentContent);
Task<DocumentNavigationsDto> GetDocumentNavigationsAsync(string documentContent);
}
}

79
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<ScribanDocumentSectionRenderer> 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<Dictionary<string, List<string>>> GetAvailableParametersAsync(string document)
public Task<Dictionary<string, List<string>>> GetAvailableParametersAsync(string document)
{
return GetSectionAsync<Dictionary<string, List<string>>>(document, DocsParam);
}
public Task<DocumentNavigationsDto> GetDocumentNavigationsAsync(string documentContent)
{
return GetSectionAsync<DocumentNavigationsDto>(documentContent, DocsNav);
}
protected virtual async Task<T> GetSectionAsync<T>(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<string, List<string>>();
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<string, List<string>>();
return new T();
}
var pureJson = insideJsonSection.Replace(DocsParam, "").Trim();
var pureJson = insideJsonSection.Replace(sectionName, "").Trim();
if (!DocsJsonSerializerHelper.TryDeserialize<Dictionary<string, List<string>>>(pureJson, out var availableParameters))
if (!DocsJsonSerializerHelper.TryDeserialize<T>(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<string, List<string>>();
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;

32
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml

@ -388,6 +388,38 @@
</abp-alert>
}
@Html.Raw(Model.Document.Content)
@if (Model.DocumentNavigationsDto.HasValues)
{
<hr class="my-4"/>
<div class="row navigation">
<div class="col-6">
@if (Model.DocumentNavigationsDto.HasPrevious)
{
<a class="prev-link" href="@Model.CreateDocumentLink(Model.DocumentNavigationsDto.Previous.Path)">
<span class="desc d-block">
<i class="fa fa-chevron-left me-1"></i>
@L["Previous"]
</span>
<span class="title d-block">@Model.DocumentNavigationsDto.Previous.Name</span>
</a>
}
</div>
<div class="col-6">
@if (Model.DocumentNavigationsDto.HasNext)
{
<a class="next-link text-end" href="@Model.CreateDocumentLink(Model.DocumentNavigationsDto.Next.Path)">
<span class="desc d-block">
@L["Next"]
<i class="fa fa-chevron-right ms-1"></i>
</span>
<span class="title d-block">@Model.DocumentNavigationsDto.Next.Name</span>
</a>
}
</div>
</div>
}
</article>
<div id="crawler_link" style="display:none;">

18
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs

@ -82,6 +82,8 @@ namespace Volo.Docs.Pages.Documents.Project
public bool FullSearchEnabled { get; set; }
public bool IsLatestVersion { get; private set; }
public DocumentNavigationsDto DocumentNavigationsDto { get; private set; }
private const int MaxDescriptionMetaTagLength = 200;
private readonly IDocumentAppService _documentAppService;
@ -253,6 +255,20 @@ namespace Volo.Docs.Pages.Documents.Project
DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/" +
DocsAppConsts.Latest + "/" + DocumentName;
}
public string CreateDocumentLink(string documentName)
{
return new StringBuilder()
.Append(DocumentsUrlPrefix)
.Append(LanguageCode)
.Append('/')
.Append(ProjectName)
.Append('/')
.Append(LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version)
.Append('/')
.Append(documentName)
.ToString();
}
private IActionResult RedirectToDefaultLanguage()
{
@ -522,6 +538,8 @@ namespace Volo.Docs.Pages.Documents.Project
SetUserPreferences();
var partialTemplates = await GetDocumentPartialTemplatesAsync();
DocumentNavigationsDto = await _documentSectionRenderer.GetDocumentNavigationsAsync(Document.Content);
Document.Content = await _documentSectionRenderer.RenderAsync(Document.Content, UserPreferences, partialTemplates);
}

1
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.css.map

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["index.scss"],"names":[],"mappings":"AACI;EACI;EACA;EACA;;;AAKJ;EACI;;;AAMA;EACI;;AACA;EACI;;AAGR;EACI;EACA;EACA","file":"Index.css"}

1
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.min.css.map

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["index.scss"],"names":[],"mappings":"AACI,8BACI,4BACA,4CACA,uBAKJ,+BACI,0CAMA,0DACI,cACA,kEACI,eAGR,4DACI,gBACA,eACA","file":"Index.min.css"}

23
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.css

@ -1,8 +1,23 @@
.code-toolbar .line-highlight {
margin-top: 1.5em !important;
background: rgba(233, 237, 241, 0.34) !important;
padding: 1px !important; }
padding: 1px !important;
}
.input-group .input-group-text{
background-color: transparent!important;
}
.input-group .input-group-text {
background-color: transparent !important;
}
.navigation .next-link .desc, .navigation .prev-link .desc {
color: #0D6EFD;
}
.navigation .next-link .desc .fa, .navigation .prev-link .desc .fa {
font-size: 12px;
}
.navigation .next-link .title, .navigation .prev-link .title {
font-weight: 600;
font-size: 18px;
color: #0B1621;
}
/*# sourceMappingURL=Index.css.map */

2
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.min.css

@ -1 +1 @@
.code-toolbar .line-highlight{margin-top:1.5em !important;background:rgba(233,237,241,.34) !important;padding:1px !important;} .input-group .input-group-text{background-color: transparent!important;}
.code-toolbar .line-highlight{margin-top:1.5em !important;background:rgba(233,237,241,.34) !important;padding:1px !important}.input-group .input-group-text{background-color:rgba(0,0,0,0) !important}.navigation .next-link .desc,.navigation .prev-link .desc{color:#0d6efd}.navigation .next-link .desc .fa,.navigation .prev-link .desc .fa{font-size:12px}.navigation .next-link .title,.navigation .prev-link .title{font-weight:600;font-size:18px;color:#0b1621}/*# sourceMappingURL=Index.min.css.map */

18
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.scss

@ -10,4 +10,20 @@
.input-group-text{
background-color: transparent!important;
}
}
}
.navigation {
.next-link, .prev-link {
.desc {
color: #0D6EFD;
.fa{
font-size: 12px;
}
}
.title {
font-weight: 600;
font-size: 18px;
color: #0B1621;
}
}
}

Loading…
Cancel
Save