Browse Source

Merge branch 'salihozkara/docsImprovements' into salihozkara/abpUnited

pull/19876/head
Salih 3 years ago
parent
commit
29a1350a5f
  1. 16
      modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs
  2. 2
      modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs
  3. 25
      modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs
  4. 13
      modules/docs/src/Volo.Docs.Web/DocsUiOptions.cs
  5. 21
      modules/docs/src/Volo.Docs.Web/DocsWebModule.cs
  6. 40
      modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs
  7. 7
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs
  8. 5
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  9. 143
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs

16
modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -49,11 +48,16 @@ namespace VoloDocs.Web.Pages
//Eg: "/en/abp/latest" //Eg: "/en/abp/latest"
public string GetUrlForProject(ProjectDto project, string language = "en", string version = null) public string GetUrlForProject(ProjectDto project, string language = "en", string version = null)
{ {
return "." + var routeValues = new Dictionary<string, object> {
_urlUiOptions.RoutePrefix.EnsureStartsWith('/').EnsureEndsWith('/') + { nameof(Volo.Docs.Pages.Documents.Project.IndexModel.LanguageCode), language },
language.EnsureEndsWith('/') + { nameof(Volo.Docs.Pages.Documents.Project.IndexModel.Version), version ?? DocsAppConsts.Latest },
project.ShortName.EnsureEndsWith('/') + };
(version ?? DocsAppConsts.Latest);
if (!_urlUiOptions.SingleProjectMode.Enable)
{
routeValues.Add(nameof(Volo.Docs.Pages.Documents.Project.IndexModel.ProjectName), project.ShortName);
}
return Url.Page("/Documents/Project/Index", routeValues);
} }
} }
} }

2
modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs

@ -78,6 +78,8 @@ namespace VoloDocs.Web
Configure<DocsUiOptions>(options => Configure<DocsUiOptions>(options =>
{ {
options.RoutePrefix = null; options.RoutePrefix = null;
options.SingleProjectMode.Enable = true;
options.SingleProjectMode.ProjectName = "abp";
}); });
Configure<DocsElasticSearchOptions>(options => Configure<DocsElasticSearchOptions>(options =>

25
modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs

@ -1,11 +1,15 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Docs.Documents; using Volo.Docs.Documents;
using Volo.Docs.Localization; using Volo.Docs.Localization;
using Volo.Docs.Pages.Documents.Project;
using Volo.Docs.Utils; using Volo.Docs.Utils;
namespace Volo.Docs.Areas.Documents.TagHelpers namespace Volo.Docs.Areas.Documents.TagHelpers
@ -18,6 +22,8 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
private readonly DocsUiOptions _uiOptions; private readonly DocsUiOptions _uiOptions;
private readonly IStringLocalizer<DocsResource> _localizer; private readonly IStringLocalizer<DocsResource> _localizer;
private readonly LinkGenerator _linkGenerator;
private const string LiItemTemplateWithLink = @"<li class='{0}'><span class='plus-icon'><i class='fa fa-{1}'></i></span>{2}{3}</li>"; private const string LiItemTemplateWithLink = @"<li class='{0}'><span class='plus-icon'><i class='fa fa-{1}'></i></span>{2}{3}</li>";
@ -45,10 +51,11 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
[HtmlAttributeName("language")] [HtmlAttributeName("language")]
public string LanguageCode { get; set; } public string LanguageCode { get; set; }
public TreeTagHelper(IOptions<DocsUiOptions> urlOptions, IStringLocalizer<DocsResource> localizer) public TreeTagHelper(IOptions<DocsUiOptions> urlOptions, IStringLocalizer<DocsResource> localizer, LinkGenerator linkGenerator)
{ {
_localizer = localizer; _localizer = localizer;
_uiOptions = urlOptions.Value; _uiOptions = urlOptions.Value;
_linkGenerator = linkGenerator;
} }
public override void Process(TagHelperContext context, TagHelperOutput output) public override void Process(TagHelperContext context, TagHelperOutput output)
@ -172,11 +179,19 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
{ {
return "javascript:;"; return "javascript:;";
} }
var prefix = _uiOptions.RoutePrefix;
var sb = new StringBuilder(); var routeValues = new Dictionary<string, object> {
return sb.Append(prefix).Append(LanguageCode).Append("/").Append(ProjectName).Append("/").Append(Version).Append("/").Append(pathWithoutFileExtension).ToString(); { nameof(IndexModel.LanguageCode), LanguageCode },
{ nameof(IndexModel.Version), Version },
{ nameof(IndexModel.DocumentName), pathWithoutFileExtension }
};
if (!_uiOptions.SingleProjectMode.Enable)
{
routeValues.Add(nameof(IndexModel.ProjectName), ProjectName);
}
return _linkGenerator.GetPathByPage("/Documents/Project/Index", values: routeValues);
} }
private string RemoveFileExtensionFromPath(string path) private string RemoveFileExtensionFromPath(string path)

