Browse Source

doc sections Scriban

pull/2297/head
Yunus Emre Kalkan 7 years ago
parent
commit
8648c0b9e2
  1. 2
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs
  2. 2
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs
  3. 3
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs
  4. 3
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs
  5. 3
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs
  6. 13
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParameterDto.cs
  7. 9
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParametersDto.cs
  8. 19
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs
  9. 2
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs
  10. 16
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
  11. 1
      modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs
  12. 3
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs
  13. 14
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs
  14. 1
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs
  15. 5
      modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs
  16. 4
      modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentParseParamaters.cs
  17. 97
      modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs
  18. 51
      modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs
  19. 9
      modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs
  20. 9
      modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs
  21. 15
      modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs
  22. 115
      modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs
  23. 19
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  24. 113
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs
  25. 244
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js
  26. 113
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js
  27. 1
      modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj
  28. 3
      modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocsTestDataBuilder.cs

2
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs

@ -14,6 +14,8 @@ namespace Volo.Docs.Admin.Projects
public string NavigationDocumentName { get; set; }
public string ParametersDocumentName { get; set; }
public string MinimumVersion { get; set; }
public string MainWebsiteUrl { get; set; }

2
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs

@ -12,6 +12,8 @@ namespace Volo.Docs.Admin.Projects
public string NavigationDocumentName { get; set; }
public string ParametersDocumentName { get; set; }
public string MinimumVersion { get; set; }
public string MainWebsiteUrl { get; set; }

3
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs

@ -53,7 +53,8 @@ namespace Volo.Docs.Admin.Projects
input.DocumentStoreType,
input.Format,
input.DefaultDocumentName,
input.NavigationDocumentName
input.NavigationDocumentName,
input.ParametersDocumentName
)
{
MinimumVersion = input.MinimumVersion,

3
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs

@ -88,6 +88,9 @@ namespace Volo.Docs.Admin.Pages.Docs.Admin.Projects
[StringLength(ProjectConsts.MaxNavigationDocumentNameLength)]
public string NavigationDocumentName { get; set; } = "docs-nav.json";
[StringLength(ProjectConsts.MaxParametersDocumentNameLength)]
public string ParametersDocumentName { get; set; } = "docs-params.json";
[StringLength(ProjectConsts.MaxVersionNameLength)]
public string MinimumVersion { get; set; }

3
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs

@ -96,6 +96,9 @@ namespace Volo.Docs.Admin.Pages.Docs.Admin.Projects
[StringLength(ProjectConsts.MaxNavigationDocumentNameLength)]
public string NavigationDocumentName { get; set; }
[StringLength(ProjectConsts.MaxParametersDocumentNameLength)]
public string ParametersDocumentName { get; set; }
[StringLength(ProjectConsts.MaxVersionNameLength)]
public string MinimumVersion { get; set; }

13
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParameterDto.cs

@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Volo.Docs.Documents
{
public class DocumentParameterDto
{
public string Name { get; set; }
public string DisplayName { get; set; }
public Dictionary<string, string> Values { get; set; }
}
}

9
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParametersDto.cs

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Volo.Docs.Documents
{
public class DocumentParametersDto
{
public List<DocumentParameterDto> Parameters {get;set;}
}
}

19
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs

@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Docs.Language;
using Volo.Docs.Projects;
namespace Volo.Docs.Documents
{
public class GetParametersDocumentInput
{
public Guid ProjectId { get; set; }
[StringLength(ProjectConsts.MaxVersionNameLength)]
public string Version { get; set; }
[Required]
[StringLength(LanguageConsts.MaxLanguageCodeLength)]
public string LanguageCode { get; set; }
}
}

2
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs

@ -11,6 +11,8 @@ namespace Volo.Docs.Documents
Task<DocumentWithDetailsDto> GetNavigationAsync(GetNavigationDocumentInput input);
Task<DocumentParametersDto> GetParametersAsync(GetParametersDocumentInput input);
Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input);
}
}

