Merge remote-tracking branch 'oqtane/dev' into dev

This commit is contained in:
Leigh Pointer 2023-05-31 08:25:26 +02:00
commit 55cfbb721b
13 changed files with 366 additions and 165 deletions

View File

@ -52,6 +52,12 @@
<input id="sitemap" class="form-control" @bind="@_sitemap" required disabled /> <input id="sitemap" class="form-control" @bind="@_sitemap" required disabled />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="version" HelpText="The site version (for site content migrations)" ResourceKey="Version">Version: </Label>
<div class="col-sm-9">
<input id="version" class="form-control" @bind="@_version" required disabled />
</div>
</div>
</div> </div>
<br /> <br />
<Section Name="Appearance" ResourceKey="Appearance"> <Section Name="Appearance" ResourceKey="Appearance">
@ -345,6 +351,7 @@
private string _homepageid = "-"; private string _homepageid = "-";
private string _isdeleted; private string _isdeleted;
private string _sitemap = ""; private string _sitemap = "";
private string _version = "";
private int _logofileid = -1; private int _logofileid = -1;
private FileManager _logofilemanager; private FileManager _logofilemanager;
private int _faviconfileid = -1; private int _faviconfileid = -1;
@ -402,6 +409,7 @@
} }
_isdeleted = site.IsDeleted.ToString(); _isdeleted = site.IsDeleted.ToString();
_sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml"; _sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml";
_version = site.Version;
// appearance // appearance
if (site.LogoFileId != null) if (site.LogoFileId != null)

View File

@ -375,4 +375,10 @@
<data name="SMTPEnabled.Text" xml:space="preserve"> <data name="SMTPEnabled.Text" xml:space="preserve">
<value>Enabled?</value> <value>Enabled?</value>
</data> </data>
<data name="Version.HelpText" xml:space="preserve">
<value>The site version (for site content migrations)</value>
</data>
<data name="Version.Text" xml:space="preserve">
<value>Version:</value>
</data>
</root> </root>

View File

@ -199,10 +199,6 @@ namespace Oqtane.Infrastructure
if (result.Success) if (result.Success)
{ {
result = CreateSite(install); result = CreateSite(install);
if (result.Success)
{
result = MigrateSites();
}
} }
} }
} }
@ -685,77 +681,6 @@ namespace Oqtane.Infrastructure
return result; return result;
} }
private Installation MigrateSites()
{
var result = new Installation { Success = false, Message = string.Empty };
// get site upgrades
Dictionary<string, Type> siteupgrades = new Dictionary<string, Type>();
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
foreach (Assembly assembly in assemblies)
{
foreach (var type in assembly.GetTypes(typeof(ISiteMigration)))
{
if (Attribute.IsDefined(type, typeof(SiteMigrationAttribute)))
{
var attribute = (SiteMigrationAttribute)Attribute.GetCustomAttribute(type, typeof(SiteMigrationAttribute));
siteupgrades.Add(attribute.AliasName + " " + attribute.Version, type);
}
}
}
// execute site upgrades
if (siteupgrades.Count > 0)
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var aliases = scope.ServiceProvider.GetRequiredService<IAliasRepository>();
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
var logger = scope.ServiceProvider.GetRequiredService<ILogManager>();
foreach (var alias in aliases.GetAliases().ToList().Where(item => item.IsDefault))
{
foreach (var upgrade in siteupgrades)
{
var aliasname = upgrade.Key.Split(' ').First();
// in the future this equality condition could use RegEx to allow for more flexible matching
if (string.Equals(alias.Name, aliasname, StringComparison.OrdinalIgnoreCase))
{
tenantManager.SetTenant(alias.TenantId);
var site = sites.GetSites().FirstOrDefault(item => item.SiteId == alias.SiteId);
if (site != null)
{
var version = upgrade.Key.Split(' ').Last();
if (string.IsNullOrEmpty(site.Version) || Version.Parse(version) > Version.Parse(site.Version))
{
try
{
var obj = ActivatorUtilities.CreateInstance(scope.ServiceProvider, upgrade.Value) as ISiteMigration;
if (obj != null)
{
obj.Up(site, alias);
site.Version = version;
sites.UpdateSite(site);
logger.Log(alias.SiteId, Shared.LogLevel.Information, "Site Migration", LogFunction.Other, "Site Migrated Successfully To Version {version} For {Alias}", version, alias.Name);
}
}
catch (Exception ex)
{
logger.Log(alias.SiteId, Shared.LogLevel.Error, "Site Migration", LogFunction.Other, ex, "An Error Occurred Executing Site Migration {Type} For {Alias} And Version {Version}", upgrade.Value, alias.Name, version);
}
}
}
}
}
}
}
}
result.Success = true;
return result;
}
private string DenormalizeConnectionString(string connectionString) private string DenormalizeConnectionString(string connectionString)
{ {
var dataDirectory = AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString(); var dataDirectory = AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString();

View File

@ -8,5 +8,6 @@ namespace Oqtane.Infrastructure
public int SiteId { get; set; } public int SiteId { get; set; }
public List<string> Assemblies { get; set; } = new List<string>(); public List<string> Assemblies { get; set; } = new List<string>();
public List<Resource>Scripts { get; set; } = new List<Resource>(); public List<Resource>Scripts { get; set; } = new List<Resource>();
public bool IsMigrated { get; set; } = false;
} }
} }

