Module Router Enhancement
Allows for PageVariables through the URL
This commit is contained in:
@ -14,10 +14,11 @@ 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 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; }
|
||||||
public DateTime LastSyncDate { get; set; }
|
public DateTime LastSyncDate { get; set; }
|
||||||
public Runtime Runtime { get; set; }
|
public Runtime Runtime { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -75,6 +75,7 @@
|
|||||||
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 = "";
|
||||||
var editmode = false;
|
var editmode = false;
|
||||||
@ -179,23 +180,33 @@
|
|||||||
// extract admin route elements from path
|
// extract admin route elements from path
|
||||||
var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
int result;
|
int result;
|
||||||
// check if path has moduleid and action specification ie. pagename/moduleid/action/
|
|
||||||
if (segments.Length >= 2 && int.TryParse(segments[segments.Length - 2], out result))
|
int modIdPos = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < segments.Length; i++)
|
||||||
{
|
{
|
||||||
action = segments[segments.Length - 1];
|
if (segments[i] == Constants.ModuleSegment)
|
||||||
moduleid = result;
|
|
||||||
path = path.Replace(moduleid.ToString() + "/" + action + "/", "");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// check if path has moduleid specification ie. pagename/moduleid/
|
|
||||||
if (segments.Length >= 1 && int.TryParse(segments[segments.Length - 1], out result))
|
|
||||||
{
|
{
|
||||||
moduleid = result;
|
modIdPos = i + 1;
|
||||||
path = path.Replace(moduleid.ToString() + "/", "");
|
}
|
||||||
|
|
||||||
|
if (i > modIdPos && modIdPos != 0)
|
||||||
|
{
|
||||||
|
action += segments[i] + "/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if path has moduleid and action specification ie. pagename/moduleid/action/
|
||||||
|
if (modIdPos > 0)
|
||||||
|
{
|
||||||
|
int.TryParse(segments[modIdPos], out result);
|
||||||
|
moduleid = result;
|
||||||
|
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + action, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.EndsWith("/")) action = action.Substring(0, action.Length - 1);
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
@ -246,7 +257,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) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
|
(page, modules, pageVariables) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -263,6 +274,7 @@
|
|||||||
Modules = modules,
|
Modules = modules,
|
||||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||||
QueryString = querystring,
|
QueryString = querystring,
|
||||||
|
PageVariables = pageVariables,
|
||||||
ModuleId = moduleid,
|
ModuleId = moduleid,
|
||||||
Action = action,
|
Action = action,
|
||||||
EditMode = editmode,
|
EditMode = editmode,
|
||||||
@ -314,9 +326,12 @@
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, string> ParseQueryString(string query)
|
private Dictionary<string, string>
|
||||||
|
ParseQueryString(string query)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> querystring = new Dictionary<string, string>();
|
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 "?"
|
||||||
@ -339,7 +354,8 @@
|
|||||||
return querystring;
|
return querystring;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Page> ProcessPage(Page page, Site site, User user)
|
private async Task<Page>
|
||||||
|
ProcessPage(Page page, Site site, User user)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -355,8 +371,10 @@
|
|||||||
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);
|
||||||
@ -393,9 +411,12 @@
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Page Page, List<Module> Modules) ProcessModules(Page page, List<Module> modules, int moduleid, string action, string defaultcontainertype)
|
private (Page Page, List<Module>
|
||||||
|
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)
|
||||||
@ -410,17 +431,52 @@
|
|||||||
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 != "")
|
||||||
{
|
{
|
||||||
foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
var controlTypeRoutes = module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
foreach (string route in controlTypeRoutes)
|
||||||
{
|
{
|
||||||
if (route.StartsWith(action + "="))
|
var pageAction = route.Split('=')[0];
|
||||||
|
|
||||||
|
var routes = pageAction.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
var newRoute = "";
|
||||||
|
if (pages.Length == routes.Length)
|
||||||
{
|
{
|
||||||
typename = route.Replace(action + "=", "");
|
for (int i = 0; i < pages.Length; i++)
|
||||||
|
{
|
||||||
|
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);
|
||||||
@ -489,10 +545,13 @@
|
|||||||
module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1;
|
module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (page, modules);
|
return (page, modules, pageVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Resource> ManagePageResources(List<Resource> pageresources, List<Resource> resources)
|
private List<Resource>
|
||||||
|
ManagePageResources(List<Resource>
|
||||||
|
pageresources, List<Resource>
|
||||||
|
resources)
|
||||||
{
|
{
|
||||||
if (resources != null)
|
if (resources != null)
|
||||||
{
|
{
|
||||||
@ -509,7 +568,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;
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": ""
|
"DefaultConnection": "Data Source=(LocalDb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Oqtane.mdf;Initial Catalog=Oqtane;Integrated Security=SSPI;"
|
||||||
},
|
},
|
||||||
"Runtime": "Server",
|
"Runtime": "Server",
|
||||||
"Installation": {
|
"Installation": {
|
||||||
|
@ -19,6 +19,7 @@ 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";
|
||||||
|
|
||||||
// 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" };
|
||||||
@ -46,6 +47,7 @@ namespace Oqtane.Shared
|
|||||||
public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png";
|
public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png";
|
||||||
public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg";
|
public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg";
|
||||||
public const string ReservedDevices = "CON,NUL,PRN,COM0,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT0,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$";
|
public const string ReservedDevices = "CON,NUL,PRN,COM0,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT0,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$";
|
||||||
|
|
||||||
public static readonly char[] InvalidFileNameChars =
|
public static readonly char[] InvalidFileNameChars =
|
||||||
{
|
{
|
||||||
'\"', '<', '>', '|', '\0', (Char) 1, (Char) 2, (Char) 3, (Char) 4, (Char) 5, (Char) 6, (Char) 7, (Char) 8,
|
'\"', '<', '>', '|', '\0', (Char) 1, (Char) 2, (Char) 3, (Char) 4, (Char) 5, (Char) 6, (Char) 7, (Char) 8,
|
||||||
@ -55,4 +57,4 @@ namespace Oqtane.Shared
|
|||||||
};
|
};
|
||||||
public static readonly string[] InvalidFileNameEndingChars = { ".", " " };
|
public static readonly string[] InvalidFileNameEndingChars = { ".", " " };
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -39,7 +39,7 @@ namespace Oqtane.Shared
|
|||||||
{
|
{
|
||||||
if (moduleid != -1)
|
if (moduleid != -1)
|
||||||
{
|
{
|
||||||
path += $"/{moduleid}";
|
path += $"/{Constants.ModuleSegment}/{moduleid}";
|
||||||
if (!string.IsNullOrEmpty(action))
|
if (!string.IsNullOrEmpty(action))
|
||||||
{
|
{
|
||||||
path += $"/{action}";
|
path += $"/{action}";
|
||||||
@ -136,6 +136,7 @@ namespace Oqtane.Shared
|
|||||||
stringBuilder.Append(RemapInternationalCharToAscii(c));
|
stringBuilder.Append(RemapInternationalCharToAscii(c));
|
||||||
prevdash = false;
|
prevdash = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UnicodeCategory.SpaceSeparator:
|
case UnicodeCategory.SpaceSeparator:
|
||||||
case UnicodeCategory.ConnectorPunctuation:
|
case UnicodeCategory.ConnectorPunctuation:
|
||||||
case UnicodeCategory.DashPunctuation:
|
case UnicodeCategory.DashPunctuation:
|
||||||
@ -250,7 +251,7 @@ namespace Oqtane.Shared
|
|||||||
|
|
||||||
public static string PathCombine(params string[] segments)
|
public static string PathCombine(params string[] segments)
|
||||||
{
|
{
|
||||||
var separators = new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar};
|
var separators = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
|
||||||
|
|
||||||
for (int i = 1; i < segments.Length; i++)
|
for (int i = 1; i < segments.Length; i++)
|
||||||
{
|
{
|
||||||
@ -284,7 +285,6 @@ namespace Oqtane.Shared
|
|||||||
!Constants.ReservedDevices.Split(',').Contains(name.ToUpper().Split('.')[0]));
|
!Constants.ReservedDevices.Split(',').Contains(name.ToUpper().Split('.')[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static bool TryGetQueryValue(
|
public static bool TryGetQueryValue(
|
||||||
this Uri uri,
|
this Uri uri,
|
||||||
string key,
|
string key,
|
||||||
@ -304,7 +304,7 @@ namespace Oqtane.Shared
|
|||||||
{
|
{
|
||||||
value = defaultValue;
|
value = defaultValue;
|
||||||
string s;
|
string s;
|
||||||
return uri.TryGetQueryValue(key, out s, (string) null) && int.TryParse(s, out value);
|
return uri.TryGetQueryValue(key, out s, (string)null) && int.TryParse(s, out value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, string> ParseQueryString(string query)
|
public static Dictionary<string, string> ParseQueryString(string query)
|
||||||
@ -314,7 +314,7 @@ namespace Oqtane.Shared
|
|||||||
{
|
{
|
||||||
query = query.Substring(1);
|
query = query.Substring(1);
|
||||||
string str = query;
|
string str = query;
|
||||||
char[] separator = new char[1] {'&'};
|
char[] separator = new char[1] { '&' };
|
||||||
foreach (string key in str.Split(separator, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string key in str.Split(separator, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
if (key != "")
|
if (key != "")
|
||||||
@ -333,4 +333,4 @@ namespace Oqtane.Shared
|
|||||||
return dictionary;
|
return dictionary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user