16
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Volo.Abp.Caching;
using Volo.Docs.Projects;
@ -100,6 +101,20 @@ namespace Volo.Docs.Documents
);
}
public async Task<DocumentParametersDto> GetParametersAsync(GetParametersDocumentInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId);
var document = await GetDocumentWithDetailsDtoAsync(
project,
project.ParametersDocumentName,
input.LanguageCode,
input.Version
);
return JsonConvert.DeserializeObject<DocumentParametersDto>(document.Content);
}
protected virtual async Task<DocumentWithDetailsDto> GetDocumentWithDetailsDtoAsync(
Project project,
string documentName,
@ -143,5 +158,6 @@ namespace Volo.Docs.Documents
documentDto.Contributors = ObjectMapper.Map<List<DocumentContributor>, List<DocumentContributorDto>>(document.Contributors);
return documentDto;
}
}
}

1
modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs

@ -6,6 +6,7 @@
public const int MaxShortNameLength = 32;
public const int MaxDefaultDocumentNameLength = 128;
public const int MaxNavigationDocumentNameLength = 128;
public const int MaxParametersDocumentNameLength = 128;
public const int MaxLatestVersionBranchNameLength = 128;
public const int MaxVersionNameLength = 128;
}

3
modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs

@ -36,6 +36,7 @@ namespace Volo.Docs.GitHub.Documents
var rawDocumentUrl = rawRootUrl + documentName;
var commitHistoryUrl = project.GetGitHubUrlForCommitHistory() + documentName;
var isNavigationDocument = documentName == project.NavigationDocumentName;
var isParameterDocument = documentName == project.ParametersDocumentName;
var editLink = rootUrl.ReplaceFirst("/tree/", "/blob/") + languageCode + "/" + documentName;
var localDirectory = "";
var fileName = documentName;
@ -56,7 +57,7 @@ namespace Volo.Docs.GitHub.Documents
LocalDirectory = localDirectory,
FileName = fileName,
Contributors = new List<DocumentContributor>(),
//Contributors = !isNavigationDocument ? await GetContributors(commitHistoryUrl, token, userAgent): new List<DocumentContributor>(),
//Contributors = !isNavigationDocument && !isParameterDocument ? await GetContributors(commitHistoryUrl, token, userAgent): new List<DocumentContributor>(),
Version = version,
Content = await DownloadWebContentAsStringAsync(rawDocumentUrl, token, userAgent)
};

14
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs

@ -34,6 +34,11 @@ namespace Volo.Docs.Projects
/// </summary>
public virtual string NavigationDocumentName { get; protected set; }
/// <summary>
/// The document to be used for the parameters file (index).
/// </summary>
public virtual string ParametersDocumentName { get; protected set; }
public virtual string MinimumVersion { get; set; }
/// <summary>
@ -57,7 +62,8 @@ namespace Volo.Docs.Projects
[NotNull] string documentStoreType,
[NotNull] string format,
[NotNull] string defaultDocumentName,
[NotNull] string navigationDocumentName)
[NotNull] string navigationDocumentName,
[NotNull] string parametersDocumentName)
{
Id = id;
@ -67,6 +73,7 @@ namespace Volo.Docs.Projects
Format = Check.NotNullOrWhiteSpace(format, nameof(format));
DefaultDocumentName = Check.NotNullOrWhiteSpace(defaultDocumentName, nameof(defaultDocumentName));
NavigationDocumentName = Check.NotNullOrWhiteSpace(navigationDocumentName, nameof(navigationDocumentName));
ParametersDocumentName = Check.NotNullOrWhiteSpace(parametersDocumentName, nameof(parametersDocumentName));
ExtraProperties = new Dictionary<string, object>();
}
@ -86,6 +93,11 @@ namespace Volo.Docs.Projects
NavigationDocumentName = Check.NotNullOrWhiteSpace(navigationDocumentName, nameof(navigationDocumentName));
}
public void SetParametersDocumentName(string parametersDocumentName)
{
ParametersDocumentName = Check.NotNullOrWhiteSpace(parametersDocumentName, nameof(parametersDocumentName));
}
public void SetDefaultDocumentName(string defaultDocumentName)
{
DefaultDocumentName = Check.NotNullOrWhiteSpace(defaultDocumentName, nameof(defaultDocumentName));

1
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs

@ -33,6 +33,7 @@ namespace Volo.Docs.EntityFrameworkCore
b.Property(x => x.ShortName).IsRequired().HasMaxLength(ProjectConsts.MaxShortNameLength);
b.Property(x => x.DefaultDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxDefaultDocumentNameLength);
b.Property(x => x.NavigationDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxNavigationDocumentNameLength);
b.Property(x => x.ParametersDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxParametersDocumentNameLength);
b.Property(x => x.LatestVersionBranchName).HasMaxLength(ProjectConsts.MaxLatestVersionBranchNameLength);
});
}