View File

@ -192,7 +192,7 @@ namespace Oqtane.Infrastructure
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>(); var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
foreach (Site site in sites.GetSites().ToList()) foreach (Site site in sites.GetSites().ToList())
{ {
sites.CreatePages(site, pageTemplates); sites.CreatePages(site, pageTemplates, null);
} }
} }
@ -243,7 +243,7 @@ namespace Oqtane.Infrastructure
{ {
if (!pages.GetPages(site.SiteId).ToList().Where(item => item.Path == "404").Any()) if (!pages.GetPages(site.SiteId).ToList().Where(item => item.Path == "404").Any())
{ {
sites.CreatePages(site, pageTemplates); sites.CreatePages(site, pageTemplates, null);
} }
} }
} }

View File

@ -110,7 +110,7 @@ namespace Oqtane.Pages
} }
} }
var site = _sites.GetSite(alias.SiteId); var site = _sites.InitializeSite(alias);
if (site != null && !site.IsDeleted && site.Runtime != "Hybrid") if (site != null && !site.IsDeleted && site.Runtime != "Hybrid")
{ {
Route route = new Route(url, alias.Path); Route route = new Route(url, alias.Path);
@ -174,7 +174,6 @@ namespace Oqtane.Pages
} }
HeadResources += ParseScripts(site.HeadContent); HeadResources += ParseScripts(site.HeadContent);
BodyResources += ParseScripts(site.BodyContent); BodyResources += ParseScripts(site.BodyContent);
_sites.InitializeSite(site.SiteId); // populates server state
var scripts = _serverState.GetServerState(site.SiteId).Scripts; var scripts = _serverState.GetServerState(site.SiteId).Scripts;
foreach (var script in scripts) foreach (var script in scripts)
{ {

View File

@ -11,7 +11,7 @@ namespace Oqtane.Repository
Site GetSite(int siteId); Site GetSite(int siteId);
Site GetSite(int siteId, bool tracking); Site GetSite(int siteId, bool tracking);
void DeleteSite(int siteId); void DeleteSite(int siteId);
void InitializeSite(int siteId); Site InitializeSite(Alias alias);
void CreatePages(Site site, List<PageTemplate> pageTemplates); void CreatePages(Site site, List<PageTemplate> pageTemplates, Alias alias);
} }
} }

View File

