@@ -537,6 +549,7 @@
private string _defaultalias;
private string _rendermode = RenderModes.Interactive;
+ private string _enhancednavigation = "True";
private string _runtime = Runtimes.Server;
private string _prerender = "True";
private string _hybrid = "False";
@@ -660,6 +673,7 @@
// hosting model
_rendermode = site.RenderMode;
+ _enhancednavigation = site.EnhancedNavigation.ToString();
_runtime = site.Runtime;
_prerender = site.Prerender.ToString();
_hybrid = site.Hybrid.ToString();
@@ -807,13 +821,11 @@
// hosting model
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
- if (site.RenderMode != _rendermode || site.Runtime != _runtime || site.Prerender != bool.Parse(_prerender) || site.Hybrid != bool.Parse(_hybrid))
- {
- site.RenderMode = _rendermode;
- site.Runtime = _runtime;
- site.Prerender = bool.Parse(_prerender);
- site.Hybrid = bool.Parse(_hybrid);
- }
+ site.RenderMode = _rendermode;
+ site.EnhancedNavigation = bool.Parse(_enhancednavigation);
+ site.Runtime = _runtime;
+ site.Prerender = bool.Parse(_prerender);
+ site.Hybrid = bool.Parse(_hybrid);
}
site = await SiteService.UpdateSiteAsync(site);
diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs
index 00dc2c61..264930c4 100644
--- a/Oqtane.Client/Modules/ModuleBase.cs
+++ b/Oqtane.Client/Modules/ModuleBase.cs
@@ -460,6 +460,11 @@ namespace Oqtane.Modules
public string ReplaceTokens(string content, object obj)
{
+ // check for null or empty content
+ if (string.IsNullOrEmpty(content))
+ {
+ return content;
+ }
// Using StringBuilder avoids the performance penalty of repeated string allocations
// that occur with string.Replace or string concatenation inside loops.
var sb = new StringBuilder();
diff --git a/Oqtane.Package/Oqtane.Server.nuspec b/Oqtane.Package/Oqtane.Server.nuspec
index 789f9215..6e4219a3 100644
--- a/Oqtane.Package/Oqtane.Server.nuspec
+++ b/Oqtane.Package/Oqtane.Server.nuspec
@@ -31,7 +31,7 @@
-
+
diff --git a/Oqtane.Server/Components/App.razor b/Oqtane.Server/Components/App.razor
index 333ed42f..0082e669 100644
--- a/Oqtane.Server/Components/App.razor
+++ b/Oqtane.Server/Components/App.razor
@@ -60,7 +60,7 @@
}
@((MarkupString)_headResources)
-
+
@if (string.IsNullOrEmpty(_message))
{
@if (_renderMode == RenderModes.Static)
@@ -97,6 +97,7 @@
private string _renderMode = RenderModes.Interactive;
private string _runtime = Runtimes.Server;
private bool _prerender = true;
+ private bool _enhancedNavigation = true;
private string _fingerprint = "";
private int _visitorId = -1;
private string _antiForgeryToken = "";
@@ -141,6 +142,7 @@
_renderMode = site.RenderMode;
_runtime = site.Runtime;
_prerender = site.Prerender;
+ _enhancedNavigation = site.EnhancedNavigation;
_fingerprint = site.Fingerprint;
var cookieConsentSettings = SettingService.GetSetting(site.Settings, "CookieConsent", string.Empty);
diff --git a/Oqtane.Server/Controllers/PageController.cs b/Oqtane.Server/Controllers/PageController.cs
index cb7b8ee5..69bed0bc 100644
--- a/Oqtane.Server/Controllers/PageController.cs
+++ b/Oqtane.Server/Controllers/PageController.cs
@@ -265,7 +265,19 @@ namespace Oqtane.Controllers
_syncManager.AddSyncEvent(_alias, EntityNames.Site, page.SiteId, SyncEventActions.Refresh);
// set user personalized page path
- _settings.AddSetting(new Setting { EntityName = EntityNames.User, EntityId = page.UserId.Value, SettingName = $"PersonalizedPagePath:{page.SiteId}:{parent.PageId}", SettingValue = path, IsPrivate = false });
+ var settingName = $"PersonalizedPagePath:{page.SiteId}:{parent.PageId}";
+ var pathSetting = _settings.GetSetting(EntityNames.User, page.UserId.Value, settingName);
+ if(pathSetting == null)
+ {
+ pathSetting = new Setting { EntityName = EntityNames.User, EntityId = page.UserId.Value, SettingName = settingName, SettingValue = path, IsPrivate = false };
+ _settings.AddSetting(pathSetting);
+ }
+ else
+ {
+ pathSetting.SettingValue = path;
+ _settings.UpdateSetting(pathSetting);
+ }
+
_syncManager.AddSyncEvent(_alias, EntityNames.User, user.UserId, SyncEventActions.Update);
}
}
diff --git a/Oqtane.Server/Managers/UserManager.cs b/Oqtane.Server/Managers/UserManager.cs
index 4e95d5f6..e6f2661d 100644
--- a/Oqtane.Server/Managers/UserManager.cs
+++ b/Oqtane.Server/Managers/UserManager.cs
@@ -279,7 +279,7 @@ namespace Oqtane.Managers
await _identityUserManager.UpdateAsync(identityuser); // security stamp not updated
}
- if (bool.Parse(_settings.GetSettingValue(EntityNames.Site, alias.SiteId, "LoginOptions:RequireConfirmedEmail", "true")))
+ if (bool.Parse(_settings.GetSettingValue(EntityNames.Site, alias.SiteId, "LoginOptions:RequireConfirmedEmail", "true")) && !user.IsDeleted)
{
if (user.EmailConfirmed)
{
diff --git a/Oqtane.Server/Migrations/Tenant/10000101_AddSiteEnhancedNavigation.cs b/Oqtane.Server/Migrations/Tenant/10000101_AddSiteEnhancedNavigation.cs
new file mode 100644
index 00000000..b119c2ee
--- /dev/null
+++ b/Oqtane.Server/Migrations/Tenant/10000101_AddSiteEnhancedNavigation.cs
@@ -0,0 +1,29 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Databases.Interfaces;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations.Tenant
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.10.00.01.01")]
+ public class AddSiteEnhancedNavigation : MultiDatabaseMigration
+ {
+ public AddSiteEnhancedNavigation(IDatabase database) : base(database)
+ {
+ }
+
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
+ siteEntityBuilder.AddBooleanColumn("EnhancedNavigation", true);
+ siteEntityBuilder.UpdateData("EnhancedNavigation", true);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ // not implemented
+ }
+ }
+}
diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj
index 1236dde0..d14efd87 100644
--- a/Oqtane.Server/Oqtane.Server.csproj
+++ b/Oqtane.Server/Oqtane.Server.csproj
@@ -43,7 +43,7 @@
-
+
diff --git a/Oqtane.Shared/Models/Site.cs b/Oqtane.Shared/Models/Site.cs
index e674be2e..a00fa5b1 100644
--- a/Oqtane.Shared/Models/Site.cs
+++ b/Oqtane.Shared/Models/Site.cs
@@ -115,6 +115,11 @@ namespace Oqtane.Models
///
public bool Hybrid { get; set; }
+ ///
+ /// Indicates if enhanced navigation should be used with static rendering
+ ///
+ public bool EnhancedNavigation { get; set; }
+
///
/// Keeps track of site configuration changes and is used by the ISiteMigration interface
///
@@ -222,6 +227,7 @@ namespace Oqtane.Models
Runtime = Runtime,
Prerender = Prerender,
Hybrid = Hybrid,
+ EnhancedNavigation = EnhancedNavigation,
Version = Version,
HomePageId = HomePageId,
HeadContent = HeadContent,