Url parameters working on any page, plus queries and anchors

This commit is contained in:
Michael Atwood 2020-06-30 03:41:35 -07:00
parent fdc39d57fb
commit c5037e7084
5 changed files with 100 additions and 77 deletions

View File

@ -14,7 +14,8 @@ namespace Oqtane.UI
public List<Module> Modules { get; set; } public List<Module> Modules { get; set; }
public Uri Uri { get; set; } public Uri Uri { get; set; }
public Dictionary<string, string> QueryString { get; set; } public Dictionary<string, string> QueryString { get; set; }
public Dictionary<string, string> PageVariables { get; set; } public string UrlParameters { get; set; }
public string Anchor { get; set; }
public int ModuleId { get; set; } public int ModuleId { get; set; }
public string Action { get; set; } public string Action { get; set; }
public bool EditMode { get; set; } public bool EditMode { get; set; }

View File

@ -75,9 +75,10 @@
Page page; Page page;
User user = null; User user = null;
List<Module> modules; List<Module> modules;
Dictionary<string, string> pageVariables = new Dictionary<string, string>();
var moduleid = -1; var moduleid = -1;
var action = ""; var action = string.Empty;
var urlparameters = string.Empty;
var anchor = string.Empty;
var editmode = false; var editmode = false;
var reload = Reload.None; var reload = Reload.None;
var lastsyncdate = DateTime.UtcNow; var lastsyncdate = DateTime.UtcNow;
@ -88,6 +89,12 @@
// get path // get path
var path = uri.LocalPath.Substring(1); var path = uri.LocalPath.Substring(1);
//set anchor
if (uri.Fragment.StartsWith('#'))
{
anchor = uri.Fragment.Remove(0, 1);
}
// parse querystring // parse querystring
var querystring = ParseQueryString(uri.Query); var querystring = ParseQueryString(uri.Query);
@ -182,18 +189,29 @@
int result; int result;
int modIdPos = 0; int modIdPos = 0;
int actionPos = 0;
int ulrParametersPos = 0;
for (int i = 0; i < segments.Length; i++) for (int i = 0; i < segments.Length; i++)
{ {
if (segments[i] == Constants.ModuleSegment)
if (segments[i] == Constants.UrlParametersDelimiter)
{ {
modIdPos = i + 1; ulrParametersPos = i + 1;
} }
if (i > modIdPos && modIdPos != 0) if (i >= ulrParametersPos && ulrParametersPos != 0)
{ {
action += segments[i] + "/"; urlparameters += "/" + segments[i];
} }
if (segments[i] == Constants.ModuleDelimiter)
{
modIdPos = i + 1;
actionPos = modIdPos + 1;
action = segments[actionPos];
}
} }
// check if path has moduleid and action specification ie. pagename/moduleid/action/ // check if path has moduleid and action specification ie. pagename/moduleid/action/
@ -201,11 +219,14 @@
{ {
int.TryParse(segments[modIdPos], out result); int.TryParse(segments[modIdPos], out result);
moduleid = result; moduleid = result;
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + action, ""); path = path.Replace("/" + segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + segments[actionPos], "");
} }
if (action.EndsWith("/")) action = action.Substring(0, action.Length - 1); if (ulrParametersPos > 0)
{
path = path.Replace("/" + segments[ulrParametersPos - 1] + urlparameters, "");
}
// remove trailing slash so it can be used as a key for Pages // remove trailing slash so it can be used as a key for Pages
if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1);
@ -257,7 +278,7 @@
if (PageState == null || reload >= Reload.Page) if (PageState == null || reload >= Reload.Page)
{ {
modules = await ModuleService.GetModulesAsync(site.SiteId); modules = await ModuleService.GetModulesAsync(site.SiteId);
(page, modules, pageVariables) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType); (page, modules) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
} }
else else
{ {
@ -274,7 +295,8 @@
Modules = modules, Modules = modules,
Uri = new Uri(_absoluteUri, UriKind.Absolute), Uri = new Uri(_absoluteUri, UriKind.Absolute),
QueryString = querystring, QueryString = querystring,
PageVariables = pageVariables, UrlParameters = urlparameters,
Anchor = anchor,
ModuleId = moduleid, ModuleId = moduleid,
Action = action, Action = action,
EditMode = editmode, EditMode = editmode,
@ -326,12 +348,9 @@
return Task.CompletedTask; return Task.CompletedTask;
} }
private Dictionary<string, string> private Dictionary<string, string> ParseQueryString(string query)
ParseQueryString(string query)
{ {
Dictionary<string, string> Dictionary<string, string> querystring = new Dictionary<string, string>();
querystring = new Dictionary<string, string>
();
if (!string.IsNullOrEmpty(query)) if (!string.IsNullOrEmpty(query))
{ {
query = query.Substring(1); // ignore "?" query = query.Substring(1); // ignore "?"
@ -354,8 +373,7 @@
return querystring; return querystring;
} }
private async Task<Page> private async Task<Page> ProcessPage(Page page, Site site, User user)
ProcessPage(Page page, Site site, User user)
{ {
try try
{ {
@ -371,10 +389,8 @@
page.LayoutType = site.DefaultLayoutType; page.LayoutType = site.DefaultLayoutType;
} }
page.Panes = new List<string> page.Panes = new List<string>();
(); page.Resources = new List<Resource>();
page.Resources = new List<Resource>
();
string panes = ""; string panes = "";
Type themetype = Type.GetType(page.ThemeType); Type themetype = Type.GetType(page.ThemeType);
@ -411,12 +427,9 @@
return page; return page;
} }
private (Page Page, List<Module> private (Page Page, List<Module> Modules) ProcessModules(Page page, List<Module> modules, int moduleid, string action, string defaultcontainertype)
Modules, Dictionary<string, string> PageVariables) ProcessModules(Page page, List<Module>
modules, int moduleid, string action, string defaultcontainertype)
{ {
var paneindex = new Dictionary<string, int>(); var paneindex = new Dictionary<string, int>();
var pageVariables = new Dictionary<string, string>();
foreach (Module module in modules) foreach (Module module in modules)
{ {
if (module.PageId == page.PageId || module.ModuleId == moduleid) if (module.PageId == page.PageId || module.ModuleId == moduleid)
@ -431,52 +444,17 @@
typename = Constants.ErrorModule; typename = Constants.ErrorModule;
} }
var pages = action.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (module.ModuleId == moduleid && action != "") if (module.ModuleId == moduleid && action != "")
{ {
// check if the module defines custom routes // check if the module defines custom routes
if (module.ModuleDefinition.ControlTypeRoutes != "") if (module.ModuleDefinition.ControlTypeRoutes != "")
{ {
var controlTypeRoutes = module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
foreach (string route in controlTypeRoutes)
{ {
var pageAction = route.Split('=')[0]; if (route.StartsWith(action + "="))
var routes = pageAction.Split('/', StringSplitOptions.RemoveEmptyEntries);
var newRoute = "";
if (pages.Length == routes.Length)
{ {
for (int i = 0; i < pages.Length; i++) typename = route.Replace(action + "=", "");
{
if (pages.Length > i)
{
if (routes[i] == pages[i])
{
newRoute += pages[i] + "/";
}
else if (routes[i].StartsWith("[") && routes[i].EndsWith("]"))
{
newRoute += pages[i] + "/";
var key = routes[i].Replace("[", "");
key = key.Replace("]", "");
pageVariables.TryAdd(key, pages[i]);
}
else
{
i = pages.Length;
newRoute = "";
}
}
}
if (newRoute != "")
{
typename = route.Replace(pageAction + "=", "");
}
} }
} }
} }
module.ModuleType = typename.Replace(Constants.ActionToken, action); module.ModuleType = typename.Replace(Constants.ActionToken, action);
@ -545,13 +523,10 @@
module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1; module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1;
} }
return (page, modules, pageVariables); return (page, modules);
} }
private List<Resource> private List<Resource> ManagePageResources(List<Resource> pageresources, List<Resource> resources)
ManagePageResources(List<Resource>
pageresources, List<Resource>
resources)
{ {
if (resources != null) if (resources != null)
{ {
@ -568,7 +543,7 @@
} }
private Runtime GetRuntime() private Runtime GetRuntime()
=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))
? Runtime.WebAssembly ? Runtime.WebAssembly
: Runtime.Server; : Runtime.Server;
} }