@ -11,7 +11,6 @@ using Oqtane.Infrastructure;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Modules; using Oqtane.Modules;
using Oqtane.Shared; using Oqtane.Shared;
using Oqtane.Themes;
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
@ -115,7 +114,7 @@ namespace Oqtane.Repository
{ {
moduleDefinitions = _cache.GetOrCreate($"moduledefinitions:{_tenants.GetAlias().SiteKey}", entry => moduleDefinitions = _cache.GetOrCreate($"moduledefinitions:{_tenants.GetAlias().SiteKey}", entry =>
{ {
entry.SlidingExpiration = TimeSpan.FromMinutes(30); entry.Priority = CacheItemPriority.NeverRemove;
return ProcessModuleDefinitions(siteId); return ProcessModuleDefinitions(siteId);
}); });
} }

View File

@ -1,11 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Oqtane.Extensions; using Oqtane.Enums;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Modules; using Oqtane.Modules;
@ -27,10 +27,13 @@ namespace Oqtane.Repository
private readonly IThemeRepository _themeRepository; private readonly IThemeRepository _themeRepository;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IConfigurationRoot _config; private readonly IConfigurationRoot _config;
private readonly ServerStateManager _serverState;
private readonly ILogManager _logger;
private static readonly object _lock = new object();
public SiteRepository(TenantDBContext context, IRoleRepository roleRepository, IProfileRepository profileRepository, IFolderRepository folderRepository, IPageRepository pageRepository, public SiteRepository(TenantDBContext context, IRoleRepository roleRepository, IProfileRepository profileRepository, IFolderRepository folderRepository, IPageRepository pageRepository,
IModuleRepository moduleRepository, IPageModuleRepository pageModuleRepository, IModuleDefinitionRepository moduleDefinitionRepository, IThemeRepository themeRepository, IServiceProvider serviceProvider, IModuleRepository moduleRepository, IPageModuleRepository pageModuleRepository, IModuleDefinitionRepository moduleDefinitionRepository, IThemeRepository themeRepository, IServiceProvider serviceProvider,
IConfigurationRoot config) IConfigurationRoot config, ServerStateManager serverState, ILogManager logger)
{ {
_db = context; _db = context;
_roleRepository = roleRepository; _roleRepository = roleRepository;
@ -43,6 +46,8 @@ namespace Oqtane.Repository
_themeRepository = themeRepository; _themeRepository = themeRepository;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_config = config; _config = config;
_serverState = serverState;
_logger = logger;
} }
public IEnumerable<Site> GetSites() public IEnumerable<Site> GetSites()
@ -90,10 +95,112 @@ namespace Oqtane.Repository
_db.SaveChanges(); _db.SaveChanges();
} }
public void InitializeSite(int siteId) public Site InitializeSite(Alias alias)
{ {
_moduleDefinitionRepository.GetModuleDefinitions(siteId); var site = GetSite(alias.SiteId);
_themeRepository.GetThemes(); _themeRepository.GetThemes();
var moduleDefinitions = _moduleDefinitionRepository.GetModuleDefinitions(alias.SiteId);
// site migrations
var serverstate = _serverState.GetServerState(alias.SiteId);
if (!serverstate.IsMigrated)
{
// ensure migrations are only executed once
lock (_lock)
{
if (!serverstate.IsMigrated)
{
var version = ProcessSiteMigrations(alias, site);
version = ProcessPageTemplates(alias, site, moduleDefinitions, version);
if (site.Version != version)
{
site.Version = version;
UpdateSite(site);
}
serverstate.IsMigrated = true;
_serverState.SetServerState(alias.SiteId, serverstate);
}
}
}
return site;
}
private string ProcessSiteMigrations(Alias alias, Site site)
{
var version = site.Version;
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
foreach (Assembly assembly in assemblies)
{
foreach (var type in assembly.GetTypes(typeof(ISiteMigration)))
{
if (Attribute.IsDefined(type, typeof(SiteMigrationAttribute)))
{
var attribute = (SiteMigrationAttribute)Attribute.GetCustomAttribute(type, typeof(SiteMigrationAttribute));
if (attribute.AliasName == "*" || attribute.AliasName == alias.Name)
{
if (string.IsNullOrEmpty(site.Version) || Version.Parse(attribute.Version) > Version.Parse(site.Version))
{
try
{
var obj = ActivatorUtilities.CreateInstance(_serviceProvider, type) as ISiteMigration;
if (obj != null)
{
obj.Up(site, alias);
_logger.Log(LogLevel.Information, "Site Migration", LogFunction.Other, "Site Migrated Successfully To Version {version} For {Alias}", version, alias.Name);
}
}
catch (Exception ex)
{
_logger.Log(LogLevel.Error, "Site Migration", LogFunction.Other, ex, "An Error Occurred Executing Site Migration {Type} For {Alias} And Version {Version}", type, alias.Name, version);
}
if (string.IsNullOrEmpty(version) || Version.Parse(attribute.Version) > Version.Parse(version))
{
version = attribute.Version;
}
}
}
}
}
}
return version;
}
private string ProcessPageTemplates(Alias alias, Site site, IEnumerable<ModuleDefinition> moduleDefinitions, string version)
{
var pageTemplates = new List<PageTemplate>();
foreach (var moduleDefinition in moduleDefinitions)
{
if (moduleDefinition.PageTemplates != null)
{
foreach (var pageTemplate in moduleDefinition.PageTemplates)
{
if (pageTemplate.PageTemplateModules.Count == 0)
{
pageTemplate.PageTemplateModules.Add(new PageTemplateModule());
}
foreach (var pageTemplateModule in pageTemplate.PageTemplateModules)
{
if (string.IsNullOrEmpty(pageTemplateModule.ModuleDefinitionName))
{
pageTemplateModule.ModuleDefinitionName = moduleDefinition.ModuleDefinitionName;
}
if (string.IsNullOrEmpty(pageTemplateModule.Title))
{
pageTemplateModule.Title = moduleDefinition.Name;
}
}
pageTemplates.Add(pageTemplate);
if (pageTemplate.Version != "*" && (string.IsNullOrEmpty(version) || Version.Parse(pageTemplate.Version) > Version.Parse(version)))
{
version = pageTemplate.Version;
}
}
}
}
CreatePages(site, pageTemplates, alias);
return version;
} }
private void CreateSite(Site site) private void CreateSite(Site site)
@ -188,90 +295,179 @@ namespace Oqtane.Repository
List<PageTemplate> pageTemplates = ((ISiteTemplate) siteTemplateObject).CreateSite(site); List<PageTemplate> pageTemplates = ((ISiteTemplate) siteTemplateObject).CreateSite(site);
if (pageTemplates != null && pageTemplates.Count > 0) if (pageTemplates != null && pageTemplates.Count > 0)
{ {
CreatePages(site, pageTemplates); CreatePages(site, pageTemplates, null);
} }
} }
// create admin pages // create admin pages
CreatePages(site, CreateAdminPages()); CreatePages(site, CreateAdminPages(), null);
} }
public void CreatePages(Site site, List<PageTemplate> pageTemplates) public void CreatePages(Site site, List<PageTemplate> pageTemplates, Alias alias)
{ {
List<ModuleDefinition> moduledefinitions = _moduleDefinitionRepository.GetModuleDefinitions(site.SiteId).ToList(); List<Page> pages = null;
foreach (PageTemplate pagetemplate in pageTemplates) List<PageModule> pageModules = null;
List<ModuleDefinition> moduleDefinitions = null;
foreach (PageTemplate pageTemplate in pageTemplates)
{ {
if (pageTemplate.AliasName == "*" || alias == null || pageTemplate.AliasName == alias.Name)
{
if (string.IsNullOrEmpty(site.Version) || pageTemplate.Version == "*" || Version.Parse(pageTemplate.Version) > Version.Parse(site.Version))
{
if (pages == null)
{
pages = _pageRepository.GetPages(site.SiteId).ToList();
}
var page = pages.FirstOrDefault(item => item.Path == pageTemplate.Path);
if (page == null)
{
page = new Page();
page.SiteId = site.SiteId;
page.Path = pageTemplate.Path.ToLower();
}
page.Name = (string.IsNullOrEmpty(pageTemplate.Name)) ? page.Path : pageTemplate.Name;
page.Name = (page.Name.Contains("/")) ? page.Name.Substring(page.Name.LastIndexOf("/") + 1) : page.Name;
int? parentid = null; int? parentid = null;
if (pagetemplate.Parent != "") if (!string.IsNullOrEmpty(pageTemplate.Parent))
{ {
List<Page> pages = _pageRepository.GetPages(site.SiteId).ToList(); if (pages.Any(item => item.Path.ToLower() == pageTemplate.Parent.ToLower()))
Page parent = pages.Where(item => item.Name == pagetemplate.Parent).FirstOrDefault(); {
parentid = parent.PageId; parentid = pages.FirstOrDefault(item => item.Path.ToLower() == pageTemplate.Parent.ToLower()).PageId;
}
}
page.ParentId = parentid;
page.Title = pageTemplate.Title;
page.Order = pageTemplate.Order;
page.Url = pageTemplate.Url;
page.ThemeType = pageTemplate.ThemeType;
page.DefaultContainerType = pageTemplate.DefaultContainerType;
page.HeadContent = pageTemplate.HeadContent;
page.BodyContent = pageTemplate.BodyContent;
page.Icon = pageTemplate.Icon;
page.IsNavigation = pageTemplate.IsNavigation;
page.IsClickable = pageTemplate.IsClickable;
page.IsPersonalizable = pageTemplate.IsPersonalizable;
page.UserId = null;
page.IsDeleted = pageTemplate.IsDeleted;
page.PermissionList = pageTemplate.PermissionList;
try
{
if (page.PageId != 0 && pageTemplate.Update)
{
page = _pageRepository.UpdatePage(page);
if (alias != null)
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Update, "Page Updated {Page}", page);
}
}
else
{
page = _pageRepository.AddPage(page);
pages.Add(page);
if (alias != null)
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Create, "Page Added {Page}", page);
}
}
}
catch (Exception ex)
{
if (alias != null)
{
_logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Processing Page {Page}", page);
}
} }
Page page = new Page if (pageModules == null)
{ {
SiteId = site.SiteId, pageModules = _pageModuleRepository.GetPageModules(site.SiteId).ToList();
ParentId = parentid, }
Name = pagetemplate.Name, if (moduleDefinitions == null)
Title = "", {
Path = pagetemplate.Path, moduleDefinitions = _moduleDefinitionRepository.GetModuleDefinitions(site.SiteId).ToList();
Order = (pagetemplate.Order == 0) ? 1 : pagetemplate.Order, }
Url = "", foreach (PageTemplateModule pageTemplateModule in pageTemplate.PageTemplateModules)
IsNavigation = pagetemplate.IsNavigation, {
ThemeType = "", var moduleDefinition = moduleDefinitions.Where(item => item.ModuleDefinitionName == pageTemplateModule.ModuleDefinitionName).FirstOrDefault();
DefaultContainerType = "", if (moduleDefinition != null)
Icon = pagetemplate.Icon, {
PermissionList = pagetemplate.PermissionList, var pageModule = pageModules.FirstOrDefault(item => item.PageId == page.PageId && item.Module.ModuleDefinitionName == pageTemplateModule.ModuleDefinitionName && item.Title == pageTemplateModule.Title);
IsPersonalizable = pagetemplate.IsPersonalizable, if (pageModule == null)
UserId = null, {
IsClickable = true pageModule = new PageModule();
}; pageModule.PageId = page.PageId;
page = _pageRepository.AddPage(page); pageModule.Module = new Module();
pageModule.Module.SiteId = site.SiteId;
pageModule.Module.ModuleDefinitionName = pageTemplateModule.ModuleDefinitionName;
}
pageModule.Title = pageTemplateModule.Title;
pageModule.Pane = pageTemplateModule.Pane;
pageModule.ContainerType = pageTemplateModule.ContainerType;
pageModule.IsDeleted = pageTemplateModule.IsDeleted;
pageModule.Module.PermissionList = pageTemplateModule.PermissionList;
pageModule.Module.AllPages = false;
pageModule.Module.IsDeleted = false;
try
{
if (pageModule.ModuleId != 0 && pageTemplate.Update)
{
_moduleRepository.UpdateModule(pageModule.Module);
_pageModuleRepository.UpdatePageModule(pageModule);
if (alias != null)
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Update, "Page Mopdule Updated {PageModule}", pageModule);
}
}
else
{
pageModule.Module = _moduleRepository.AddModule(pageModule.Module);
pageModule.ModuleId = pageModule.Module.ModuleId;
pageModule.Module = null; // remove tracking
_pageModuleRepository.AddPageModule(pageModule);
if (alias != null)
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Create, "Page Mopdule Added {PageModule}", pageModule);
}
}
foreach (PageTemplateModule pagetemplatemodule in pagetemplate.PageTemplateModules) }
catch (Exception ex)
{ {
if (pagetemplatemodule.ModuleDefinitionName != "") if (alias != null)
{ {
ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == pagetemplatemodule.ModuleDefinitionName).FirstOrDefault(); _logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Processing Page Module {PageModule}", pageModule);
if (moduledefinition != null) }
{ }
Module module = new Module
{
SiteId = site.SiteId,
ModuleDefinitionName = pagetemplatemodule.ModuleDefinitionName,
AllPages = false,
PermissionList = pagetemplatemodule.PermissionList,
};
module = _moduleRepository.AddModule(module);
if (pagetemplatemodule.Content != "" && moduledefinition.ServerManagerType!= "") if (pageTemplateModule.Content != "" && moduleDefinition.ServerManagerType != "")
{ {
Type moduletype = Type.GetType(moduledefinition.ServerManagerType); Type moduletype = Type.GetType(moduleDefinition.ServerManagerType);
if (moduletype != null && moduletype.GetInterface("IPortable") != null) if (moduletype != null && moduletype.GetInterface("IPortable") != null)
{ {
try try
{ {
var module = _moduleRepository.GetModule(pageModule.ModuleId);
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype); var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
((IPortable)moduleobject).ImportModule(module, pagetemplatemodule.Content, moduledefinition.Version); ((IPortable)moduleobject).ImportModule(module, pageTemplateModule.Content, moduleDefinition.Version);
} }
catch catch (Exception ex)
{ {
// error in IPortable implementation if (alias != null)
}
}
}
PageModule pagemodule = new PageModule
{ {
PageId = page.PageId, _logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Importing Content For {ModuleDefinitionName}", pageTemplateModule.ModuleDefinitionName);
ModuleId = module.ModuleId, }
Title = pagetemplatemodule.Title, }
Pane = pagetemplatemodule.Pane, }
Order = 1, }
ContainerType = "" }
}; else
_pageModuleRepository.AddPageModule(pagemodule); {
if (alias != null)
{
_logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, "Module Definition Does Not Exist {ModuleDefinitionName}", pageTemplateModule.ModuleDefinitionName);
}
}
} }
} }
} }