13
modules/docs/src/Volo.Docs.Web/DocsUiOptions.cs

@ -32,6 +32,8 @@ namespace Volo.Docs
/// Default value: True; /// Default value: True;
/// </summary> /// </summary>
public bool SectionRendering = true; public bool SectionRendering = true;
public SingleProjectModeOptions SingleProjectMode { get; } = new ();
private string GetFormattedRoutePrefix() private string GetFormattedRoutePrefix()
{ {
@ -43,4 +45,15 @@ namespace Volo.Docs
return _routePrefix.EnsureEndsWith('/').EnsureStartsWith('/'); return _routePrefix.EnsureEndsWith('/').EnsureStartsWith('/');
} }
} }
public class SingleProjectModeOptions
{
/// <summary>
/// Determines whether to enable single project mode by removing the project name from the routing.
/// When enabled, only a single project is allowed within the module.
/// </summary>
public bool Enable { get; set; }
public string ProjectName { get; set; }
}
} }

21
modules/docs/src/Volo.Docs.Web/DocsWebModule.cs

@ -61,10 +61,23 @@ namespace Volo.Docs
var routePrefix = docsOptions.RoutePrefix; var routePrefix = docsOptions.RoutePrefix;
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{projectName}"); if (docsOptions.SingleProjectMode.Enable)
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{languageCode}/{projectName}"); {
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{languageCode}/{projectName}/{version}/{*documentName}"); if (routePrefix != "/")
options.Conventions.AddPageRoute("/Documents/Search", routePrefix + "search/{languageCode}/{projectName}/{version}"); {
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix);
}
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{languageCode}");
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{languageCode}/{version}/{*documentName}");
options.Conventions.AddPageRoute("/Documents/Search", routePrefix + "search/{languageCode}/{version}");
}
else
{
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{projectName}");
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{languageCode}/{projectName}");
options.Conventions.AddPageRoute("/Documents/Project/Index", routePrefix + "{languageCode}/{projectName}/{version}/{*documentName}");
options.Conventions.AddPageRoute("/Documents/Search", routePrefix + "search/{languageCode}/{projectName}/{version}");
}
}); });
context.Services.AddAutoMapperObjectMapper<DocsWebModule>(); context.Services.AddAutoMapperObjectMapper<DocsWebModule>();

40
modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs

@ -1,10 +1,12 @@
using System; using System;
using System.Diagnostics; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Docs.Documents; using Volo.Docs.Documents;
using Volo.Docs.HtmlConverting; using Volo.Docs.HtmlConverting;
using Volo.Docs.Pages.Documents.Project;
using Volo.Docs.Projects; using Volo.Docs.Projects;
using Volo.Docs.Utils; using Volo.Docs.Utils;
@ -16,15 +18,17 @@ namespace Volo.Docs.Markdown
private readonly IMarkdownConverter _markdownConverter; private readonly IMarkdownConverter _markdownConverter;
private readonly DocsUiOptions _uiOptions; private readonly DocsUiOptions _uiOptions;
private readonly LinkGenerator _linkGenerator;
public MarkdownDocumentToHtmlConverter(IMarkdownConverter markdownConverter, public MarkdownDocumentToHtmlConverter(IMarkdownConverter markdownConverter,
IOptions<DocsUiOptions> urlOptions) IOptions<DocsUiOptions> urlOptions, LinkGenerator linkGenerator)
{ {
_markdownConverter = markdownConverter; _markdownConverter = markdownConverter;
_linkGenerator = linkGenerator;
_uiOptions = urlOptions.Value; _uiOptions = urlOptions.Value;
} }
private const string MdLinkFormat = "[{0}]({1}{2}/{3}/{4}{5}/{6})"; private const string MdLinkFormat = "[{0}]({1})";
private const string MarkdownLinkRegExp = @"\[(.*?)\]\(((.*?)(\?(.*?))*?)\)"; private const string MarkdownLinkRegExp = @"\[(.*?)\]\(((.*?)(\?(.*?))*?)\)";
private const string AnchorLinkRegExp = @"<a[^>]+href=\""(.*?)\""[^>]*>(.*)?</a>"; private const string AnchorLinkRegExp = @"<a[^>]+href=\""(.*?)\""[^>]*>(.*)?</a>";
@ -117,12 +121,7 @@ namespace Volo.Docs.Markdown
return string.Format( return string.Format(
MdLinkFormat, MdLinkFormat,
displayText, displayText,
_uiOptions.RoutePrefix, GenerateUrl(languageCode, $"{version}{documentLocalDirectoryNormalized}", documentName, projectShortName)
languageCode,
projectShortName,
version,
documentLocalDirectoryNormalized,
documentName
); );
}); });
} }
@ -149,12 +148,7 @@ namespace Volo.Docs.Markdown
return string.Format( return string.Format(
MdLinkFormat, MdLinkFormat,
displayText, displayText,
_uiOptions.RoutePrefix, GenerateUrl(languageCode, $"{version}{documentLocalDirectoryNormalized}", documentName, projectShortName)
languageCode,
projectShortName,
version,
documentLocalDirectoryNormalized,
documentName
); );
}); });
} }
@ -178,5 +172,21 @@ namespace Volo.Docs.Markdown
return documentName.Left(documentName.Length - Type.Length - 1); return documentName.Left(documentName.Length - Type.Length - 1);
} }
private string GenerateUrl(string languageCode, string version, string documentName, string projectShortName)
{
var routeValues = new Dictionary<string, object> {
{ nameof(IndexModel.LanguageCode), languageCode },
{ nameof(IndexModel.Version), version },
{ nameof(IndexModel.DocumentName), documentName }
};
if (!_uiOptions.SingleProjectMode.Enable)
{
routeValues.Add(nameof(IndexModel.ProjectName), projectShortName);
}
return _linkGenerator.GetPathByPage("/Documents/Project/Index", values: routeValues);
}
} }
} }

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

