From a164e1b786e9c1f50a3aa71b4ab91783fc044ede Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 3 Dec 2019 11:41:13 +0300 Subject: [PATCH 01/11] Docs module conditional section feature resolves https://github.com/abpframework/abp/issues/1626 --- .../HtmlConverting/DocumentSectionConsts.cs | 10 +++ .../DocumentSectionDictionary.cs | 8 ++ .../HtmlConverting/DocumentSectionFinder.cs | 67 ++++++++++++++++ .../DocumentSectionHtmlReplacer.cs | 22 +++++ .../HtmlConverting/IDocumentSectionFinder.cs | 9 +++ .../IDocumentSectionHtmlReplacer.cs | 9 +++ .../Pages/Documents/Project/Index.cshtml | 17 ++++ .../Pages/Documents/Project/Index.cshtml.cs | 14 +++- .../Pages/Documents/Project/index.js | 80 ++++++++++++++++++- 9 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs new file mode 100644 index 0000000000..ca3e8697e4 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs @@ -0,0 +1,10 @@ +namespace Volo.Docs.HtmlConverting +{ + public class DocumentSectionConsts + { + public const string SectionOpenerPrefix = "[doc-section:"; + public const string SectionOpenerKeyValueSeparator = "="; + public const string SectionOpenerPostfix = "]"; + public const string SectionCloser = "[/doc-section]"; + } +} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs new file mode 100644 index 0000000000..1354a548a8 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Docs.HtmlConverting +{ + public class DocumentSectionDictionary : Dictionary> + { + } +} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs new file mode 100644 index 0000000000..b8d8fd8c17 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs @@ -0,0 +1,67 @@ +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 Logger { get; set; } + + public DocumentSectionFinder() + { + Logger = NullLogger.Instance; + } + + public DocumentSectionDictionary Find(string document) + { + return FindNextSections(document, new DocumentSectionDictionary()); + 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 keyValueWithSeparator = targetPartOfDocument.Substring(startOfSection) + [DocumentSectionConsts.SectionOpenerPrefix.Length..endOfSectionOpener]; + + 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() { value }); + } + + var endOfSection = targetPartOfDocument.IndexOf(DocumentSectionConsts.SectionCloser, StringComparison.InvariantCulture) + + DocumentSectionConsts.SectionCloser.Length; + + return FindNextSections(targetPartOfDocument.Substring(endOfSection), sections); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs new file mode 100644 index 0000000000..55a7013d12 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs @@ -0,0 +1,22 @@ +namespace Volo.Docs.HtmlConverting +{ + public class DocumentSectionHtmlReplacer : IDocumentSectionHtmlReplacer + { + public string Replace(string document, DocumentSectionDictionary sections) + { + foreach (var key in sections) + { + foreach (var value in key.Value) + { + document = document.Replace( + DocumentSectionConsts.SectionOpenerPrefix + key.Key + DocumentSectionConsts.SectionOpenerKeyValueSeparator + value + DocumentSectionConsts.SectionOpenerPostfix, + $"
"); + } + } + + document = document.Replace(DocumentSectionConsts.SectionCloser, "
"); + + return document; + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs new file mode 100644 index 0000000000..14f7944869 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs @@ -0,0 +1,9 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Docs.HtmlConverting +{ + public interface IDocumentSectionFinder: ITransientDependency + { + public DocumentSectionDictionary Find(string document); + } +} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs new file mode 100644 index 0000000000..7f517bc341 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs @@ -0,0 +1,9 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Docs.HtmlConverting +{ + public interface IDocumentSectionHtmlReplacer : ITransientDependency + { + public string Replace(string document, DocumentSectionDictionary sections); + } +} 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 f74a47fb50..afa397556f 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 @@ -207,10 +207,27 @@ } } + + + @if (Model.DocumentSections != null && Model.DocumentSections.Count > 0) + { + foreach (var key in Model.DocumentSections) + { + @(key.Key + ":") + + } + } +
+ @if (Model.DocumentLanguageIsDifferent) { diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index d675251ac4..c06f24f7fa 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -56,22 +56,30 @@ namespace Volo.Docs.Pages.Documents.Project public bool DocumentLanguageIsDifferent { get; set; } + public DocumentSectionDictionary DocumentSections { get; set; } + private readonly IDocumentAppService _documentAppService; private readonly IDocumentToHtmlConverterFactory _documentToHtmlConverterFactory; private readonly IProjectAppService _projectAppService; + private readonly IDocumentSectionHtmlReplacer _documentSectionHtmlReplacer; + private readonly IDocumentSectionFinder _documentSectionFinder; private readonly DocsUiOptions _uiOptions; public IndexModel( IDocumentAppService documentAppService, IDocumentToHtmlConverterFactory documentToHtmlConverterFactory, IProjectAppService projectAppService, - IOptions options) + IOptions options, + IDocumentSectionHtmlReplacer documentSectionHtmlReplacer, + IDocumentSectionFinder documentSectionFinder) { ObjectMapperContext = typeof(DocsWebModule); _documentAppService = documentAppService; _documentToHtmlConverterFactory = documentToHtmlConverterFactory; _projectAppService = projectAppService; + _documentSectionHtmlReplacer = documentSectionHtmlReplacer; + _documentSectionFinder = documentSectionFinder; _uiOptions = options.Value; } @@ -374,6 +382,10 @@ namespace Volo.Docs.Pages.Documents.Project private void ConvertDocumentContentToHtml() { + DocumentSections = _documentSectionFinder.Find(Document.Content); + + Document.Content = _documentSectionHtmlReplacer.Replace(Document.Content, DocumentSections); + var converter = _documentToHtmlConverterFactory.Create(Document.Format ?? Project.Format); var content = converter.Convert(Project, Document, GetSpecificVersionOrLatest(), LanguageCode); diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 8eb2083749..6b27b20a7f 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -2,7 +2,7 @@ $(function () { var initNavigationFilter = function (navigationContainerId) { - + var $navigation = $("#" + navigationContainerId); @@ -102,12 +102,90 @@ ); }; + + 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 uri = window.location.href.toString(); + + if (uri.indexOf("?") > 0) { + uri = uri.substring(0, uri.indexOf("?")); + } + + var comboboxes = $(".doc-section-combobox"); + + var new_uri = uri + "?"; + + for (var i = 0; i < comboboxes.length; i++) { + var key = $(comboboxes[i]).data('key'); + var value = comboboxes[i].value; + + new_uri += key + "=" + value; + + if (i !== comboboxes.length - 1) { + new_uri += "&"; + } + } + + window.history.replaceState({}, document.title, new_uri); + }; + + var changeSections = function (combobox) { + var key = $(combobox).data('key'); + var value = combobox.value; + + $(".doc-section[data-key=" + key + "]").hide(); + $(".doc-section[data-key=" + key + "][data-value=" + value + "]").show(); + + localStorage["abp-doc-section-" + key] = value; + + setQueryString(); + }; + + $(".doc-section-combobox").change(function () { + changeSections(this); + }); + + 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; + } + } + + for (var k = 0; k < comboboxes.length; k++) { + changeSections(comboboxes[k]); + } + }; + + initNavigationFilter("sidebar-scroll"); initAnchorTags(".docs-page .docs-body"); initSocialShareLinks(); + initSections(); + }); })(jQuery); From 2850206fef6e4794734ee83ca44eeb7381b0cdfa Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 3 Dec 2019 13:28:09 +0300 Subject: [PATCH 02/11] Update DocumentSectionFinder.cs --- .../src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs index b8d8fd8c17..f6f2c9aaee 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs @@ -16,7 +16,6 @@ namespace Volo.Docs.HtmlConverting public DocumentSectionDictionary Find(string document) { - return FindNextSections(document, new DocumentSectionDictionary()); try { return FindNextSections(document, new DocumentSectionDictionary()); From 567a78b235fee01aaa1bcd6a06f1a6109bb84e86 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 3 Dec 2019 13:38:14 +0300 Subject: [PATCH 03/11] document section now supports inner seciton --- .../Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs index f6f2c9aaee..5b1c1bfa1b 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs @@ -57,10 +57,7 @@ namespace Volo.Docs.HtmlConverting sections.Add(key, new List() { value }); } - var endOfSection = targetPartOfDocument.IndexOf(DocumentSectionConsts.SectionCloser, StringComparison.InvariantCulture) - + DocumentSectionConsts.SectionCloser.Length; - - return FindNextSections(targetPartOfDocument.Substring(endOfSection), sections); + return FindNextSections(targetPartOfDocument.Substring(endOfSectionOpener), sections); } } } From 76d32f8af21061bec78f79d41fad4108677b34ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 3 Dec 2019 15:51:43 +0300 Subject: [PATCH 04/11] Disable document resource cache on development --- .../Volo/Docs/Documents/DocumentAppService.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs index 186f9827b0..d23f071d43 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Volo.Abp.Application.Services; using Volo.Abp.Caching; using Volo.Docs.Projects; @@ -18,19 +16,21 @@ namespace Volo.Docs.Documents protected IDistributedCache DocumentCache { get; } protected IDistributedCache LanguageCache { get; } protected IDistributedCache ResourceCache { get; } - + protected IHostEnvironment HostEnvironment { get; } public DocumentAppService( IProjectRepository projectRepository, IDocumentStoreFactory documentStoreFactory, IDistributedCache documentCache, IDistributedCache languageCache, - IDistributedCache resourceCache) + IDistributedCache resourceCache, + IHostEnvironment hostEnvironment) { _projectRepository = projectRepository; _documentStoreFactory = documentStoreFactory; DocumentCache = documentCache; LanguageCache = languageCache; ResourceCache = resourceCache; + HostEnvironment = hostEnvironment; } public virtual async Task GetAsync(GetDocumentInput input) @@ -83,7 +83,7 @@ namespace Volo.Docs.Documents return ObjectMapper.Map(documentResource); } - if (Debugger.IsAttached) + if (HostEnvironment.IsDevelopment()) { return await GetResourceAsync(); } @@ -119,7 +119,7 @@ namespace Volo.Docs.Documents return CreateDocumentWithDetailsDto(project, document); } - if (Debugger.IsAttached) + if (HostEnvironment.IsDevelopment()) { return await GetDocumentAsync(); } From bb6121824a2b49e5455565d921202853c8f48a5c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 3 Dec 2019 17:06:38 +0300 Subject: [PATCH 05/11] document sections support and/or --- .../HtmlConverting/DocumentSectionConsts.cs | 2 + .../HtmlConverting/DocumentSectionFinder.cs | 40 ++++++++++- .../DocumentSectionHtmlReplacer.cs | 43 +++++++++-- .../HtmlConverting/HtmlNormalizer.cs | 2 - .../IDocumentSectionHtmlReplacer.cs | 2 +- .../Pages/Documents/Project/Index.cshtml.cs | 2 +- .../Pages/Documents/Project/index.js | 72 ++++++++++++++++--- 7 files changed, 138 insertions(+), 25 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs index ca3e8697e4..ba8d566563 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionConsts.cs @@ -4,6 +4,8 @@ { public const string SectionOpenerPrefix = "[doc-section:"; public const string SectionOpenerKeyValueSeparator = "="; + public const string SectionOpenerAndCondition = "&"; + public const string SectionOpenerOrCondition = "|"; public const string SectionOpenerPostfix = "]"; public const string SectionCloser = "[/doc-section]"; } diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs index 5b1c1bfa1b..14ffbd7e61 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs @@ -30,7 +30,7 @@ namespace Volo.Docs.HtmlConverting } } - private DocumentSectionDictionary FindNextSections(string targetPartOfDocument, DocumentSectionDictionary sections) + private DocumentSectionDictionary FindNextSections(string targetPartOfDocument, DocumentSectionDictionary sections) { var startOfSection = targetPartOfDocument.IndexOf(DocumentSectionConsts.SectionOpenerPrefix, StringComparison.InvariantCulture); @@ -41,10 +41,44 @@ namespace Volo.Docs.HtmlConverting var endOfSectionOpener = targetPartOfDocument.Substring(startOfSection).IndexOf(DocumentSectionConsts.SectionOpenerPostfix, StringComparison.InvariantCulture); - var keyValueWithSeparator = targetPartOfDocument.Substring(startOfSection) + 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]; @@ -57,7 +91,7 @@ namespace Volo.Docs.HtmlConverting sections.Add(key, new List() { value }); } - return FindNextSections(targetPartOfDocument.Substring(endOfSectionOpener), sections); + return sections; } } } diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs index 55a7013d12..2e452d730a 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs @@ -1,17 +1,46 @@ -namespace Volo.Docs.HtmlConverting +using System; + +namespace Volo.Docs.HtmlConverting { public class DocumentSectionHtmlReplacer : IDocumentSectionHtmlReplacer { - public string Replace(string document, DocumentSectionDictionary sections) + public string Replace(string document) { - foreach (var key in sections) + while (document.Contains(DocumentSectionConsts.SectionOpenerPrefix)) { - foreach (var value in key.Value) + 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++) { - document = document.Replace( - DocumentSectionConsts.SectionOpenerPrefix + key.Key + DocumentSectionConsts.SectionOpenerKeyValueSeparator + value + DocumentSectionConsts.SectionOpenerPostfix, - $"
"); + keys[i] = keysValuesSplitted[i].Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator)[0]; + values[i] = keysValuesSplitted[i].Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator)[1]; } + + var div = $"
"; + + document = document.Remove(sectionIndex, sectionCloserIndex + DocumentSectionConsts.SectionOpenerPrefix.Length +1); + + document = document.Insert(sectionIndex, div); } document = document.Replace(DocumentSectionConsts.SectionCloser, "
"); diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/HtmlNormalizer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/HtmlNormalizer.cs index ed3f999614..6f0a680ce2 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/HtmlNormalizer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/HtmlNormalizer.cs @@ -28,7 +28,6 @@ namespace Volo.Docs.HtmlConverting }, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline); - return content; } @@ -36,6 +35,5 @@ namespace Volo.Docs.HtmlConverting { return Regex.Replace(content, "", "", RegexOptions.IgnoreCase); } - } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs index 7f517bc341..509bee0798 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs @@ -4,6 +4,6 @@ namespace Volo.Docs.HtmlConverting { public interface IDocumentSectionHtmlReplacer : ITransientDependency { - public string Replace(string document, DocumentSectionDictionary sections); + public string Replace(string document); } } diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index c06f24f7fa..083f045227 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -384,7 +384,7 @@ namespace Volo.Docs.Pages.Documents.Project { DocumentSections = _documentSectionFinder.Find(Document.Content); - Document.Content = _documentSectionHtmlReplacer.Replace(Document.Content, DocumentSections); + Document.Content = _documentSectionHtmlReplacer.Replace(Document.Content); var converter = _documentToHtmlConverterFactory.Create(Document.Format ?? Project.Format); var content = converter.Convert(Project, Document, GetSpecificVersionOrLatest(), LanguageCode); diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 6b27b20a7f..6343e6bc83 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -102,7 +102,6 @@ ); }; - var initSections = function () { var getQueryStringParameterByName = function (name) { var url = window.location.href; @@ -139,20 +138,73 @@ window.history.replaceState({}, document.title, new_uri); }; - var changeSections = function (combobox) { - var key = $(combobox).data('key'); - var value = combobox.value; + var setSections = function () { + + var sections = $(".doc-section"); + + 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; - $(".doc-section[data-key=" + key + "]").hide(); - $(".doc-section[data-key=" + key + "][data-value=" + value + "]").show(); + for (var k = 0; k < keysSplitted.length; k++) { + if (valuesSplitted[k] !== comboboxSelectedValues[comboboxKeys.indexOf(keysSplitted[k])]) { + hide = true; + break; + } + } - localStorage["abp-doc-section-" + key] = value; + 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 (show) { + $(sections[i]).show(); + } + else { + $(sections[i]).hide(); + } + } setQueryString(); }; $(".doc-section-combobox").change(function () { - changeSections(this); + localStorage["abp-doc-section-" + $(this).data("key")] = this.value; + setSections(); }); var comboboxes = $(".doc-section-combobox"); @@ -172,9 +224,7 @@ } } - for (var k = 0; k < comboboxes.length; k++) { - changeSections(comboboxes[k]); - } + setSections(); }; From 0845b3a8d104241447ac111f6b593465ef8d855b Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 4 Dec 2019 09:44:52 +0300 Subject: [PATCH 06/11] doc sections: use span instead of div for inline texts --- .../HtmlConverting/DocumentSectionHtmlReplacer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs index 2e452d730a..ece94f8ee5 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs @@ -32,18 +32,18 @@ namespace Volo.Docs.HtmlConverting values[i] = keysValuesSplitted[i].Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator)[1]; } - var div = $"
"; + $"\">"; document = document.Remove(sectionIndex, sectionCloserIndex + DocumentSectionConsts.SectionOpenerPrefix.Length +1); document = document.Insert(sectionIndex, div); } - document = document.Replace(DocumentSectionConsts.SectionCloser, "
"); + document = document.Replace(DocumentSectionConsts.SectionCloser, ""); return document; } From 028006a623b39ee191d09911f483396479ca2548 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 4 Dec 2019 10:32:16 +0300 Subject: [PATCH 07/11] document sections: adaptive toc --- .../Pages/Documents/Project/index.js | 128 +++++++++++++++++- .../Pages/Documents/Shared/Scripts/vs.js | 113 ---------------- 2 files changed, 127 insertions(+), 114 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 6343e6bc83..0784549262 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -1,11 +1,130 @@ (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"); }; @@ -191,15 +310,21 @@ } } + 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(); } } setQueryString(); + + initToc(); }; $(".doc-section-combobox").change(function () { @@ -236,6 +361,7 @@ initSections(); + initToc(); }); })(jQuery); diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js index dcf9916619..7a081943c0 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js @@ -1,117 +1,4 @@ (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 $(''); }; From 8648c0b9e2a12d495809bfede242b148fce6942b Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 4 Dec 2019 18:00:02 +0300 Subject: [PATCH 08/11] doc sections Scriban --- .../Docs/Admin/Projects/CreateProjectDto.cs | 2 + .../Docs/Admin/Projects/UpdateProjectDto.cs | 2 + .../Admin/Projects/ProjectAdminAppService.cs | 3 +- .../Docs/Admin/Projects/Create.cshtml.cs | 3 + .../Pages/Docs/Admin/Projects/Edit.cshtml.cs | 3 + .../Docs/Documents/DocumentParameterDto.cs | 13 + .../Docs/Documents/DocumentParametersDto.cs | 9 + .../Documents/GetParametersDocumentInput.cs | 19 ++ .../Docs/Documents/IDocumentAppService.cs | 2 + .../Volo/Docs/Documents/DocumentAppService.cs | 16 ++ .../Volo/Docs/Projects/ProjectConsts.cs | 1 + .../GitHub/Documents/GithubDocumentStore.cs | 3 +- .../Volo/Docs/Projects/Project.cs | 14 +- .../DocsDbContextModelBuilderExtensions.cs | 1 + .../Docs/Documents/DocsDocumentController.cs | 5 + ...ctionary.cs => DocumentParseParamaters.cs} | 4 +- .../HtmlConverting/DocumentSectionFinder.cs | 97 ------- .../DocumentSectionHtmlReplacer.cs | 51 ---- .../HtmlConverting/IDocumentSectionFinder.cs | 9 - .../IDocumentSectionHtmlReplacer.cs | 9 - .../IDocumentSectionRenderer.cs | 15 ++ .../ScribanDocumentSectionParser.cs | 115 +++++++++ .../Pages/Documents/Project/Index.cshtml | 19 +- .../Pages/Documents/Project/Index.cshtml.cs | 113 +++++++- .../Pages/Documents/Project/index.js | 244 +++--------------- .../Pages/Documents/Shared/Scripts/vs.js | 113 ++++++++ .../src/Volo.Docs.Web/Volo.Docs.Web.csproj | 1 + .../Volo/Docs/DocsTestDataBuilder.cs | 3 +- 28 files changed, 492 insertions(+), 397 deletions(-) create mode 100644 modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParameterDto.cs create mode 100644 modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParametersDto.cs create mode 100644 modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs rename modules/docs/src/Volo.Docs.Web/HtmlConverting/{DocumentSectionDictionary.cs => DocumentParseParamaters.cs} (52%) delete mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs delete mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs delete mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs delete mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs create mode 100644 modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs index 2427d2d51f..eb603b334c 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs +++ b/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; } diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs index b2ac8472ae..9e94cec66e 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs +++ b/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; } diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs index d1812ec410..d5aef3e614 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs +++ b/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, diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs index 4e5cbd1fbc..dc4af5e94c 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs +++ b/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; } diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs index e1b83b8177..49b569d18c 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs +++ b/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; } diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParameterDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParameterDto.cs new file mode 100644 index 0000000000..ea387b2794 --- /dev/null +++ b/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 Values { get; set; } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParametersDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentParametersDto.cs new file mode 100644 index 0000000000..0e1d1fdb9c --- /dev/null +++ b/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 Parameters {get;set;} + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs new file mode 100644 index 0000000000..33bd25b394 --- /dev/null +++ b/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; } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs index fa8345a7c3..cfc4840824 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs @@ -11,6 +11,8 @@ namespace Volo.Docs.Documents Task GetNavigationAsync(GetNavigationDocumentInput input); + Task GetParametersAsync(GetParametersDocumentInput input); + Task GetResourceAsync(GetDocumentResourceInput input); } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs index d23f071d43..ae42b3acf4 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs +++ b/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 GetParametersAsync(GetParametersDocumentInput input) + { + var project = await _projectRepository.GetAsync(input.ProjectId); + + var document = await GetDocumentWithDetailsDtoAsync( + project, + project.ParametersDocumentName, + input.LanguageCode, + input.Version + ); + + return JsonConvert.DeserializeObject(document.Content); + } + protected virtual async Task GetDocumentWithDetailsDtoAsync( Project project, string documentName, @@ -143,5 +158,6 @@ namespace Volo.Docs.Documents documentDto.Contributors = ObjectMapper.Map, List>(document.Contributors); return documentDto; } + } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs index 57f3c17112..927a1a4c59 100644 --- a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs +++ b/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; } diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs index a5c81d46fc..bd399a4f83 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs +++ b/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(), - //Contributors = !isNavigationDocument ? await GetContributors(commitHistoryUrl, token, userAgent): new List(), + //Contributors = !isNavigationDocument && !isParameterDocument ? await GetContributors(commitHistoryUrl, token, userAgent): new List(), Version = version, Content = await DownloadWebContentAsStringAsync(rawDocumentUrl, token, userAgent) }; diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs index 2a98ea6cff..45882be839 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs @@ -34,6 +34,11 @@ namespace Volo.Docs.Projects /// public virtual string NavigationDocumentName { get; protected set; } + /// + /// The document to be used for the parameters file (index). + /// + public virtual string ParametersDocumentName { get; protected set; } + public virtual string MinimumVersion { get; set; } /// @@ -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(); } @@ -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)); diff --git a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs index b9cada3e4d..f6a17b68d7 100644 --- a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs +++ b/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); }); } diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs index 54244bbe01..dd60b2de06 100644 --- a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs +++ b/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 GetParametersAsync(GetParametersDocumentInput input) + { + return DocumentAppService.GetParametersAsync(input); + } } } diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentParseParamaters.cs similarity index 52% rename from modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs rename to modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentParseParamaters.cs index 1354a548a8..7d9f26832f 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionDictionary.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentParseParamaters.cs @@ -2,7 +2,7 @@ namespace Volo.Docs.HtmlConverting { - public class DocumentSectionDictionary : Dictionary> + public class DocumentRenderParameters : Dictionary { } -} +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs deleted file mode 100644 index 14ffbd7e61..0000000000 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionFinder.cs +++ /dev/null @@ -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 Logger { get; set; } - - public DocumentSectionFinder() - { - Logger = NullLogger.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() { value }); - } - - return sections; - } - } -} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs deleted file mode 100644 index ece94f8ee5..0000000000 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentSectionHtmlReplacer.cs +++ /dev/null @@ -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 = $""; - - document = document.Remove(sectionIndex, sectionCloserIndex + DocumentSectionConsts.SectionOpenerPrefix.Length +1); - - document = document.Insert(sectionIndex, div); - } - - document = document.Replace(DocumentSectionConsts.SectionCloser, ""); - - return document; - } - } -} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs deleted file mode 100644 index 14f7944869..0000000000 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionFinder.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Volo.Abp.DependencyInjection; - -namespace Volo.Docs.HtmlConverting -{ - public interface IDocumentSectionFinder: ITransientDependency - { - public DocumentSectionDictionary Find(string document); - } -} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs deleted file mode 100644 index 509bee0798..0000000000 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionHtmlReplacer.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Volo.Abp.DependencyInjection; - -namespace Volo.Docs.HtmlConverting -{ - public interface IDocumentSectionHtmlReplacer : ITransientDependency - { - public string Replace(string document); - } -} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs new file mode 100644 index 0000000000..6bba74ee7f --- /dev/null +++ b/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 Render(string doucment, DocumentRenderParameters parameters); + + Task>> GetAvailableParametersAsync(string document); + } +} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs new file mode 100644 index 0000000000..71c6f0af03 --- /dev/null +++ b/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 Render(string document, DocumentRenderParameters parameters = null) + { + Template scribanTemplate; + if (parameters == null) + { + scribanTemplate = Template.Parse(document); + return scribanTemplate.Render(); + } + + var p2 = new Dictionary(); + + 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>> GetAvailableParametersAsync(string document) + { + try + { + var jsonOpener = "````json"; + var jsonCloser = "````"; + var docs_param = "//[doc-params]"; + + if (!document.Contains(jsonOpener)) + { + return new Dictionary>(); + } + + 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>>(pureJson); + } + + return new Dictionary>(); + } + catch (Exception e) + { + //log + return new Dictionary>(); + } + } + + private async Task 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; + } + } +} 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 afa397556f..47f912e980 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 @@ -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 + ":") - + @foreach (var value in parameter.Values) { - + @if (value.Key == (Model.UserPreferences.ContainsKey(parameter.Name) ? Model.UserPreferences[parameter.Name]:null)) + { + + } + else + { + + } } } diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index 083f045227..df0ab02f27 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/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 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() + }; + + 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() + }; + + foreach (var value in parameter.Values) + { + if (availableParameter.Contains(value.Key)) + { + newParameter.Values.Add(value.Key, value.Value); + } + } + + DocumentPreferences.Parameters.Add(newParameter); + } + + } + } } -} \ No newline at end of file +} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 0784549262..a2ef1803ac 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/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); diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js index 7a081943c0..dcf9916619 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js +++ b/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 $(''); }; diff --git a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj index cced411e33..27c806762e 100644 --- a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj +++ b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj @@ -19,6 +19,7 @@ + diff --git a/modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocsTestDataBuilder.cs b/modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocsTestDataBuilder.cs index 39ffc9691e..15fa70eee7 100644 --- a/modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocsTestDataBuilder.cs +++ b/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 From 1bb0bb61b433b2cb4dac31b290b739f0b30c6bee Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 5 Dec 2019 10:17:43 +0300 Subject: [PATCH 09/11] refactor --- .../Volo/Docs/Documents/DocumentAppService.cs | 24 ++-- .../IDocumentSectionRenderer.cs | 2 +- .../ScribanDocumentSectionParser.cs | 107 +++++++++--------- .../Pages/Documents/Project/Index.cshtml | 2 +- .../Pages/Documents/Project/Index.cshtml.cs | 39 ++++--- 5 files changed, 99 insertions(+), 75 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs index ae42b3acf4..b3b2a05b53 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs @@ -105,14 +105,22 @@ namespace Volo.Docs.Documents { var project = await _projectRepository.GetAsync(input.ProjectId); - var document = await GetDocumentWithDetailsDtoAsync( - project, - project.ParametersDocumentName, - input.LanguageCode, - input.Version - ); - - return JsonConvert.DeserializeObject(document.Content); + try + { + var document = await GetDocumentWithDetailsDtoAsync( + project, + project.ParametersDocumentName, + input.LanguageCode, + input.Version + ); + + return JsonConvert.DeserializeObject(document.Content); + } + catch (DocumentNotFoundException) + { + Logger.LogWarning($"Parameter file ({project.ParametersDocumentName}) not found."); + return new DocumentParametersDto(); + } } protected virtual async Task GetDocumentWithDetailsDtoAsync( diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs index 6bba74ee7f..2d9511d05b 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentSectionRenderer.cs @@ -8,7 +8,7 @@ namespace Volo.Docs.HtmlConverting { public interface IDocumentSectionRenderer: ITransientDependency { - Task Render(string doucment, DocumentRenderParameters parameters); + Task RenderAsync(string doucment, DocumentRenderParameters parameters); Task>> GetAvailableParametersAsync(string document); } diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs index 71c6f0af03..549a285d0c 100644 --- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionParser.cs @@ -4,94 +4,102 @@ using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json; using Scriban; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Volo.Docs.HtmlConverting { public class ScribanDocumentSectionRenderer : IDocumentSectionRenderer { - public async Task Render(string document, DocumentRenderParameters parameters = null) + private const string jsonOpener = "````json"; + private const string jsonCloser = "````"; + private const string docs_param = "//[doc-params]"; + + public ILogger Logger { get; set; } + + public ScribanDocumentSectionRenderer() { - Template scribanTemplate; - if (parameters == null) - { - scribanTemplate = Template.Parse(document); - return scribanTemplate.Render(); - } + Logger = NullLogger.Instance; + } - var p2 = new Dictionary(); + public async Task RenderAsync(string document, DocumentRenderParameters parameters = null) + { + Template scribanTemplate = Template.Parse(document); - foreach (var item in parameters) + if (parameters == null) { - p2.Add(item.Key, item.Value); + return await scribanTemplate.RenderAsync(); } - scribanTemplate = Template.Parse(document); - var result = scribanTemplate.Render(p2); + var result = await scribanTemplate.RenderAsync(parameters); + return RemoveOptionsJson(result); + } + public async Task>> GetAvailableParametersAsync(string document) + { try { - return await RemoveOptionsJson(result); + if (!document.Contains(jsonOpener) || !document.Contains(docs_param)) + { + return new Dictionary>(); + } + + var (jsonBeginningIndex, JsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document); + + if (jsonBeginningIndex < 0 || JsonEndingIndex <= 0 || string.IsNullOrWhiteSpace(insideJsonSection)) + { + return new Dictionary>(); + } + + var pureJson = insideJsonSection.Replace(docs_param, "").Trim(); + + return JsonConvert.DeserializeObject>>(pureJson); } catch (Exception) { - return scribanTemplate.Render(); + Logger.LogWarning("Unable to parse parameters of document."); + return new Dictionary>(); } } - public async Task>> GetAvailableParametersAsync(string document) + private string RemoveOptionsJson(string document) { + var orgDocument = document; try { - var jsonOpener = "````json"; - var jsonCloser = "````"; - var docs_param = "//[doc-params]"; - - if (!document.Contains(jsonOpener)) + if (!document.Contains(jsonOpener) || !document.Contains(docs_param)) { - return new Dictionary>(); + return orgDocument; } - 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(); + var (jsonBeginningIndex, JsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document); - return JsonConvert.DeserializeObject>>(pureJson); + if (jsonBeginningIndex < 0 || JsonEndingIndex <= 0 || string.IsNullOrWhiteSpace(insideJsonSection)) + { + return orgDocument; } - return new Dictionary>(); + return document.Remove( + jsonBeginningIndex - jsonOpener.Length, (JsonEndingIndex + jsonCloser.Length) - (jsonBeginningIndex - jsonOpener.Length) + ); } - catch (Exception e) + catch (Exception) { - //log - return new Dictionary>(); + return orgDocument; } } - private async Task RemoveOptionsJson(string document) + private (int, int, string) GetJsonBeginEndIndexesAndPureJson(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; + return (-1,-1,""); } var JsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(jsonCloser) + jsonBeginningIndex; @@ -103,13 +111,10 @@ namespace Volo.Docs.HtmlConverting continue; } - return document.Remove( - jsonBeginningIndex - jsonOpener.Length, (JsonEndingIndex + jsonCloser.Length) - (jsonBeginningIndex - jsonOpener.Length) - ); - + return (jsonBeginningIndex, JsonEndingIndex, insideJsonSection); } - return document; + return (-1, -1, ""); } } } 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 47f912e980..f4b5ca699e 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 @@ -209,7 +209,7 @@ } - @if (Model.DocumentPreferences != null && Model.DocumentPreferences.Parameters != null && Model.DocumentPreferences.Parameters.Count > 0) + @if (Model.DocumentPreferences != null && Model.DocumentPreferences.Parameters != null && Model.DocumentPreferences.Parameters.Any()) { foreach (var parameter in Model.DocumentPreferences.Parameters) { diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index df0ab02f27..37b92ac547 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -382,10 +382,9 @@ namespace Volo.Docs.Pages.Documents.Project private async Task ConvertDocumentContentToHtmlAsync() { await SetDocumentPreferences(); + SetUserPreferences(); - UserPreferences = GetParameters(); - - Document.Content = await _documentSectionRenderer.Render(Document.Content, UserPreferences); + Document.Content = await _documentSectionRenderer.RenderAsync(Document.Content, UserPreferences); var converter = _documentToHtmlConverterFactory.Create(Document.Format ?? Project.Format); var content = converter.Convert(Project, Document, GetSpecificVersionOrLatest(), LanguageCode); @@ -406,9 +405,9 @@ namespace Volo.Docs.Pages.Documents.Project Document.Content = content; } - private DocumentRenderParameters GetParameters() + private void SetUserPreferences() { - var parameters = new DocumentRenderParameters(); + UserPreferences = new DocumentRenderParameters(); var cookie = Request.Cookies["AbpIoDocsPreferences"]; @@ -425,7 +424,7 @@ namespace Volo.Docs.Pages.Documents.Project var key = keyValue.Split("=")[0]; var value = keyValue.Split("=")[1]; - parameters.Add(key, value); + UserPreferences.Add(key, value); } } @@ -433,22 +432,25 @@ namespace Volo.Docs.Pages.Documents.Project foreach (var keyValue in query) { - if (parameters.ContainsKey(keyValue.Key)) + if (UserPreferences.ContainsKey(keyValue.Key)) { - parameters.Remove(keyValue.Key); + UserPreferences.Remove(keyValue.Key); } - parameters.Add(keyValue.Key, keyValue.Value); + UserPreferences.Add(keyValue.Key, keyValue.Value); + } + + if (DocumentPreferences?.Parameters == null) + { + return; } foreach (var parameter in DocumentPreferences.Parameters) { - if (!parameters.ContainsKey(parameter.Name)) + if (!UserPreferences.ContainsKey(parameter.Name)) { - parameters.Add(parameter.Name, parameter.Values.FirstOrDefault().Key); + UserPreferences.Add(parameter.Name, parameter.Values.FirstOrDefault().Key); } } - - return parameters; } public async Task SetDocumentPreferences() @@ -461,6 +463,11 @@ namespace Volo.Docs.Pages.Documents.Project Version = Version }); + if (projectParameters?.Parameters == null) + { + return; + } + var availableparameters = await _documentSectionRenderer.GetAvailableParametersAsync(Document.Content); DocumentPreferences = new DocumentParametersDto @@ -468,6 +475,11 @@ namespace Volo.Docs.Pages.Documents.Project Parameters = new List() }; + if (availableparameters == null || !availableparameters.Any()) + { + return; + } + foreach (var parameter in projectParameters.Parameters) { var availableParameter = availableparameters.GetOrDefault(parameter.Name); @@ -490,7 +502,6 @@ namespace Volo.Docs.Pages.Documents.Project DocumentPreferences.Parameters.Add(newParameter); } - } } } From 70ee2e0d229cb19aab4f3ad55a1d85c304cfd955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 5 Dec 2019 10:27:03 +0300 Subject: [PATCH 10/11] Add defaults. --- .../docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs index 45882be839..f1cfd0d777 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs @@ -61,9 +61,9 @@ namespace Volo.Docs.Projects [NotNull] string shortName, [NotNull] string documentStoreType, [NotNull] string format, - [NotNull] string defaultDocumentName, - [NotNull] string navigationDocumentName, - [NotNull] string parametersDocumentName) + [NotNull] string defaultDocumentName = "Index", + [NotNull] string navigationDocumentName = "docs-nav.json", + [NotNull] string parametersDocumentName = "docs-params.json") { Id = id; From 7cf59482344b63a5538015b6b82d4f59f915fda4 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 5 Dec 2019 10:28:14 +0300 Subject: [PATCH 11/11] added info alert to doc selection --- .../src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 f4b5ca699e..bb84b8a0ea 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 @@ -208,6 +208,7 @@
} +