5
modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs

@ -45,5 +45,10 @@ namespace Volo.Docs.Documents
{
return DocumentAppService.GetResourceAsync(input);
}
public Task<DocumentParametersDto> GetParametersAsync(GetParametersDocumentInput input)
{
return DocumentAppService.GetParametersAsync(input);
}
}
}

4
modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs → modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentParseParamaters.cs

@ -2,7 +2,7 @@
namespace Volo.Docs.HtmlConverting
{
public class DocumentSectionDictionary : Dictionary<string,List<string>>
public class DocumentRenderParameters : Dictionary<string,string>
{
}
}
}

97
modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs

@ -1,97 +0,0 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
namespace Volo.Docs.HtmlConverting
{
public class DocumentSectionFinder : IDocumentSectionFinder
{
public ILogger<DocumentSectionFinder> Logger { get; set; }
public DocumentSectionFinder()
{
Logger = NullLogger<DocumentSectionFinder>.Instance;
}
public DocumentSectionDictionary Find(string document)
{
try
{
return FindNextSections(document, new DocumentSectionDictionary());
}
catch (Exception e)
{
Logger.LogWarning(
$"Incorrect usage of \"{DocumentSectionConsts.SectionOpenerPrefix}" +
$"KEY{DocumentSectionConsts.SectionOpenerKeyValueSeparator}" +
$"VALUE{DocumentSectionConsts.SectionOpenerPostfix}..{DocumentSectionConsts.SectionCloser}\" syntax.");
return new DocumentSectionDictionary();
}
}
private DocumentSectionDictionary FindNextSections(string targetPartOfDocument, DocumentSectionDictionary sections)
{
var startOfSection = targetPartOfDocument.IndexOf(DocumentSectionConsts.SectionOpenerPrefix, StringComparison.InvariantCulture);
if (startOfSection < 0)
{
return sections;
}
var endOfSectionOpener = targetPartOfDocument.Substring(startOfSection).IndexOf(DocumentSectionConsts.SectionOpenerPostfix, StringComparison.InvariantCulture);
var keysValues = targetPartOfDocument.Substring(startOfSection)
[DocumentSectionConsts.SectionOpenerPrefix.Length..endOfSectionOpener];
sections = ParseAndAddContidionToSections(keysValues, sections);
return FindNextSections(targetPartOfDocument.Substring(endOfSectionOpener), sections);
}
private DocumentSectionDictionary ParseAndAddContidionToSections(string keysValues, DocumentSectionDictionary sections)
{
if (keysValues.Contains(DocumentSectionConsts.SectionOpenerAndCondition, StringComparison.InvariantCulture))
{
var keysValuesSplitted = keysValues.Split(DocumentSectionConsts.SectionOpenerAndCondition);
foreach (var keyValue in keysValuesSplitted)
{
sections = AddContidionToSections(keyValue, sections);
}
}
else if (keysValues.Contains(DocumentSectionConsts.SectionOpenerOrCondition, StringComparison.InvariantCulture))
{
var keysValuesSplitted = keysValues.Split(DocumentSectionConsts.SectionOpenerOrCondition);
foreach (var keyValue in keysValuesSplitted)
{
sections = AddContidionToSections(keyValue, sections);
}
}
else
{
sections = AddContidionToSections(keysValues, sections);
}
return sections;
}
private DocumentSectionDictionary AddContidionToSections(string keyValueWithSeparator, DocumentSectionDictionary sections)
{
var keyValue = keyValueWithSeparator.Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator);
var key = keyValue[0];
var value = keyValue[1];
if (sections.ContainsKey(key))
{
sections[key].AddIfNotContains(value);
}
else
{
sections.Add(key, new List<string>() { value });
}
return sections;
}
}
}

51
modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs

@ -1,51 +0,0 @@
using System;
namespace Volo.Docs.HtmlConverting
{
public class DocumentSectionHtmlReplacer : IDocumentSectionHtmlReplacer
{
public string Replace(string document)
{
while (document.Contains(DocumentSectionConsts.SectionOpenerPrefix))
{
var sectionIndex = document.IndexOf(DocumentSectionConsts.SectionOpenerPrefix, StringComparison.InvariantCulture);
var sectionCloserIndex = document.Substring(sectionIndex + DocumentSectionConsts.SectionOpenerPrefix.Length)
.IndexOf(DocumentSectionConsts.SectionOpenerPostfix, StringComparison.InvariantCulture);
var keysValues = document.Substring(sectionIndex + DocumentSectionConsts.SectionOpenerPrefix.Length)
[0..sectionCloserIndex];
var andOperation = keysValues.Contains(DocumentSectionConsts.SectionOpenerAndCondition, StringComparison.InvariantCulture);
var orOperation = keysValues.Contains(DocumentSectionConsts.SectionOpenerOrCondition, StringComparison.InvariantCulture);
var splitterChar = andOperation ? DocumentSectionConsts.SectionOpenerAndCondition : DocumentSectionConsts.SectionOpenerOrCondition;
string[] keysValuesSplitted = keysValues.Split(splitterChar);
var keys = new string[keysValuesSplitted.Length];
var values = new string[keysValuesSplitted.Length];
for (int i = 0; i < keysValuesSplitted.Length; i++)
{
keys[i] = keysValuesSplitted[i].Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator)[0];
values[i] = keysValuesSplitted[i].Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator)[1];
}
var div = $"<span class=\"doc-section\" data-keys=\"" +
$"{string.Join(splitterChar, keys)}" +
$"\" data-values=\"" +
$"{string.Join(splitterChar, values)}" +
$"\">";
document = document.Remove(sectionIndex, sectionCloserIndex + DocumentSectionConsts.SectionOpenerPrefix.Length +1);
document = document.Insert(sectionIndex, div);
}
document = document.Replace(DocumentSectionConsts.SectionCloser, "</span>");
return document;
}
}
}

9
modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs

@ -1,9 +0,0 @@
using Volo.Abp.DependencyInjection;
namespace Volo.Docs.HtmlConverting
{
public interface IDocumentSectionFinder: ITransientDependency
{
public DocumentSectionDictionary Find(string document);
}
}

9
modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs

@ -1,9 +0,0 @@
using Volo.Abp.DependencyInjection;
namespace Volo.Docs.HtmlConverting
{
public interface IDocumentSectionHtmlReplacer : ITransientDependency
{
public string Replace(string document);
}
}

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

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Docs.HtmlConverting
{
public interface IDocumentSectionRenderer: ITransientDependency
{
Task<string> Render(string doucment, DocumentRenderParameters parameters);
Task<Dictionary<string, List<string>>> GetAvailableParametersAsync(string document);
}
}

115
modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs

@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Scriban;
namespace Volo.Docs.HtmlConverting
{
public class ScribanDocumentSectionRenderer : IDocumentSectionRenderer
{
public async Task<string> Render(string document, DocumentRenderParameters parameters = null)
{
Template scribanTemplate;
if (parameters == null)
{
scribanTemplate = Template.Parse(document);
return scribanTemplate.Render();
}
var p2 = new Dictionary<string, string>();
foreach (var item in parameters)
{
p2.Add(item.Key, item.Value);
}
scribanTemplate = Template.Parse(document);
var result = scribanTemplate.Render(p2);
try
{
return await RemoveOptionsJson(result);
}
catch (Exception)
{
return scribanTemplate.Render();
}
}
public async Task<Dictionary<string, List<string>>> GetAvailableParametersAsync(string document)
{
try
{
var jsonOpener = "````json";
var jsonCloser = "````";
var docs_param = "//[doc-params]";
if (!document.Contains(jsonOpener))
{
return new Dictionary<string, List<string>>();
}
var searchedIndex = 0;
while (searchedIndex < document.Length)
{
var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(jsonOpener) + jsonOpener.Length + searchedIndex;
var JsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(jsonCloser) + jsonBeginningIndex;
var insideJsonSection = document[jsonBeginningIndex..JsonEndingIndex];
if (insideJsonSection.IndexOf(docs_param) < 0)
{
searchedIndex = JsonEndingIndex + jsonCloser.Length;
continue;
}
var pureJson = insideJsonSection.Replace(docs_param, "").Trim();
return JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(pureJson);
}
return new Dictionary<string, List<string>>();
}
catch (Exception e)
{
//log
return new Dictionary<string, List<string>>();
}
}
private async Task<string> RemoveOptionsJson(string document)
{
var jsonOpener = "````json";
var jsonCloser = "````";
var docs_param = "//[doc-params]";
var searchedIndex = 0;
while (searchedIndex < document.Length)
{
var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(jsonOpener) + jsonOpener.Length + searchedIndex;
if (jsonBeginningIndex < 0)
{
return document;
}
var JsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(jsonCloser) + jsonBeginningIndex;
var insideJsonSection = document[jsonBeginningIndex..JsonEndingIndex];
if (insideJsonSection.IndexOf(docs_param) < 0)
{
searchedIndex = JsonEndingIndex + jsonCloser.Length;
continue;
}
return document.Remove(
jsonBeginningIndex - jsonOpener.Length, (JsonEndingIndex + jsonCloser.Length) - (jsonBeginningIndex - jsonOpener.Length)
);
}
return document;
}
}
}

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