@ -27,13 +27,16 @@ namespace Volo.Docs.Pages.Documents
public virtual async Task<IActionResult> OnGetAsync() public virtual async Task<IActionResult> OnGetAsync()
{ {
DocumentsUrlPrefix = _uiOptions.RoutePrefix; if (_uiOptions.SingleProjectMode.Enable)
{
return RedirectToPage("/Documents/Project/Index");
}
var listResult = await _projectAppService.GetListAsync(); var listResult = await _projectAppService.GetListAsync();
if (listResult.Items.Count == 1) if (listResult.Items.Count == 1)
{ {
return Redirect(DocumentsUrlPrefix + listResult.Items[0].ShortName); return RedirectToPage("/Documents/Project/Index", new { shortName = listResult.Items[0].ShortName });
} }
Projects = listResult.Items; Projects = listResult.Items;

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

@ -480,7 +480,7 @@ else
{ {
model = new ErrorPageModel model = new ErrorPageModel
{ {
RedirectUrl = Model.DocumentsUrlPrefix, RedirectUrl = Url.Page("/Projects/Index"),
ErrorCode = "404", ErrorCode = "404",
ErrorMessage = L.GetString("ProjectNotFound") ErrorMessage = L.GetString("ProjectNotFound")
} }
@ -493,8 +493,7 @@ else
{ {
model = new ErrorPageModel model = new ErrorPageModel
{ {
RedirectUrl = Model.DocumentsUrlPrefix + Model.LanguageCode + "/" + Model.ProjectName + "/" RedirectUrl = Model.BuildDocumentUrl(Model.ProjectName, Model.LanguageCode, Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version, null),
+ (Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version),
ErrorCode = "404", ErrorCode = "404",
ErrorMessage = L.GetString("DocumentNotFound"), ErrorMessage = L.GetString("DocumentNotFound"),
AutoRedirect = !Model.DocumentName.IsNullOrWhiteSpace() AutoRedirect = !Model.DocumentName.IsNullOrWhiteSpace()

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

@ -63,8 +63,6 @@ namespace Volo.Docs.Pages.Documents.Project
public VersionInfoViewModel LatestVersionInfo { get; private set; } public VersionInfoViewModel LatestVersionInfo { get; private set; }
public string DocumentsUrlPrefix { get; set; }
public bool ShowProjectsCombobox { get; set; } public bool ShowProjectsCombobox { get; set; }
public bool ShowProjectsComboboxLabel { get; set; } public bool ShowProjectsComboboxLabel { get; set; }
@ -149,8 +147,7 @@ namespace Volo.Docs.Pages.Documents.Project
private async Task<IActionResult> SetPageAsync() private async Task<IActionResult> SetPageAsync()
{ {
DocumentsUrlPrefix = _uiOptions.RoutePrefix; ShowProjectsCombobox = _uiOptions.ShowProjectsCombobox && !_uiOptions.SingleProjectMode.Enable;
ShowProjectsCombobox = _uiOptions.ShowProjectsCombobox;
ShowProjectsComboboxLabel = ShowProjectsCombobox && _uiOptions.ShowProjectsComboboxLabel; ShowProjectsComboboxLabel = ShowProjectsCombobox && _uiOptions.ShowProjectsComboboxLabel;
FullSearchEnabled = await _documentAppService.FullSearchEnabledAsync(); FullSearchEnabled = await _documentAppService.FullSearchEnabledAsync();
@ -217,6 +214,29 @@ namespace Volo.Docs.Pages.Documents.Project
private async Task SetProjectAsync() private async Task SetProjectAsync()
{ {
if (!_uiOptions.SingleProjectMode.Enable)
{
Project = await _projectAppService.GetAsync(ProjectName);
return;
}
var singleProjectName = _uiOptions.SingleProjectMode.ProjectName;
if (!singleProjectName.IsNullOrWhiteSpace())
{
Project = await _projectAppService.GetAsync(singleProjectName);
ProjectName = singleProjectName;
return;
}
var listResult = await _projectAppService.GetListAsync();
if (listResult.Items.Count == 1)
{
Project = listResult.Items[0];
ProjectName = Project.ShortName;
return;
}
ProjectName = singleProjectName;
Project = await _projectAppService.GetAsync(ProjectName); Project = await _projectAppService.GetAsync(ProjectName);
} }
@ -233,61 +253,63 @@ namespace Volo.Docs.Pages.Documents.Project
private bool CheckLanguage() private bool CheckLanguage()
{ {
return LanguageConfig.Languages.Any(l => l.Code == LanguageCode); return LanguageConfig.Languages.Any(l => l.Code.Equals(LanguageCode, StringComparison.OrdinalIgnoreCase));
} }
private IActionResult ReloadPageWithCulture() private IActionResult ReloadPageWithCulture()
{ {
var sb = new StringBuilder(); return Redirect(
new StringBuilder()
var returnUrl = sb.Append(DocumentsUrlPrefix).Append(LanguageCode).Append("/").Append(ProjectName) .Append("/Abp/Languages/Switch?culture=")
.Append("/").Append(LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version).Append("/").Append(DocumentName).ToString(); .Append(LanguageCode).Append("&uiCulture=")
.Append(LanguageCode).Append("&returnUrl=").Append(BuildDocumentUrl(ProjectName, LanguageCode,
sb.Clear(); LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version, DocumentName)).ToString());
return Redirect(sb.Append("/Abp/Languages/Switch?culture=").Append(LanguageCode).Append("&uiCulture=")
.Append(LanguageCode).Append("&returnUrl=").Append(returnUrl).ToString());
} }
public string GetFullUrlOfTheLatestDocument() public string GetFullUrlOfTheLatestDocument()
{ {
return Request.Scheme + "://" + Request.Host.Value + Request.PathBase + return Request.Scheme + Uri.SchemeDelimiter + Request.Host.Value + Request.PathBase + BuildDocumentUrl(ProjectName, LanguageCode, DocsAppConsts.Latest, DocumentName);
DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/" +
DocsAppConsts.Latest + "/" + DocumentName;
} }
public string CreateDocumentLink(string documentName) public string CreateDocumentLink(string documentName)
{ {
return new StringBuilder() return BuildDocumentUrl(ProjectName, LanguageCode, LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version, documentName);
.Append(DocumentsUrlPrefix) }
.Append(LanguageCode)
.Append('/') public string BuildDocumentUrl(string projectName, string languageCode, string version, string documentName)
.Append(ProjectName) {
.Append('/') var routeValues = new Dictionary<string, object> {
.Append(LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version) { nameof(LanguageCode), languageCode },
.Append('/') { nameof(Version), version },
.Append(documentName) { nameof(DocumentName), documentName }
.ToString(); };
if (!_uiOptions.SingleProjectMode.Enable)
{
routeValues.Add(nameof(ProjectName), projectName);
}
return Url.Page("/Documents/Project/Index", routeValues);
} }
private IActionResult RedirectToDefaultLanguage() private IActionResult RedirectToDefaultLanguage()
{ {
return RedirectToPage(new { return RedirectToPage(BuildDocumentUrl(
projectName = ProjectName, projectName : ProjectName,
version = (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version), version : (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
languageCode = DefaultLanguageCode, languageCode : DefaultLanguageCode,
documentName = DocumentName documentName : DocumentName
}); ));
} }
private IActionResult RedirectToDefaultDocument() private IActionResult RedirectToDefaultDocument()
{ {
return RedirectToPage(new { return RedirectToPage(BuildDocumentUrl (
projectName = ProjectName, projectName : ProjectName,
version = (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version), version : (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
documentName = "", documentName : "",
languageCode = DefaultLanguageCode languageCode : DefaultLanguageCode
}); ));
} }
private async Task SetProjectsAsync() private async Task SetProjectsAsync()
@ -308,15 +330,7 @@ namespace Volo.Docs.Pages.Documents.Project
{ {
return null; return null;
} }
return BuildDocumentUrl(project.ShortName, LanguageCode, Version, null);
return new StringBuilder()
.Append(DocumentsUrlPrefix)
.Append(LanguageCode)
.Append('/')
.Append(project.ShortName)
.Append('/')
.Append(DocsAppConsts.Latest)
.ToString();
} }
private async Task SetVersionAsync() private async Task SetVersionAsync()
@ -458,16 +472,8 @@ namespace Volo.Docs.Pages.Documents.Project
{ {
version = DocsAppConsts.Latest; version = DocsAppConsts.Latest;
} }
var linkStringBuilder = new StringBuilder(); return BuildDocumentUrl(ProjectName, LanguageCode, version, documentName);
linkStringBuilder.Append(DocumentsUrlPrefix).Append(LanguageCode).Append("/").Append(ProjectName).Append("/").Append(version);
if (documentName != null)
{
linkStringBuilder.Append("/").Append(DocumentName);
}
return linkStringBuilder.ToString();
} }
public string GetSpecificVersionOrLatest() public string GetSpecificVersionOrLatest()
@ -513,19 +519,15 @@ namespace Volo.Docs.Pages.Documents.Project
{ {
LanguageSelectListItems = new List<SelectListItem>(); LanguageSelectListItems = new List<SelectListItem>();
var sb = new StringBuilder();
foreach (var language in LanguageConfig.Languages) foreach (var language in LanguageConfig.Languages)
{ {
LanguageSelectListItems.Add( LanguageSelectListItems.Add(
new SelectListItem( new SelectListItem(
language.DisplayName, language.DisplayName,
sb.Append(DocumentsUrlPrefix).Append(language.Code).Append("/").Append(Project.ShortName).Append("/").Append(LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version).Append("/").Append(DocumentName).ToString(), BuildDocumentUrl(ProjectName, language.Code, LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version, DocumentName),
language.Code == LanguageCode language.Code.Equals(LanguageCode, StringComparison.OrdinalIgnoreCase)
) )
); );
sb.Clear();
} }
} }
@ -578,14 +580,7 @@ namespace Volo.Docs.Pages.Documents.Project
{ {
foreach (var parameter in partialTemplates.Parameters) foreach (var parameter in partialTemplates.Parameters)
{ {
if (!UserPreferences.ContainsKey(parameter.Key)) UserPreferences[parameter.Key] = parameter.Value;
{
UserPreferences.Add(parameter.Key, parameter.Value);
}
else
{
UserPreferences[parameter.Key] = parameter.Value;
}
} }
} }

Loading…
Cancel
Save