Merge remote-tracking branch 'oqtane/dev' into dev
This commit is contained in:
@ -119,7 +119,13 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mx-auto text-center">
|
<div class="mx-auto text-center">
|
||||||
<button type="button" class="btn btn-success" @onclick="Install">@Localizer["InstallNow"]</button><br /><br />
|
<button type="button" class="btn btn-success" @onclick="Install">@Localizer["InstallNow"]</button><br /><br />
|
||||||
<ModuleMessage Message="@_message" Type="MessageType.Error"></ModuleMessage>
|
@if (!string.IsNullOrEmpty(_message))
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show mb-3" role="alert">
|
||||||
|
@((MarkupString)_message)
|
||||||
|
<button type="button" class="btn-close" aria-label="Close" @onclick="DismissModal"></button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="app-progress-indicator" style="@_loadingDisplay"></div>
|
<div class="app-progress-indicator" style="@_loadingDisplay"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -316,4 +322,9 @@
|
|||||||
_showConnectionString = !_showConnectionString;
|
_showConnectionString = !_showConnectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DismissModal()
|
||||||
|
{
|
||||||
|
_message = "";
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
{
|
{
|
||||||
if (page.IsClickable)
|
if (page.IsClickable)
|
||||||
{
|
{
|
||||||
var url = string.IsNullOrEmpty(page.Url) ? NavigateUrl(page.Path) : page.Url;
|
return string.IsNullOrEmpty(page.Url) ? NavigateUrl(page.Path) : page.Url;
|
||||||
if (PageState.QueryString.ContainsKey("method"))
|
|
||||||
{
|
|
||||||
url += ((url.Contains("?")) ? "&" : "?") + "method=" + PageState.QueryString["method"];
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -42,16 +42,6 @@
|
|||||||
}
|
}
|
||||||
headcontent += $"<link id=\"app-favicon\" rel=\"shortcut icon\" type=\"image/{favicontype}\" href=\"{favicon}\" />\n";
|
headcontent += $"<link id=\"app-favicon\" rel=\"shortcut icon\" type=\"image/{favicontype}\" href=\"{favicon}\" />\n";
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("method") && PageState.QueryString["method"] == "new")
|
|
||||||
{
|
|
||||||
// stylesheets
|
|
||||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
|
||||||
{
|
|
||||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
|
||||||
headcontent += "<link rel=\"stylesheet\" href=\"" + url + "\"" + (!string.IsNullOrEmpty(resource.Integrity) ? " integrity=\"" + resource.Integrity + "\"" : "") + (!string.IsNullOrEmpty(resource.CrossOrigin) ? " crossorigin=\"" + resource.CrossOrigin + "\"" : "") + " type=\"text/css\"/>" + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// head content
|
// head content
|
||||||
AddHeadContent(headcontent, PageState.Site.HeadContent);
|
AddHeadContent(headcontent, PageState.Site.HeadContent);
|
||||||
if (!string.IsNullOrEmpty(PageState.Site.HeadContent))
|
if (!string.IsNullOrEmpty(PageState.Site.HeadContent))
|
||||||
@ -106,27 +96,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PageState.QueryString.ContainsKey("method") || (PageState.QueryString.ContainsKey("method") && PageState.QueryString["method"] == "old"))
|
// style sheets
|
||||||
|
if (PageState.Page.Resources != null && PageState.Page.Resources.Exists(item => item.ResourceType == ResourceType.Stylesheet))
|
||||||
{
|
{
|
||||||
// style sheets
|
var interop = new Interop(JSRuntime);
|
||||||
if (PageState.Page.Resources != null && PageState.Page.Resources.Exists(item => item.ResourceType == ResourceType.Stylesheet))
|
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
||||||
|
var links = new List<object>();
|
||||||
|
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||||
{
|
{
|
||||||
var interop = new Interop(JSRuntime);
|
var prefix = "app-stylesheet-" + resource.Level.ToString().ToLower();
|
||||||
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
||||||
var links = new List<object>();
|
links.Add(new { id = prefix + "-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", insertbefore = prefix });
|
||||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
|
||||||
{
|
|
||||||
var prefix = "app-stylesheet-" + resource.Level.ToString().ToLower();
|
|
||||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
|
||||||
links.Add(new { id = prefix + "-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", insertbefore = prefix });
|
|
||||||
}
|
|
||||||
if (links.Any())
|
|
||||||
{
|
|
||||||
await interop.IncludeLinks(links.ToArray());
|
|
||||||
}
|
|
||||||
await interop.RemoveElementsById("app-stylesheet-page-", "", "app-stylesheet-page-" + batch + "-00");
|
|
||||||
await interop.RemoveElementsById("app-stylesheet-module-", "", "app-stylesheet-module-" + batch + "-00");
|
|
||||||
}
|
}
|
||||||
|
if (links.Any())
|
||||||
|
{
|
||||||
|
await interop.IncludeLinks(links.ToArray());
|
||||||
|
}
|
||||||
|
await interop.RemoveElementsById("app-stylesheet-page-", "", "app-stylesheet-page-" + batch + "-00");
|
||||||
|
await interop.RemoveElementsById("app-stylesheet-module-", "", "app-stylesheet-module-" + batch + "-00");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Oqtane.Infrastructure
|
namespace Oqtane.Infrastructure
|
||||||
{
|
{
|
||||||
// this interface is for declaring global resources and is useful for scenarios where you want to declare resources in a single location for the entire application
|
|
||||||
public interface IHostResources
|
public interface IHostResources
|
||||||
{
|
{
|
||||||
|
[Obsolete("IHostResources is deprecated. Use module or theme scoped Resources in conjunction with ResourceLevel.Site instead.", false)]
|
||||||
List<Resource> Resources { get; } // identifies global resources for an application
|
List<Resource> Resources { get; } // identifies global resources for an application
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
@ -38,17 +39,23 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
await Task.Yield(); // required so that this method does not block startup
|
await Task.Yield(); // required so that this method does not block startup
|
||||||
|
|
||||||
try
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
while (!stoppingToken.IsCancellationRequested)
|
using (var scope = _serviceScopeFactory.CreateScope())
|
||||||
{
|
{
|
||||||
using (var scope = _serviceScopeFactory.CreateScope())
|
ILogger<HostedServiceBase> _filelogger = scope.ServiceProvider.GetRequiredService<ILogger<HostedServiceBase>>();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
|
var jobs = scope.ServiceProvider.GetRequiredService<IJobRepository>();
|
||||||
|
var jobLogs = scope.ServiceProvider.GetRequiredService<IJobLogRepository>();
|
||||||
|
var tenantRepository = scope.ServiceProvider.GetRequiredService<ITenantRepository>();
|
||||||
|
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
||||||
|
|
||||||
// get name of job
|
// get name of job
|
||||||
string jobType = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName);
|
string jobType = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName);
|
||||||
|
|
||||||
// load jobs and find current job
|
// load jobs and find current job
|
||||||
IJobRepository jobs = scope.ServiceProvider.GetRequiredService<IJobRepository>();
|
|
||||||
Job job = jobs.GetJobs().Where(item => item.JobType == jobType).FirstOrDefault();
|
Job job = jobs.GetJobs().Where(item => item.JobType == jobType).FirstOrDefault();
|
||||||
if (job != null && job.IsEnabled && !job.IsExecuting)
|
if (job != null && job.IsEnabled && !job.IsExecuting)
|
||||||
{
|
{
|
||||||
@ -73,7 +80,9 @@ namespace Oqtane.Infrastructure
|
|||||||
// determine if the job should be run
|
// determine if the job should be run
|
||||||
if (NextExecution <= DateTime.UtcNow && (job.EndDate == null || job.EndDate >= DateTime.UtcNow))
|
if (NextExecution <= DateTime.UtcNow && (job.EndDate == null || job.EndDate >= DateTime.UtcNow))
|
||||||
{
|
{
|
||||||
IJobLogRepository jobLogs = scope.ServiceProvider.GetRequiredService<IJobLogRepository>();
|
// update the job to indicate it is running
|
||||||
|
job.IsExecuting = true;
|
||||||
|
jobs.UpdateJob(job);
|
||||||
|
|
||||||
// create a job log entry
|
// create a job log entry
|
||||||
JobLog log = new JobLog();
|
JobLog log = new JobLog();
|
||||||
@ -84,16 +93,10 @@ namespace Oqtane.Infrastructure
|
|||||||
log.Notes = "";
|
log.Notes = "";
|
||||||
log = jobLogs.AddJobLog(log);
|
log = jobLogs.AddJobLog(log);
|
||||||
|
|
||||||
// update the job to indicate it is running
|
|
||||||
job.IsExecuting = true;
|
|
||||||
jobs.UpdateJob(job);
|
|
||||||
|
|
||||||
// execute the job
|
// execute the job
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var notes = "";
|
var notes = "";
|
||||||
var tenantRepository = scope.ServiceProvider.GetRequiredService<ITenantRepository>();
|
|
||||||
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
|
||||||
foreach (var tenant in tenantRepository.GetTenants())
|
foreach (var tenant in tenantRepository.GetTenants())
|
||||||
{
|
{
|
||||||
// set tenant and execute job
|
// set tenant and execute job
|
||||||
@ -133,16 +136,19 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
// wait 1 minute
|
{
|
||||||
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
|
// can occur during the initial installation because the database has not yet been created
|
||||||
|
if (!ex.Message.Contains("No database provider has been configured for this DbContext"))
|
||||||
|
{
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, $"An Error Occurred Executing Scheduled Job: {Name} - {ex}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// can occur during the initial installation as there is no DBContext
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// wait 1 minute
|
||||||
|
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateTime CalculateNextExecution(DateTime nextExecution, Job job)
|
private DateTime CalculateNextExecution(DateTime nextExecution, Job job)
|
||||||
@ -191,9 +197,11 @@ namespace Oqtane.Infrastructure
|
|||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
using (var scope = _serviceScopeFactory.CreateScope())
|
||||||
{
|
{
|
||||||
using (var scope = _serviceScopeFactory.CreateScope())
|
ILogger<HostedServiceBase> _filelogger = scope.ServiceProvider.GetRequiredService<ILogger<HostedServiceBase>>();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
string jobTypeName = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName);
|
string jobTypeName = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName);
|
||||||
IJobRepository jobs = scope.ServiceProvider.GetRequiredService<IJobRepository>();
|
IJobRepository jobs = scope.ServiceProvider.GetRequiredService<IJobRepository>();
|
||||||
@ -207,7 +215,7 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// auto registration - job will not run on initial installation but will run after restart
|
// auto registration - job will not run on initial installation due to no DBContext but will run after restart
|
||||||
job = new Job { JobType = jobTypeName };
|
job = new Job { JobType = jobTypeName };
|
||||||
|
|
||||||
// optional HostedServiceBase properties
|
// optional HostedServiceBase properties
|
||||||
@ -233,17 +241,21 @@ namespace Oqtane.Infrastructure
|
|||||||
jobs.AddJob(job);
|
jobs.AddJob(job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
_executingTask = ExecuteAsync(_cancellationTokenSource.Token);
|
|
||||||
|
|
||||||
if (_executingTask.IsCompleted)
|
|
||||||
{
|
{
|
||||||
return _executingTask;
|
// can occur during the initial installation because the database has not yet been created
|
||||||
|
if (!ex.Message.Contains("No database provider has been configured for this DbContext"))
|
||||||
|
{
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, $"An Error Occurred Starting Scheduled Job: {Name} - {ex}"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
|
_executingTask = ExecuteAsync(_cancellationTokenSource.Token);
|
||||||
|
|
||||||
|
if (_executingTask.IsCompleted)
|
||||||
{
|
{
|
||||||
// can occur during the initial installation because this method is called during startup and the database has not yet been created
|
return _executingTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@ -251,9 +263,11 @@ namespace Oqtane.Infrastructure
|
|||||||
|
|
||||||
public async Task StopAsync(CancellationToken cancellationToken)
|
public async Task StopAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
using (var scope = _serviceScopeFactory.CreateScope())
|
||||||
{
|
{
|
||||||
using (var scope = _serviceScopeFactory.CreateScope())
|
ILogger<HostedServiceBase> _filelogger = scope.ServiceProvider.GetRequiredService<ILogger<HostedServiceBase>>();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
string jobTypeName = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName);
|
string jobTypeName = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName);
|
||||||
IJobRepository jobs = scope.ServiceProvider.GetRequiredService<IJobRepository>();
|
IJobRepository jobs = scope.ServiceProvider.GetRequiredService<IJobRepository>();
|
||||||
@ -266,10 +280,11 @@ namespace Oqtane.Infrastructure
|
|||||||
jobs.UpdateJob(job);
|
jobs.UpdateJob(job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (Exception ex)
|
||||||
catch
|
{
|
||||||
{
|
// error updating the job
|
||||||
// error updating the job
|
_filelogger.LogError(Utilities.LogMessage(this, $"An Error Occurred Stopping Scheduled Job: {Name} - {ex}"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop called without start
|
// stop called without start
|
||||||
|
@ -57,10 +57,10 @@ namespace Oqtane.SiteTemplates
|
|||||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||||
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||||
},
|
},
|
||||||
Content = "<p><a href=\"https://www.oqtane.org\" target=\"_new\">Oqtane</a> is an open source <b>CMS</b> and <b>Application Framework</b> that provides advanced functionality for developing web, mobile, and desktop applications on .NET Core. It leverages the Blazor component model to compose a <b>fully dynamic</b> web development experience which can be hosted either client-side or server-side. Whether you are looking for a platform to <b>accelerate your web development</b> efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles.</p>" +
|
Content = "<p><a href=\"https://www.oqtane.org\" target=\"_new\">Oqtane</a> is an open source <b>CMS</b> and <b>Application Framework</b> that provides advanced functionality for developing web, mobile, and desktop applications on .NET. It leverages Blazor to compose a <b>fully dynamic</b> digital experience. Whether you are looking for a platform to <b>accelerate your web development</b> efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles and patterns.</p>" +
|
||||||
"<p align=\"center\"><a href=\"https://www.oqtane.org\" target=\"_new\"><img class=\"img-fluid\" src=\"oqtane-glow.png\"></a></p><p align=\"center\"><a class=\"btn btn-primary\" href=\"https://www.oqtane.org/Community\" target=\"_new\">Join Our Community</a> <a class=\"btn btn-primary\" href=\"https://github.com/oqtane/oqtane.framework\" target=\"_new\">Clone Our Repo</a></p>" +
|
"<p align=\"center\"><a href=\"https://www.oqtane.org\" target=\"_new\"><img class=\"img-fluid\" src=\"oqtane-glow.png\"></a></p><p align=\"center\"><a class=\"btn btn-primary\" href=\"https://www.oqtane.org\" target=\"_new\">Join Our Community</a> <a class=\"btn btn-primary\" href=\"https://github.com/oqtane/oqtane.framework\" target=\"_new\">Clone Our Repo</a></p>" +
|
||||||
"<p><a href=\"https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor\" target=\"_new\">Blazor</a> is an open source and cross-platform web UI framework for building single-page applications using .NET and C#. Blazor applications can be hosted in a variety of ways. Blazor Server uses SignalR (WebSockets) to host your application on a web server and provide a responsive and robust development experience. Blazor WebAssembly relies on Wasm, an open web standard that does not require plugins in order for applications to run natively in a web browser. Blazor Hybrid is part of .NET MAUI and uses a Web View to render components natively on mobile and desktop devices. Razor components can be used with all of the hosting models without any modification.</p>" +
|
"<p><a href=\"https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor\" target=\"_new\">Blazor</a> is an open source and cross-platform web UI framework for building single-page applications using .NET and C#. Blazor applications can be hosted in a variety of ways. Blazor Server uses SignalR (WebSockets) to host your application on a web server and provide a responsive and robust development experience. Blazor WebAssembly relies on Wasm, an open web standard that does not require plugins in order for applications to run natively in a web browser. Blazor Hybrid is part of .NET MAUI and uses a Web View to render components natively on mobile and desktop devices. Razor components can be shared across all of the hosting models without any modification.</p>" +
|
||||||
"<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">.NET Core</a>, the popular cross platform web development framework from Microsoft that extends the <a href=\"https://dotnet.microsoft.com/learn/dotnet/what-is-dotnet\" target=\"_new\" >.NET developer platform</a> with tools and libraries for building web apps.</p>"
|
"<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">ASP.NET</a>, the popular cross platform development framework from Microsoft that provides powerful tools and libraries for building modern software applications.</p>"
|
||||||
},
|
},
|
||||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "MIT License", Pane = PaneNames.Default,
|
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "MIT License", Pane = PaneNames.Default,
|
||||||
PermissionList = new List<Permission> {
|
PermissionList = new List<Permission> {
|
||||||
|
@ -167,29 +167,26 @@ namespace Oqtane.Pages
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stylesheets
|
// stylesheets
|
||||||
if (!HttpContext.Request.Query.ContainsKey("method") || (HttpContext.Request.Query.ContainsKey("method") && HttpContext.Request.Query["method"] == "old"))
|
var resources = new List<Resource>();
|
||||||
|
if (string.IsNullOrEmpty(page.ThemeType))
|
||||||
{
|
{
|
||||||
var resources = new List<Resource>();
|
page.ThemeType = site.DefaultThemeType;
|
||||||
if (string.IsNullOrEmpty(page.ThemeType))
|
|
||||||
{
|
|
||||||
page.ThemeType = site.DefaultThemeType;
|
|
||||||
}
|
|
||||||
var theme = site.Themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
|
|
||||||
if (theme?.Resources != null)
|
|
||||||
{
|
|
||||||
resources.AddRange(theme.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet).ToList());
|
|
||||||
}
|
|
||||||
var type = Type.GetType(page.ThemeType);
|
|
||||||
if (type != null)
|
|
||||||
{
|
|
||||||
var obj = Activator.CreateInstance(type) as IThemeControl;
|
|
||||||
if (obj?.Resources != null)
|
|
||||||
{
|
|
||||||
resources.AddRange(obj.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet).ToList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ManageStyleSheets(resources, alias, theme.ThemeName);
|
|
||||||
}
|
}
|
||||||
|
var theme = site.Themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
|
||||||
|
if (theme?.Resources != null)
|
||||||
|
{
|
||||||
|
resources.AddRange(theme.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet).ToList());
|
||||||
|
}
|
||||||
|
var type = Type.GetType(page.ThemeType);
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
var obj = Activator.CreateInstance(type) as IThemeControl;
|
||||||
|
if (obj?.Resources != null)
|
||||||
|
{
|
||||||
|
resources.AddRange(obj.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet).ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ManageStyleSheets(resources, alias, theme.ThemeName);
|
||||||
|
|
||||||
// scripts
|
// scripts
|
||||||
if (Runtime == "Server")
|
if (Runtime == "Server")
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Oqtane is a CMS and Application Framework. It leverages Blazor, an open source and cross-platform web UI framework for building single-page apps using .NET and C# instead of JavaScript. Blazor apps are composed of reusable web UI components implemented using C#, HTML, and CSS. Both client and server code is written in C#, allowing you to share code and libraries.
|
Oqtane is a CMS and Application Framework. It leverages Blazor, an open source and cross-platform web UI framework for building modern apps using .NET and C# instead of JavaScript. Blazor apps are composed of reusable web UI components implemented using C#, HTML, and CSS. Both client and server code is written in C#, allowing you to share code and libraries.
|
||||||
|
|
||||||
Oqtane is being developed based on some fundamental principles which are outlined in the [Oqtane Philosophy](https://www.oqtane.org/blog/!/20/oqtane-philosophy).
|
Oqtane is being developed based on some fundamental principles which are outlined in the [Oqtane Philosophy](https://www.oqtane.org/blog/!/20/oqtane-philosophy).
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user