@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>10.1.0</Version>
|
||||
<Version>10.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@@ -10,7 +10,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Oqtane.Client" Version="10.1.0" />
|
||||
<PackageReference Include="Oqtane.Client" Version="10.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Application.Template</id>
|
||||
<version>10.1.0</version>
|
||||
<version>10.1.1</version>
|
||||
<title>Oqtane Application Template For Blazor</title>
|
||||
<authors>Shaun Walker</authors>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Oqtane.Server" Version="10.1.0" />
|
||||
<PackageReference Include="Oqtane.Server" Version="10.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Oqtane.Shared" Version="10.1.0" />
|
||||
<PackageReference Include="Oqtane.Shared" Version="10.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="site" HelpText="Specify if site properties should be updated (ie. name, headcontent, bodycontent)" ResourceKey="Site">Site Properties? </Label>
|
||||
<Label Class="col-sm-3" For="site" HelpText="Specify if site information should be updated (ie. name, head content, body content, settings)" ResourceKey="Site">Site Info? </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="site" class="form-select" @bind="@_site">
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
@@ -37,7 +37,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="pages" HelpText="Specify if page properties should be updated (ie. name, title, headcontent, bodycontent)" ResourceKey="Pages">Page Properties? </Label>
|
||||
<Label Class="col-sm-3" For="pages" HelpText="Specify if page information should be updated (ie. name, title, head content, body content, settings)" ResourceKey="Pages">Page Info? </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="pages" class="form-select" @bind="@_pages">
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
@@ -46,7 +46,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="modules" HelpText="Specify if module properties should be updated (ie. title, header, footer)" ResourceKey="Modules">Module Properties? </Label>
|
||||
<Label Class="col-sm-3" For="modules" HelpText="Specify if module information should be updated (ie. title, header, footer, settings)" ResourceKey="Modules">Module Info? </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="modules" class="form-select" @bind="@_modules">
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
|
||||
@@ -130,7 +130,7 @@ else
|
||||
|
||||
private async Task LoadModuleDefinitions()
|
||||
{
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries).Contains(_category)).ToList();
|
||||
_packages = await PackageService.GetPackageUpdatesAsync("module");
|
||||
}
|
||||
|
||||
|
||||
@@ -1413,10 +1413,13 @@
|
||||
{
|
||||
if (_siteGroupId != -1)
|
||||
{
|
||||
var siteGroupMember = await SiteGroupMemberService.GetSiteGroupMemberAsync(PageState.Site.SiteId, _siteGroupId);
|
||||
if (siteGroupMember != null)
|
||||
if (_siteId != -1)
|
||||
{
|
||||
await SiteGroupMemberService.DeleteSiteGroupMemberAsync(siteGroupMember.SiteGroupId);
|
||||
var siteGroupMember = await SiteGroupMemberService.GetSiteGroupMemberAsync(_siteId, _siteGroupId);
|
||||
if (siteGroupMember != null)
|
||||
{
|
||||
await SiteGroupMemberService.DeleteSiteGroupMemberAsync(siteGroupMember.SiteGroupMemberId);
|
||||
}
|
||||
}
|
||||
|
||||
var siteGroupMembers = await SiteGroupMemberService.GetSiteGroupMembersAsync(-1, _siteGroupId);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.3" />
|
||||
<PackageReference Include="Radzen.Blazor" Version="9.0.0" />
|
||||
<PackageReference Include="Radzen.Blazor" Version="9.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -130,16 +130,16 @@
|
||||
<value>Specify if module content should be updated</value>
|
||||
</data>
|
||||
<data name="Pages.Text" xml:space="preserve">
|
||||
<value>Page Properties?</value>
|
||||
<value>Page Info?</value>
|
||||
</data>
|
||||
<data name="Pages.HelpText" xml:space="preserve">
|
||||
<value>Specify if page properties should be updated (ie. name, title, headcontent, bodycontent)</value>
|
||||
<value>Specify if page information should be updated (ie. name, title, head content, body content settings)</value>
|
||||
</data>
|
||||
<data name="Site.Text" xml:space="preserve">
|
||||
<value>Site Properties?</value>
|
||||
<value>Site Info?</value>
|
||||
</data>
|
||||
<data name="Site.HelpText" xml:space="preserve">
|
||||
<value>Specify if site properties should be updated (ie. name, headcontent, bodycontent)</value>
|
||||
<value>Specify if site information should be updated (ie. name, head content, body content, settings)</value>
|
||||
</data>
|
||||
<data name="Replace.Text" xml:space="preserve">
|
||||
<value>Replace With:</value>
|
||||
@@ -148,10 +148,10 @@
|
||||
<value>Specify the replacement content</value>
|
||||
</data>
|
||||
<data name="Modules.Text" xml:space="preserve">
|
||||
<value>Module Properties?</value>
|
||||
<value>Module Info?</value>
|
||||
</data>
|
||||
<data name="Modules.HelpText" xml:space="preserve">
|
||||
<value>Specify if module properties should be updated (ie. title, header, footer)</value>
|
||||
<value>Specify if module information should be updated (ie. title, header, footer settings)</value>
|
||||
</data>
|
||||
<data name="Success.Save" xml:space="preserve">
|
||||
<value>Your Global Replace Request Has Been Submitted And Will Be Executed Shortly. Please Be Patient.</value>
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
||||
_containerType = PageState.Site.DefaultContainerType;
|
||||
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Page.SiteId);
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries).Contains(_category)).ToList();
|
||||
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries)).Distinct().Where(item => item != "Headless").ToList();
|
||||
_siteGroups = await SiteGroupService.GetSiteGroupsAsync(PageState.Site.SiteId);
|
||||
}
|
||||
@@ -312,7 +312,7 @@
|
||||
private void CategoryChanged(ChangeEventArgs e)
|
||||
{
|
||||
_category = (string)e.Value;
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries).Contains(_category)).ToList();
|
||||
_moduleDefinitionName = "-";
|
||||
_message = "";
|
||||
}
|
||||
@@ -521,7 +521,7 @@
|
||||
case "Edit":
|
||||
// get page management moduleid
|
||||
moduleId = int.Parse(PageState.Site.Settings[Constants.PageManagementModule]);
|
||||
NavigationManager.NavigateTo(Utilities.EditUrl(PageState.Alias.Path, "admin/pages", moduleId, "Edit", $"id={PageState.Page.PageId}&returnurl={WebUtility.UrlEncode(PageState.Route.PathAndQuery)}"));
|
||||
NavigationManager.NavigateTo(Utilities.EditUrl(PageState.Alias.Path, "admin/pages", moduleId, location, $"id={PageState.Page.PageId}&returnurl={WebUtility.UrlEncode(PageState.Route.PathAndQuery)}"));
|
||||
break;
|
||||
case "Copy":
|
||||
// get page management moduleid
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<ApplicationId>com.oqtane.maui</ApplicationId>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>10.1.0</ApplicationDisplayVersion>
|
||||
<ApplicationDisplayVersion>10.1.1</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>10.1.0</version>
|
||||
<version>10.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
@@ -23,7 +23,7 @@
|
||||
<dependency id="Microsoft.AspNetCore.Components.WebAssembly.Authentication" version="10.0.3" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.Localization" version="10.0.3" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.Http" version="10.0.3" exclude="Build,Analyzers" />
|
||||
<dependency id="Radzen.Blazor" version="9.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Radzen.Blazor" version="9.0.8" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>10.1.0</version>
|
||||
<version>10.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@@ -11,8 +11,8 @@
|
||||
<copyright>.NET Foundation</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v10.1.0/Oqtane.Framework.10.1.0.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v10.1.1/Oqtane.Framework.10.1.1.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane framework</tags>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>10.1.0</version>
|
||||
<version>10.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
@@ -26,8 +26,8 @@
|
||||
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="10.0.3" exclude="Build,Analyzers" />
|
||||
<dependency id="SixLabors.ImageSharp" version="3.1.12" exclude="Build,Analyzers" />
|
||||
<dependency id="HtmlAgilityPack" version="1.12.4" exclude="Build,Analyzers" />
|
||||
<dependency id="Swashbuckle.AspNetCore" version="10.1.2" exclude="Build,Analyzers" />
|
||||
<dependency id="MailKit" version="4.14.1" exclude="Build,Analyzers" />
|
||||
<dependency id="Swashbuckle.AspNetCore" version="10.1.4" exclude="Build,Analyzers" />
|
||||
<dependency id="MailKit" version="4.15.1" exclude="Build,Analyzers" />
|
||||
<dependency id="MySql.Data" version="9.6.0" exclude="Build,Analyzers" />
|
||||
<dependency id="MySql.EntityFrameworkCore" version="10.0.1" exclude="Build,Analyzers" />
|
||||
<dependency id="EFCore.NamingConventions" version="10.0.1" exclude="Build,Analyzers" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>10.1.0</version>
|
||||
<version>10.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
@@ -20,7 +20,7 @@
|
||||
<group targetFramework="net10.0">
|
||||
<dependency id="Microsoft.EntityFrameworkCore" version="10.0.3" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.DependencyInjection.Abstractions" version="10.0.3" exclude="Build,Analyzers" />
|
||||
<dependency id="NodaTime" version="3.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="NodaTime" version="3.3.1" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Updater</id>
|
||||
<version>10.1.0</version>
|
||||
<version>10.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
|
||||
@@ -1 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.0.Install.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.1.Install.zip" -Force
|
||||
|
||||
@@ -1 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.0.Upgrade.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.1.Upgrade.zip" -Force
|
||||
|
||||
@@ -266,6 +266,28 @@
|
||||
|
||||
private void HandlePageNotFound(Site site, Page page, Route route)
|
||||
{
|
||||
// filter
|
||||
string useragent = (Context.Request.Headers[HeaderNames.UserAgent] != StringValues.Empty) ? Context.Request.Headers[HeaderNames.UserAgent] : "(none)";
|
||||
var settings = Context.GetSiteSettings();
|
||||
var filter = settings.GetValue("VisitorFilter", Constants.DefaultVisitorFilter);
|
||||
foreach (string term in filter.ToLower().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray())
|
||||
{
|
||||
if (_remoteIPAddress.ToLower().Contains(term) || useragent.ToLower().Contains(term))
|
||||
{
|
||||
// handle not found request in static mode
|
||||
if (_renderMode == RenderModes.Static)
|
||||
{
|
||||
NavigationManager.NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
// redirect to 404 page
|
||||
NavigationManager.NavigateTo(route.SiteUrl + "/404", true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// referrer will only be set if the link originated externally
|
||||
string referrer = (Context.Request.Headers[HeaderNames.Referer] != StringValues.Empty) ? Context.Request.Headers[HeaderNames.Referer] : "";
|
||||
|
||||
@@ -564,23 +586,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLocalizationCookie(string cookieValue)
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions
|
||||
{
|
||||
Expires = DateTimeOffset.UtcNow.AddYears(1),
|
||||
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax, // Set SameSite attribute
|
||||
Secure = true, // Ensure the cookie is only sent over HTTPS
|
||||
HttpOnly = false // cookie is updated using JS Interop in Interactive render mode
|
||||
};
|
||||
|
||||
Context.Response.Cookies.Append(
|
||||
Shared.CookieRequestCultureProvider.DefaultCookieName,
|
||||
cookieValue,
|
||||
cookieOptions
|
||||
);
|
||||
}
|
||||
|
||||
private async Task<List<Resource>> GetPageResources(Alias alias, Site site, Page page, List<Module> modules, int moduleid, string action)
|
||||
{
|
||||
var resources = new List<Resource>();
|
||||
@@ -852,4 +857,21 @@
|
||||
SetLocalizationCookie(cultureCookie);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLocalizationCookie(string cookieValue)
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions
|
||||
{
|
||||
Expires = DateTimeOffset.UtcNow.AddYears(1),
|
||||
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax, // Set SameSite attribute
|
||||
Secure = true, // Ensure the cookie is only sent over HTTPS
|
||||
HttpOnly = false // cookie is updated using JS Interop in Interactive render mode
|
||||
};
|
||||
|
||||
Context.Response.Cookies.Append(
|
||||
Shared.CookieRequestCultureProvider.DefaultCookieName,
|
||||
cookieValue,
|
||||
cookieOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace Oqtane.Controllers
|
||||
_userPermissions.IsAuthorized(User, module.SiteId, EntityNames.Folder, folderid, PermissionNames.Edit) && !string.IsNullOrEmpty(filename))
|
||||
{
|
||||
// get content
|
||||
var content = _modules.ExportModule(moduleid);
|
||||
var content = _modules.ExportModule(module, "Export Module");
|
||||
|
||||
// get folder
|
||||
var folder = _folders.GetFolder(folderid, false);
|
||||
@@ -317,7 +317,7 @@ namespace Oqtane.Controllers
|
||||
var module = _modules.GetModule(moduleid);
|
||||
if (ModelState.IsValid && module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, module.SiteId, EntityNames.Page, pageid, PermissionNames.Edit))
|
||||
{
|
||||
success = _modules.ImportModule(moduleid, content);
|
||||
success = _modules.ImportModule(module, content, "Import Module");
|
||||
if (success)
|
||||
{
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Module Content Imported {ModuleId}", moduleid);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Oqtane.Enums;
|
||||
@@ -239,10 +238,11 @@ namespace Oqtane.Controllers
|
||||
};
|
||||
module = _modules.AddModule(module);
|
||||
|
||||
string content = _modules.ExportModule(pm.ModuleId);
|
||||
// deep copy module content (includes settings)
|
||||
string content = _modules.ExportModule(pm.Module, "Copy Page");
|
||||
if (content != "")
|
||||
{
|
||||
_modules.ImportModule(module.ModuleId, content);
|
||||
_modules.ImportModule(module, content, "Copy Page");
|
||||
}
|
||||
|
||||
PageModule pagemodule = new PageModule();
|
||||
@@ -509,6 +509,20 @@ namespace Oqtane.Controllers
|
||||
var toPage = _pages.GetPage(toPageId);
|
||||
if (toPage != null && toPage.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, toPage.PermissionList))
|
||||
{
|
||||
// copy page settings
|
||||
var settings = _settings.GetSettings(EntityNames.Page, fromPage.PageId).ToList();
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
_settings.AddSetting(new Setting
|
||||
{
|
||||
EntityName = setting.EntityName,
|
||||
EntityId = toPage.PageId,
|
||||
SettingName = setting.SettingName,
|
||||
SettingValue = setting.SettingValue,
|
||||
IsPrivate = setting.IsPrivate
|
||||
});
|
||||
}
|
||||
|
||||
// copy modules
|
||||
List<PageModule> pageModules = _pageModules.GetPageModules(fromPage.SiteId).ToList();
|
||||
foreach (PageModule pm in pageModules.Where(item => item.PageId == fromPage.PageId && !item.Module.AllPages && !item.IsDeleted))
|
||||
@@ -544,10 +558,12 @@ namespace Oqtane.Controllers
|
||||
}).ToList();
|
||||
|
||||
module = _modules.AddModule(module);
|
||||
string content = _modules.ExportModule(pm.ModuleId);
|
||||
|
||||
// deep copy module content (includes settings)
|
||||
string content = _modules.ExportModule(pm.Module, "Copy Page");
|
||||
if (content != "")
|
||||
{
|
||||
_modules.ImportModule(module.ModuleId, content);
|
||||
_modules.ImportModule(module, content, "Copy Page");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -617,7 +617,11 @@ namespace Oqtane.Infrastructure
|
||||
private string SynchronizeModules(IServiceProvider provider, ISettingRepository settingRepository, IPageModuleRepository pageModuleRepository, IModuleRepository moduleRepository, SiteGroupMember siteGroupMember, List<PageModule> primaryPageModules, List<PageModule> secondaryPageModules, Page primaryPage, Page secondaryPage, int secondarySiteId)
|
||||
{
|
||||
var log = "";
|
||||
var removePageModules = secondaryPageModules.Where(item => item.PageId == secondaryPage.PageId).ToList();
|
||||
var removePageModules = new List<PageModule>();
|
||||
if (secondaryPage != null)
|
||||
{
|
||||
removePageModules = secondaryPageModules.Where(item => item.PageId == secondaryPage.PageId).ToList();
|
||||
}
|
||||
|
||||
// iterate through primary modules on primary page
|
||||
foreach (var primaryPageModule in primaryPageModules.Where(item => item.PageId == primaryPage.PageId))
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Net;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Shared;
|
||||
|
||||
@@ -20,7 +19,9 @@ namespace Oqtane.Infrastructure
|
||||
var siteRepository = provider.GetRequiredService<ISiteRepository>();
|
||||
var pageRepository = provider.GetRequiredService<IPageRepository>();
|
||||
var pageModuleRepository = provider.GetRequiredService<IPageModuleRepository>();
|
||||
var TenantManager = provider.GetRequiredService<ITenantManager>();
|
||||
var moduleRepository = provider.GetRequiredService<IModuleRepository>();
|
||||
var settingRepository = provider.GetRequiredService<ISettingRepository>();
|
||||
var tenantManager = provider.GetRequiredService<ITenantManager>();
|
||||
var syncManager = provider.GetRequiredService<ISyncManager>();
|
||||
|
||||
if (!string.IsNullOrEmpty(parameters))
|
||||
@@ -59,6 +60,14 @@ namespace Oqtane.Infrastructure
|
||||
log += $"Site Updated<br />";
|
||||
refresh = true;
|
||||
}
|
||||
if (globalReplace.Site)
|
||||
{
|
||||
if (UpdateSettings(settingRepository, EntityNames.Site, site.SiteId, find, replace, comparisonType))
|
||||
{
|
||||
log += $"Site Settings Updated<br />";
|
||||
refresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
var pages = pageRepository.GetPages(site.SiteId).ToList();
|
||||
var pageModules = pageModuleRepository.GetPageModules(site.SiteId).ToList();
|
||||
@@ -94,6 +103,14 @@ namespace Oqtane.Infrastructure
|
||||
log += $"Page Updated: /{page.Path}<br />";
|
||||
refresh = true;
|
||||
}
|
||||
if (globalReplace.Pages)
|
||||
{
|
||||
if (UpdateSettings(settingRepository, EntityNames.Page, page.PageId, find, replace, comparisonType))
|
||||
{
|
||||
log += $"Page Settings Updated<br />";
|
||||
refresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var pageModule in pageModules.Where(item => item.PageId == page.PageId))
|
||||
{
|
||||
@@ -120,28 +137,24 @@ namespace Oqtane.Infrastructure
|
||||
log += $"Module Updated: {pageModule.Title} Page: /{page.Path}<br />";
|
||||
refresh = true;
|
||||
}
|
||||
if (globalReplace.Modules)
|
||||
{
|
||||
if (UpdateSettings(settingRepository, EntityNames.Module, pageModule.ModuleId, find, replace, comparisonType))
|
||||
{
|
||||
log += $"Module Settings Updated<br />";
|
||||
refresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
// module content
|
||||
if (pageModule.Module.ModuleDefinition != null && pageModule.Module.ModuleDefinition.ServerManagerType != "")
|
||||
if (globalReplace.Content)
|
||||
{
|
||||
Type moduleType = Type.GetType(pageModule.Module.ModuleDefinition.ServerManagerType);
|
||||
if (moduleType != null && moduleType.GetInterface(nameof(IPortable)) != null)
|
||||
var content = moduleRepository.ExportModule(pageModule.Module, "Global Replace");
|
||||
if (!string.IsNullOrEmpty(content) && content.Contains(WebUtility.HtmlEncode(find), comparisonType))
|
||||
{
|
||||
try
|
||||
{
|
||||
var moduleObject = ActivatorUtilities.CreateInstance(provider, moduleType);
|
||||
var moduleContent = ((IPortable)moduleObject).ExportModule(pageModule.Module);
|
||||
if (!string.IsNullOrEmpty(moduleContent) && moduleContent.Contains(WebUtility.HtmlEncode(find), comparisonType) && globalReplace.Content)
|
||||
{
|
||||
moduleContent = moduleContent.Replace(WebUtility.HtmlEncode(find), WebUtility.HtmlEncode(replace), comparisonType);
|
||||
((IPortable)moduleObject).ImportModule(pageModule.Module, moduleContent, pageModule.Module.ModuleDefinition.Version);
|
||||
log += $"Module Content Updated: {pageModule.Title} Page: /{page.Path}<br />";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log += $"Error Processing Module {pageModule.Module.ModuleDefinition.Name} - {ex.Message}<br />";
|
||||
}
|
||||
content = content.Replace(WebUtility.HtmlEncode(find), WebUtility.HtmlEncode(replace), comparisonType);
|
||||
moduleRepository.ImportModule(pageModule.Module, content, "Global Replace");
|
||||
log += $"Module Content Updated: {pageModule.Title} Page: /{page.Path}<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +163,7 @@ namespace Oqtane.Infrastructure
|
||||
if (refresh)
|
||||
{
|
||||
// clear cache
|
||||
syncManager.AddSyncEvent(TenantManager.GetAlias(), EntityNames.Site, site.SiteId, SyncEventActions.Refresh);
|
||||
syncManager.AddSyncEvent(tenantManager.GetAlias(), EntityNames.Site, site.SiteId, SyncEventActions.Refresh);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -160,5 +173,21 @@ namespace Oqtane.Infrastructure
|
||||
|
||||
return log;
|
||||
}
|
||||
|
||||
private bool UpdateSettings(ISettingRepository settingRepository, string entityName, int entityId, string find, string replace, StringComparison comparisonType)
|
||||
{
|
||||
var changed = false;
|
||||
var settings = settingRepository.GetSettings(entityName, entityId).ToList();
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
if (setting.SettingValue != null && setting.SettingValue.Contains(find, comparisonType))
|
||||
{
|
||||
setting.SettingValue = setting.SettingValue.Replace(find, replace, comparisonType);
|
||||
settingRepository.UpdateSetting(setting);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.3" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.2" />
|
||||
<PackageReference Include="MailKit" Version="4.14.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.4" />
|
||||
<PackageReference Include="MailKit" Version="4.15.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Oqtane.Pages
|
||||
|
||||
public IActionResult OnGet(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
if (string.IsNullOrWhiteSpace(path) || _alias == null)
|
||||
{
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return BrokenFile();
|
||||
|
||||
@@ -448,11 +448,20 @@ namespace Oqtane.Repository
|
||||
var route = routeAttributes.First().Template;
|
||||
if (!string.IsNullOrEmpty(route))
|
||||
{
|
||||
// @page "/route" (note that nested routes are not permitted)
|
||||
// @page "/path" or @page "alias/path" (note that nested paths are not permitted)
|
||||
var pageTemplate = new PageTemplate();
|
||||
pageTemplate.AliasName = "*";
|
||||
if (route.StartsWith("/"))
|
||||
{
|
||||
pageTemplate.AliasName = "*"; // all sites
|
||||
pageTemplate.Path = route.Substring(1);
|
||||
}
|
||||
else // route contains an alias name
|
||||
{
|
||||
var lastSlash = route.LastIndexOf('/');
|
||||
pageTemplate.AliasName = route.Substring(0, lastSlash);
|
||||
pageTemplate.Path = route.Substring(lastSlash + 1);
|
||||
}
|
||||
pageTemplate.Version = "*";
|
||||
pageTemplate.Path = route.Substring(1);
|
||||
pageTemplate.Update = false;
|
||||
pageTemplate.PageTemplateModules = new List<PageTemplateModule>();
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ namespace Oqtane.Repository
|
||||
Module GetModule(int moduleId, bool tracking);
|
||||
void DeleteModule(int moduleId);
|
||||
string ExportModule(int moduleId);
|
||||
string ExportModule(Module module, string IPortableContext);
|
||||
bool ImportModule(int moduleId, string content);
|
||||
bool ImportModule(Module module, string content, string IPortableContext);
|
||||
}
|
||||
|
||||
public class ModuleRepository : IModuleRepository
|
||||
@@ -99,18 +101,23 @@ namespace Oqtane.Repository
|
||||
}
|
||||
|
||||
public string ExportModule(int moduleId)
|
||||
{
|
||||
Module module = GetModule(moduleId);
|
||||
return ExportModule(module, "Export Module");
|
||||
}
|
||||
|
||||
public string ExportModule(Module module, string IPortableContext)
|
||||
{
|
||||
string content = "";
|
||||
try
|
||||
{
|
||||
Module module = GetModule(moduleId);
|
||||
if (module != null)
|
||||
{
|
||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
||||
ModuleDefinition moduledefinition = moduledefinitions.FirstOrDefault(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||
if (moduledefinition != null)
|
||||
{
|
||||
var settings = _settings.GetSettings(EntityNames.Module, moduleId);
|
||||
var settings = _settings.GetSettings(EntityNames.Module, module.ModuleId);
|
||||
|
||||
ModuleContent modulecontent = new ModuleContent();
|
||||
modulecontent.ModuleDefinitionName = moduledefinition.ModuleDefinitionName;
|
||||
@@ -125,6 +132,7 @@ namespace Oqtane.Repository
|
||||
{
|
||||
try
|
||||
{
|
||||
module.IPortableContext = IPortableContext;
|
||||
module.Settings = settings.ToDictionary(x => x.SettingName, x => x.SettingValue);
|
||||
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
|
||||
modulecontent.Content = ((IPortable)moduleobject).ExportModule(module);
|
||||
@@ -149,30 +157,46 @@ namespace Oqtane.Repository
|
||||
}
|
||||
|
||||
public bool ImportModule(int moduleId, string content)
|
||||
{
|
||||
Module module = GetModule(moduleId);
|
||||
return ImportModule(module, content, "Import Module");
|
||||
}
|
||||
|
||||
public bool ImportModule(Module module, string content, string IPortableContext)
|
||||
{
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
Module module = GetModule(moduleId);
|
||||
if (module != null)
|
||||
{
|
||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
||||
ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault();
|
||||
if (moduledefinition != null)
|
||||
{
|
||||
ModuleContent modulecontent = JsonSerializer.Deserialize<ModuleContent>(content.Replace("\n", ""));
|
||||
var modulecontent = new ModuleContent();
|
||||
if (content.StartsWith("{") && content.EndsWith("}"))
|
||||
{
|
||||
// content was exported as a serialized ModuleContent object
|
||||
modulecontent = JsonSerializer.Deserialize<ModuleContent>(content.Replace("\n", ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
// raw content
|
||||
modulecontent.ModuleDefinitionName = moduledefinition.ModuleDefinitionName;
|
||||
modulecontent.Version = moduledefinition.Version;
|
||||
modulecontent.Content = content;
|
||||
}
|
||||
if (modulecontent.ModuleDefinitionName == moduledefinition.ModuleDefinitionName)
|
||||
{
|
||||
var settings = _settings.GetSettings(EntityNames.Module, moduleId);
|
||||
|
||||
if (modulecontent.Settings != null)
|
||||
{
|
||||
var settings = _settings.GetSettings(EntityNames.Module, module.ModuleId);
|
||||
foreach (var kvp in modulecontent.Settings)
|
||||
{
|
||||
var setting = settings.FirstOrDefault(item => item.SettingName == kvp.Key);
|
||||
if (setting == null)
|
||||
{
|
||||
setting = new Setting { EntityName = EntityNames.Module, EntityId = moduleId, SettingName = kvp.Key, SettingValue = kvp.Value, IsPrivate = false };
|
||||
setting = new Setting { EntityName = EntityNames.Module, EntityId = module.ModuleId, SettingName = kvp.Key, SettingValue = kvp.Value, IsPrivate = false };
|
||||
_settings.AddSetting(setting);
|
||||
}
|
||||
else
|
||||
@@ -193,7 +217,8 @@ namespace Oqtane.Repository
|
||||
{
|
||||
try
|
||||
{
|
||||
module.Settings = _settings.GetSettings(EntityNames.Module, moduleId).ToDictionary(x => x.SettingName, x => x.SettingValue);
|
||||
module.IPortableContext = IPortableContext;
|
||||
module.Settings = _settings.GetSettings(EntityNames.Module, module.ModuleId).ToDictionary(x => x.SettingName, x => x.SettingValue);
|
||||
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
|
||||
((IPortable)moduleobject).ImportModule(module, modulecontent.Content, modulecontent.Version);
|
||||
success = true;
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Modules.Admin.Users;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace Oqtane.Repository
|
||||
{
|
||||
using var db = _dbContextFactory.CreateDbContext();
|
||||
db.Entry(siteGroupMember).State = EntityState.Modified;
|
||||
db.Entry(siteGroupMember.SiteGroup).State = EntityState.Unchanged; // prevent update of linked entity
|
||||
db.SaveChanges();
|
||||
return siteGroupMember;
|
||||
}
|
||||
|
||||
@@ -532,27 +532,14 @@ namespace Oqtane.Repository
|
||||
_logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Processing Page Module {PageModule}", pageModule);
|
||||
}
|
||||
}
|
||||
|
||||
if (pageTemplateModule.Content != "" && moduleDefinition.ServerManagerType != "")
|
||||
if (!string.IsNullOrEmpty(pageTemplateModule.Content))
|
||||
{
|
||||
Type moduletype = Type.GetType(moduleDefinition.ServerManagerType);
|
||||
if (moduletype != null && moduletype.GetInterface(nameof(IPortable)) != null)
|
||||
var module = _moduleRepository.GetModule(pageModule.ModuleId);
|
||||
if (!_moduleRepository.ImportModule(module, pageTemplateModule.Content, "Site Template"))
|
||||
{
|
||||
try
|
||||
if (alias != null)
|
||||
{
|
||||
var module = _moduleRepository.GetModule(pageModule.ModuleId);
|
||||
if (module != null)
|
||||
{
|
||||
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
|
||||
((IPortable)moduleobject).ImportModule(module, pageTemplateModule.Content, moduleDefinition.Version);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (alias != null)
|
||||
{
|
||||
_logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Importing Content For {ModuleDefinitionName}", pageTemplateModule.ModuleDefinitionName);
|
||||
}
|
||||
_logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, "Error Importing Content For {ModuleDefinitionName}", pageTemplateModule.ModuleDefinitionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,12 @@ namespace Oqtane.Models
|
||||
[NotMapped]
|
||||
public bool IsShared { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the scenario where the IPortable interface is being invoked
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string IPortableContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the <see cref="ModuleDefinition"/> used for this module.
|
||||
/// </summary>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
|
||||
<PackageReference Include="NodaTime" Version="3.3.0" />
|
||||
<PackageReference Include="NodaTime" Version="3.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace Oqtane.Shared
|
||||
{
|
||||
public class Constants
|
||||
{
|
||||
public static readonly string Version = "10.1.0";
|
||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4,6.0.0,6.0.1,6.1.0,6.1.1,6.1.2,6.1.3,6.1.4,6.1.5,6.2.0,6.2.1,10.0.0,10.0.1,10.0.2,10.0.3,10.0.4,10.1.0";
|
||||
public static readonly string Version = "10.1.1";
|
||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4,6.0.0,6.0.1,6.1.0,6.1.1,6.1.2,6.1.3,6.1.4,6.1.5,6.2.0,6.2.1,10.0.0,10.0.1,10.0.2,10.0.3,10.0.4,10.1.0,10.1.1";
|
||||
public const string PackageId = "Oqtane.Framework";
|
||||
public const string ClientId = "Oqtane.Client";
|
||||
public const string UpdaterPackageId = "Oqtane.Updater";
|
||||
|
||||
@@ -12,7 +12,7 @@ Oqtane is being developed based on some fundamental principles which are outline
|
||||
|
||||
# Latest Release
|
||||
|
||||
[10.1.0](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0) was released on February 25, 2026 and is a maintenance release including 72 pull requests by 6 different contributors, pushing the total number of project commits all-time over 7600. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
|
||||
[10.1.1](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1) was released on March 6, 2026 and is a maintenance release including 21 pull requests by 2 different contributors, pushing the total number of project commits all-time over 7700. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
|
||||
|
||||
# Try It Now!
|
||||
|
||||
@@ -111,6 +111,9 @@ Connect with other developers, get support, and share ideas by joining the Oqtan
|
||||
# Roadmap
|
||||
This project is open source, and therefore is a work in progress...
|
||||
|
||||
[10.1.1](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1) (Mar 6, 2026)
|
||||
- [x] Stabilization improvements
|
||||
|
||||
[10.1.0](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0) (Feb 25, 2026)
|
||||
- [x] Site Groups, Content Synchronization, Content Localization
|
||||
- [x] Global Replace
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
"apiVersion": "2024-04-01",
|
||||
"name": "[concat(parameters('BlazorWebsiteName'), '/ZipDeploy')]",
|
||||
"properties": {
|
||||
"packageUri": "https://github.com/oqtane/oqtane.framework/releases/download/v10.1.0/Oqtane.Framework.10.1.0.Install.zip"
|
||||
"packageUri": "https://github.com/oqtane/oqtane.framework/releases/download/v10.1.1/Oqtane.Framework.10.1.1.Install.zip"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites', parameters('BlazorWebsiteName'))]"
|
||||
|
||||
Reference in New Issue
Block a user