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