@ -209,15 +209,22 @@
}
@if (Model.DocumentSections != null && Model.DocumentSections.Count > 0)
@if (Model.DocumentPreferences != null && Model.DocumentPreferences.Parameters != null && Model.DocumentPreferences.Parameters.Count > 0)
{
foreach (var key in Model.DocumentSections)
foreach (var parameter in Model.DocumentPreferences.Parameters)
{
@(key.Key + ":")
<select class="doc-section-combobox mr-4 mt-2" id="@("Section" + key.Key + "ComboboxId")" data-key="@key.Key">
@foreach (var value in key.Value)
@(parameter.DisplayName + ":")
<select class="doc-section-combobox mr-4 mt-2" id="@("Section" + parameter.Name + "ComboboxId")" data-key="@parameter.Name">
@foreach (var value in parameter.Values)
{
<option value="@value">@value</option>
@if (value.Key == (Model.UserPreferences.ContainsKey(parameter.Name) ? Model.UserPreferences[parameter.Name]:null))
{
<option value="@value.Key" selected="selected">@value.Value</option>
}
else
{
<option value="@value.Key">@value.Value</option>
}
}
</select>
}

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

@ -56,13 +56,14 @@ namespace Volo.Docs.Pages.Documents.Project
public bool DocumentLanguageIsDifferent { get; set; }
public DocumentSectionDictionary DocumentSections { get; set; }
public DocumentParametersDto DocumentPreferences { get; set; }
public DocumentRenderParameters UserPreferences { get; set; }
private readonly IDocumentAppService _documentAppService;
private readonly IDocumentToHtmlConverterFactory _documentToHtmlConverterFactory;
private readonly IProjectAppService _projectAppService;
private readonly IDocumentSectionHtmlReplacer _documentSectionHtmlReplacer;
private readonly IDocumentSectionFinder _documentSectionFinder;
private readonly IDocumentSectionRenderer _documentSectionRenderer;
private readonly DocsUiOptions _uiOptions;
public IndexModel(
@ -70,16 +71,14 @@ namespace Volo.Docs.Pages.Documents.Project
IDocumentToHtmlConverterFactory documentToHtmlConverterFactory,
IProjectAppService projectAppService,
IOptions<DocsUiOptions> options,
IDocumentSectionHtmlReplacer documentSectionHtmlReplacer,
IDocumentSectionFinder documentSectionFinder)
IDocumentSectionRenderer documentSectionRenderer)
{
ObjectMapperContext = typeof(DocsWebModule);
_documentAppService = documentAppService;
_documentToHtmlConverterFactory = documentToHtmlConverterFactory;
_projectAppService = projectAppService;
_documentSectionHtmlReplacer = documentSectionHtmlReplacer;
_documentSectionFinder = documentSectionFinder;
_documentSectionRenderer = documentSectionRenderer;
_uiOptions = options.Value;
}
@ -361,7 +360,7 @@ namespace Volo.Docs.Pages.Documents.Project
}
}
ConvertDocumentContentToHtml();
await ConvertDocumentContentToHtmlAsync();
}
private void SetLanguageSelectListItems()
@ -380,11 +379,13 @@ namespace Volo.Docs.Pages.Documents.Project
}
}
private void ConvertDocumentContentToHtml()
private async Task ConvertDocumentContentToHtmlAsync()
{
DocumentSections = _documentSectionFinder.Find(Document.Content);
await SetDocumentPreferences();
UserPreferences = GetParameters();
Document.Content = _documentSectionHtmlReplacer.Replace(Document.Content);
Document.Content = await _documentSectionRenderer.Render(Document.Content, UserPreferences);
var converter = _documentToHtmlConverterFactory.Create(Document.Format ?? Project.Format);
var content = converter.Convert(Project, Document, GetSpecificVersionOrLatest(), LanguageCode);
@ -404,5 +405,93 @@ namespace Volo.Docs.Pages.Documents.Project
Document.Content = content;
}
private DocumentRenderParameters GetParameters()
{
var parameters = new DocumentRenderParameters();
var cookie = Request.Cookies["AbpIoDocsPreferences"];
if (cookie != null)
{
var keyValues = cookie.Split("|");
foreach (var keyValue in keyValues)
{
if (keyValue.Split("=").Length < 2)
{
continue;
}
var key = keyValue.Split("=")[0];
var value = keyValue.Split("=")[1];
parameters.Add(key, value);
}
}
var query = Request.Query;
foreach (var keyValue in query)
{
if (parameters.ContainsKey(keyValue.Key))
{
parameters.Remove(keyValue.Key);
}
parameters.Add(keyValue.Key, keyValue.Value);
}
foreach (var parameter in DocumentPreferences.Parameters)
{
if (!parameters.ContainsKey(parameter.Name))
{
parameters.Add(parameter.Name, parameter.Values.FirstOrDefault().Key);
}
}
return parameters;
}
public async Task SetDocumentPreferences()
{
var projectParameters = await _documentAppService.GetParametersAsync(
new GetParametersDocumentInput
{
ProjectId = Project.Id,
LanguageCode = LanguageCode,
Version = Version
});
var availableparameters = await _documentSectionRenderer.GetAvailableParametersAsync(Document.Content);
DocumentPreferences = new DocumentParametersDto
{
Parameters = new List<DocumentParameterDto>()
};
foreach (var parameter in projectParameters.Parameters)
{
var availableParameter = availableparameters.GetOrDefault(parameter.Name);
if (availableParameter != null)
{
var newParameter = new DocumentParameterDto
{
Name = parameter.Name,
DisplayName = parameter.DisplayName,
Values = new Dictionary<string, string>()
};
foreach (var value in parameter.Values)
{
if (availableParameter.Contains(value.Key))
{
newParameter.Values.Add(value.Key, value.Value);
}
}
DocumentPreferences.Parameters.Add(newParameter);
}
}
}
}
}
}