View File

@ -98,7 +98,7 @@ namespace Oqtane.Repository
// get themes // get themes
List<Theme> themes = _cache.GetOrCreate($"themes:{_tenants.GetAlias().SiteKey}", entry => List<Theme> themes = _cache.GetOrCreate($"themes:{_tenants.GetAlias().SiteKey}", entry =>
{ {
entry.SlidingExpiration = TimeSpan.FromMinutes(30); entry.Priority = CacheItemPriority.NeverRemove;
return ProcessThemes(siteId); return ProcessThemes(siteId);
}); });

View File

@ -35,6 +35,8 @@ namespace Oqtane.Models
Runtimes = ""; Runtimes = "";
Template = ""; Template = "";
Resources = null; Resources = null;
IsAutoEnabled = true;
PageTemplates = null;
} }
/// <summary> /// <summary>
@ -111,7 +113,10 @@ namespace Oqtane.Models
public List<Resource> Resources { get; set; } // added in 4.0.0 public List<Resource> Resources { get; set; } // added in 4.0.0
[NotMapped] [NotMapped]
public bool IsAutoEnabled { get; set; } = true; // added in 4.0.0 public bool IsAutoEnabled { get; set; } // added in 4.0.0
[NotMapped]
public List<PageTemplate> PageTemplates { get; set; } // added in 4.0.0
// internal properties // internal properties
[NotMapped] [NotMapped]