View File

@ -1,6 +1,6 @@
{ {
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Data Source=(LocalDb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Oqtane.mdf;Initial Catalog=Oqtane;Integrated Security=SSPI;" "DefaultConnection": ""
}, },
"Runtime": "Server", "Runtime": "Server",
"Installation": { "Installation": {

View File

@ -19,7 +19,8 @@ namespace Oqtane.Shared
public const string ActionToken = "{Action}"; public const string ActionToken = "{Action}";
public const string DefaultAction = "Index"; public const string DefaultAction = "Index";
public const string AdminPane = "Admin"; public const string AdminPane = "Admin";
public const string ModuleSegment = "module"; public const string ModuleDelimiter = "*";
public const string UrlParametersDelimiter = "!";
// Default Module Actions are reserved and should not be used by modules // Default Module Actions are reserved and should not be used by modules
public static readonly string[] DefaultModuleActions = new[] { "Settings", "Import", "Export" }; public static readonly string[] DefaultModuleActions = new[] { "Settings", "Import", "Export" };

View File

@ -20,8 +20,53 @@ namespace Oqtane.Shared
return $"{type.Namespace}, {assemblyName}"; return $"{type.Namespace}, {assemblyName}";
} }
public static (string UrlParameters, string Querystring, string Anchor) ParseParameters(string parameters)
{
// /urlparameters /urlparameters?Id=1 /urlparameters#5 /urlparameters?Id=1#5 /urlparameters?reload#5
// Id=1 Id=1#5 reload#5 reload
// #5
var urlparameters = string.Empty;
var querystring = string.Empty;
var anchor = string.Empty;
if (parameters.Contains('#'))
{
anchor = parameters.Split('#').Last();
parameters = parameters.Replace("#" + anchor, "");
}
if (parameters.Contains('?'))
{
urlparameters = parameters.Split('?').First();
querystring = parameters.Replace(urlparameters + "?", "");
}
else if (parameters.Contains('/'))
{
urlparameters = parameters;
}
else
{
querystring = parameters;
}
return (urlparameters, querystring, anchor);
}
public static string NavigateUrl(string alias, string path, string parameters) public static string NavigateUrl(string alias, string path, string parameters)
{ {
string urlparameters;
string querystring;
string anchor;
(urlparameters, querystring, anchor) = ParseParameters(parameters);
if (!string.IsNullOrEmpty(urlparameters))
{
if (urlparameters.StartsWith("/")) urlparameters = urlparameters.Remove(0, 1);
path += $"/{Constants.UrlParametersDelimiter}/{urlparameters}";
}
var uriBuilder = new UriBuilder var uriBuilder = new UriBuilder
{ {
Path = !string.IsNullOrEmpty(alias) Path = !string.IsNullOrEmpty(alias)
@ -29,17 +74,18 @@ namespace Oqtane.Shared
? $"{alias}/{path}" ? $"{alias}/{path}"
: $"{alias}" : $"{alias}"
: $"{path}", : $"{path}",
Query = parameters Query = querystring,
}; };
return uriBuilder.Uri.PathAndQuery; var navigateUrl = uriBuilder.Uri.PathAndQuery + "#" + anchor;
return navigateUrl;
} }
public static string EditUrl(string alias, string path, int moduleid, string action, string parameters) public static string EditUrl(string alias, string path, int moduleid, string action, string parameters)
{ {
if (moduleid != -1) if (moduleid != -1)
{ {
path += $"/{Constants.ModuleSegment}/{moduleid}"; path += $"/{Constants.ModuleDelimiter}/{moduleid}";
if (!string.IsNullOrEmpty(action)) if (!string.IsNullOrEmpty(action))
{ {
path += $"/{action}"; path += $"/{action}";