244
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js

@ -1,130 +1,11 @@
(function ($) {
$(function () {
var initToc = function () {
function handleCustomScrolls() {
var wWidth = $(window).width();
if (wWidth > 766) {
$("#sidebar-scroll").mCustomScrollbar({
theme: "minimal"
});
$("#scroll-index").mCustomScrollbar({
theme: "minimal-dark"
});
}
}
$('li:not(.last-link) a.tree-toggle').click(function () {
$(this).parent().children('ul.tree').toggle(100);
$(this).closest("li").toggleClass("selected-tree");
});
$('li:not(.last-link) span.plus-icon i.fa-chevron-right').click(function () {
var $element = $(this).parent();
$element.parent().children('ul.tree').toggle(100);
$element.closest("li").toggleClass("selected-tree");
});
var scrollTopBtn = $(".scroll-top-btn");
var enoughHeight = $(".docs-sidebar-wrapper > .docs-top").height() + 60;
$(window).scroll(function () {
var topPos = $(window).scrollTop();
if (topPos > enoughHeight) {
$(scrollTopBtn).addClass("showup");
$("body").addClass("scrolled");
} else {
$(scrollTopBtn).removeClass("showup");
$("body").removeClass("scrolled");
}
});
$(scrollTopBtn).click(function () {
$('html, body').animate({
scrollTop: 0
}, 500);
return false;
});
var scrollToHashLink = function () {
var hash = window.location.hash;
if (!hash || hash === "#") {
return;
}
var $targetElement = $(hash);
$targetElement = $targetElement.length ? $targetElement : $('[name=' + this.hash.slice(1) + ']');
if (!$targetElement.length) {
return;
}
$('html,body').stop().animate({
scrollTop: $targetElement.offset().top
}, 200);
return;
};
var createToc = function () {
handleCustomScrolls();
$("#docs-sticky-index").empty();
var $myNav = $("#docs-sticky-index");
Toc.init($myNav);
$("body").scrollspy({
target: $myNav
});
$("#docs-sticky-index a").on('click', function (event) {
if (this.hash !== "") {
event.preventDefault();
var hash = this.hash;
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 500, function () {
window.location.hash = hash;
});
}
});
$(".btn-toggle").on("click", function () {
$(".toggle-row").slideToggle(400);
$(this).toggleClass("less");
});
$(".close-mmenu").on("click", function () {
$(".navbar-collapse").removeClass("show");
});
$(".open-dmenu").on("click", function () {
$(".docs-tree-list").slideToggle();
});
scrollToHashLink();
};
$(window).resize(function () {
handleCustomScrolls();
});
createToc();
};
var initNavigationFilter = function (navigationContainerId) {
var $navigation = $("#" + navigationContainerId);
var getShownDocumentLinks = function () {
return $navigation.find(".mCSB_container > li a:visible").not(".tree-toggle");
};
@ -222,25 +103,27 @@
};
var initSections = function () {
var getQueryStringParameterByName = function (name) {
var url = window.location.href;
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
};
var setQueryString = function () {
var clearQueryString = function () {
var uri = window.location.href.toString();
if (uri.indexOf("?") > 0) {
uri = uri.substring(0, uri.indexOf("?"));
}
window.history.replaceState({}, document.title, uri);
};
var setQueryString = function () {
clearQueryString();
var uri = window.location.href.toString();
var comboboxes = $(".doc-section-combobox");
if (comboboxes.length < 1) {
return;
}
var new_uri = uri + "?";
for (var i = 0; i < comboboxes.length; i++) {
@ -257,99 +140,47 @@
window.history.replaceState({}, document.title, new_uri);
};
var setSections = function () {
var setCookies = function () {
var cookie = abp.utils.getCookieValue("AbpIoDocsPreferences");
var sections = $(".doc-section");
if (!cookie || cookie == null || cookie === null) {
cookie = "";
}
var keyValues = cookie.split("|");
var comboboxes = $(".doc-section-combobox");
var comboboxKeys = [];
var comboboxSelectedValues = [];
for (var i = 0; i < comboboxes.length; i++) {
comboboxKeys.push($(comboboxes[i]).data("key"));
comboboxSelectedValues.push(comboboxes[i].value);
}
for (i = 0; i < sections.length; i++) {
var keys = $(sections[i]).data("keys");
var values = $(sections[i]).data("values");
var show = false;
var keysSplitted;
var valuesSplitted;
if (keys.indexOf("&") >= 0) {
keysSplitted = keys.split("&");
valuesSplitted = values.split("&");
var hide = false;
var key = $(comboboxes[i]).data('key');
var value = comboboxes[i].value;
for (var k = 0; k < keysSplitted.length; k++) {
if (valuesSplitted[k] !== comboboxSelectedValues[comboboxKeys.indexOf(keysSplitted[k])]) {
hide = true;
break;
}
}
var changed = false;
var keyValueslength = keyValues.length;
for (var k = 0; k < keyValueslength; k++) {
var splitted = keyValues[k].split("=");
show = !hide;
}
else if (keys.indexOf("|") >= 0) {
keysSplitted = keys.split("|");
valuesSplitted = values.split("|");
for (k = 0; k < keysSplitted.length; k++) {
if (valuesSplitted[k] === comboboxSelectedValues[comboboxKeys.indexOf(keysSplitted[k])]) {
show = true;
break;
}
}
}
else {
if (values === comboboxSelectedValues[comboboxKeys.indexOf(keys)]) {
show = true;
if (splitted.length > 0 && splitted[0] === key) {
keyValues[k] = key + "=" + value;
console.log(keyValues[k]);
changed = true;
}
}
var headers = $(sections[i]).find(':header');
if (show) {
headers.removeAttr('data-toc-skip');
$(sections[i]).show();
}
else {
headers.attr('data-toc-skip', 'true');
$(sections[i]).hide();
if (!changed) {
keyValues.push(key + "=" + value);
}
}
setQueryString();
initToc();
abp.utils.setCookieValue("AbpIoDocsPreferences", keyValues.join('|'));
};
$(".doc-section-combobox").change(function () {
localStorage["abp-doc-section-" + $(this).data("key")] = this.value;
setSections();
setCookies();
clearQueryString();
location.reload();
});
var comboboxes = $(".doc-section-combobox");
for (var i = 0; i < comboboxes.length; i++) {
var key = $(comboboxes[i]).data("key");
var cacheValue = localStorage["abp-doc-section-" + key];
if (cacheValue) {
comboboxes[i].value = cacheValue;
}
var queryValue = getQueryStringParameterByName(key);
if (queryValue) {
comboboxes[i].value = queryValue;
}
}
setSections();
setQueryString();
};
@ -361,7 +192,6 @@
initSections();
initToc();
});
})(jQuery);

113
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js

@ -1,4 +1,117 @@
(function ($) {
$(function () {
$('li:not(.last-link) a.tree-toggle').click(function () {
$(this).parent().children('ul.tree').toggle(100);
$(this).closest("li").toggleClass("selected-tree");
});
$('li:not(.last-link) span.plus-icon i.fa-chevron-right').click(function () {
var $element = $(this).parent();
$element.parent().children('ul.tree').toggle(100);
$element.closest("li").toggleClass("selected-tree");
});
var scrollTopBtn = $(".scroll-top-btn");
var enoughHeight = $(".docs-sidebar-wrapper > .docs-top").height() + 60;
$(window).scroll(function () {
var topPos = $(window).scrollTop();
if (topPos > enoughHeight) {
$(scrollTopBtn).addClass("showup");
$("body").addClass("scrolled");
} else {
$(scrollTopBtn).removeClass("showup");
$("body").removeClass("scrolled");
}
});
$(scrollTopBtn).click(function () {
$('html, body').animate({
scrollTop: 0
}, 500);
return false;
});
var scrollToHashLink = function () {
var hash = window.location.hash;
if (!hash || hash === "#") {
return;
}
var $targetElement = $(hash);
$targetElement = $targetElement.length ? $targetElement : $('[name=' + this.hash.slice(1) + ']');
if (!$targetElement.length) {
return;
}
$('html,body').stop().animate({
scrollTop: $targetElement.offset().top
}, 200);
return;
};
$(document).ready(function () {
handleCustomScrolls();
var $myNav = $("#docs-sticky-index");
Toc.init($myNav);
$("body").scrollspy({
target: $myNav
});
$("#docs-sticky-index a").on('click', function (event) {
if (this.hash !== "") {
event.preventDefault();
var hash = this.hash;
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 500, function () {
window.location.hash = hash;
});
}
});
$(".btn-toggle").on("click", function () {
$(".toggle-row").slideToggle(400);
$(this).toggleClass("less");
});
$(".close-mmenu").on("click", function () {
$(".navbar-collapse").removeClass("show");
});
$(".open-dmenu").on("click", function () {
$(".docs-tree-list").slideToggle();
});
scrollToHashLink();
});
$(window).resize(function () {
handleCustomScrolls();
});
});
function handleCustomScrolls() {
var wWidth = $(window).width();
if (wWidth > 766) {
$("#sidebar-scroll").mCustomScrollbar({
theme: "minimal"
});
$("#scroll-index").mCustomScrollbar({
theme: "minimal-dark"
});
}
}
window.Toc.helpers.createNavList = function () {
return $('<ul class="nav nav-pills flex-column"></ul>');
};

1
modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj

@ -19,6 +19,7 @@
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Packages\Volo.Abp.AspNetCore.Mvc.UI.Packages.csproj" />
<ProjectReference Include="..\Volo.Docs.HttpApi\Volo.Docs.HttpApi.csproj" />
<PackageReference Include="Markdig.Signed" Version="0.15.6" />
<PackageReference Include="Scriban" Version="2.1.0" />
</ItemGroup>

3
modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocsTestDataBuilder.cs

@ -27,7 +27,8 @@ namespace Volo.Docs
GithubDocumentStore.Type,
"md",
"index",
"docs-nav.json"
"docs-nav.json",
"docs-params.json"
);
project

Loading…
Cancel
Save