View File

@ -21,6 +21,12 @@ namespace Oqtane.Models
/// </summary> /// </summary>
public int SiteId { get; set; } public int SiteId { get; set; }
/// <summary>
/// Path of the page.
/// TODO: todoc relative to what? site root, parent-page, domain?
/// </summary>
public string Path { get; set; }
/// <summary> /// <summary>
/// Reference to the parent <see cref="Page"/> if it has one. /// Reference to the parent <see cref="Page"/> if it has one.
/// </summary> /// </summary>
@ -37,12 +43,6 @@ namespace Oqtane.Models
/// </summary> /// </summary>
public string Title { get; set; } public string Title { get; set; }
/// <summary>
/// Path of the page.
/// TODO: todoc relative to what? site root, parent-page, domain?
/// </summary>
public string Path { get; set; }
/// <summary> /// <summary>
/// Sort order in the list of other sibling pages /// Sort order in the list of other sibling pages
/// </summary> /// </summary>

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json; using System.Text.Json;
using Oqtane.Shared;
namespace Oqtane.Models namespace Oqtane.Models
{ {
@ -13,16 +13,59 @@ namespace Oqtane.Models
public class PageTemplate public class PageTemplate
{ {
public string Name { get; set; } public PageTemplate()
public string Parent { get; set; } {
public int Order { get; set; } Url = "";
Name = "";
Parent = "";
Title = "";
Path = "";
Order = 1;
ThemeType = "";
DefaultContainerType = "";
HeadContent = "";
BodyContent = "";
Icon = "";
IsNavigation = true;
IsClickable = true;
IsPersonalizable = false;
IsDeleted = false;
PermissionList = new List<Permission>()
{
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
};
PageTemplateModules = new List<PageTemplateModule>();
// properties used by IModule
AliasName = "*";
Version = "*";
Update = false;
}
public string Path { get; set; } public string Path { get; set; }
public string Parent { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public int Order { get; set; }
public string Url { get; set; }
public string ThemeType { get; set; }
public string DefaultContainerType { get; set; }
public string HeadContent { get; set; }
public string BodyContent { get; set; }
public string Icon { get; set; } public string Icon { get; set; }
public bool IsNavigation { get; set; } public bool IsNavigation { get; set; }
public bool IsClickable { get; set; }
public bool IsPersonalizable { get; set; } public bool IsPersonalizable { get; set; }
public bool IsDeleted { get; set; }
public List<Permission> PermissionList { get; set; } public List<Permission> PermissionList { get; set; }
public List<PageTemplateModule> PageTemplateModules { get; set; } public List<PageTemplateModule> PageTemplateModules { get; set; }
// properties used by IModule
public string AliasName { get; set; }
public string Version { get; set; }
public bool Update { get; set; }
[Obsolete("This property is obsolete", false)] [Obsolete("This property is obsolete", false)]
public bool EditMode { get; set; } public bool EditMode { get; set; }
@ -42,9 +85,28 @@ namespace Oqtane.Models
public class PageTemplateModule public class PageTemplateModule
{ {
public PageTemplateModule()
{
ModuleDefinitionName = "";
Title = "";
Pane = PaneNames.Default;
Order = 1;
ContainerType = "";
IsDeleted = false;
PermissionList = new List<Permission>()
{
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
};
Content = "";
}
public string ModuleDefinitionName { get; set; } public string ModuleDefinitionName { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string Pane { get; set; } public string Pane { get; set; }
public int Order { get; set; }
public string ContainerType { get; set; }
public bool IsDeleted { get; set; }
public List<Permission> PermissionList { get; set; } public List<Permission> PermissionList { get; set; }
public string Content { get; set; } public string Content { get; set; }